Key takeaways:
- IBM Quantum's directed execution model runs your circuits exactly as directed, giving explicit client-side control over the error correction stack—from mitigation to correction—without sacrificing 100+ qubit performance.
- Error mitigation routines that once ran hidden on IBM servers now run client-side, so you can inspect, customize, and extend it.
- It's the same framework behind IBM's quantum advantage demonstrations, and a foundation for the error-correction research already underway on IBM hardware—from postselected QEC to distance-5 surface codes that cut the logical error rate per round by up to 2.8x.
- A new Executor primitive powers the model, scaling to thousands of circuit variants and letting you compose custom error mitigation and error correction pipelines by hand.
- Already using Qiskit's Sampler and Estimator primitives? Upgrading is low-friction: update your provider and your existing code keeps working.
Today's most demanding quantum experiments rarely begin and end with a single circuit execution. Instead, workloads typically involve large families of closely related circuit variants, built on multi-stage workflows for noise, randomization, and post-processing—and assembling them by hand takes considerable time and effort.
With the directed execution model in IBM Quantum Compute Service, that’s changing. Directed execution is a new, lower-level execution model that, true to its name, runs your circuits exactly as directed—giving you an explicit, composable way to express how your circuits run and a transparent view into what actually happens on IBM Quantum hardware. Crucially, you gain that visibility and control without trading off the performance you have come to expect from 100+ qubit systems.
Let's take a look back at how we got here. Execution on IBM Quantum hardware started with backend.run, a direct method for running a list of circuits. This was fine when workloads were just a handful of circuits, but advanced experiments increasingly came to rely on large families of circuit variants for twirling, randomization, and noise learning, each of which had to be built on the client side and shipped over the wire. The Sampler and Estimator primitives changed that, generating variants server-side in the near-time environment then known as Qiskit Runtime, now IBM Quantum Compute Service. This boosted performance at scale, but turned execution into a black box.
Directed execution is the next step. It brings us back to a single entry point, but this isn’t simply a return to backend.run. The machinery behind it has been rebuilt to give you a level of control and performance that wasn’t possible before. You can now build algorithmic primitives like Sampler and Estimator on the client, tailored to your use case, then send them for Executor to process as directed in the near-time environment of IBM Quantum Compute Service.
Evolving the programming model, from backend.run (2016–2022) to the server-side Sampler and Estimator (2022–present) to the Executor primitive (2026 onward).
This matters for two reasons. First, it's the same framework IBM and its partners used to reach recent demonstrations of quantum advantage through trusted computation. Second, it turns IBM Quantum Compute Service into a platform for exploring the full continuum of methods that address errors—from advanced error mitigation to the error-correcting codes researchers are already running on IBM quantum hardware.
We know that a working toolchain is essential, so the directed execution model aims to deliver progress without disruption. If you currently use the Sampler and Estimator primitives, your code keeps working. Upgrading is designed to be low-friction, so in most cases, the only things that change will be your import statements—not the body of your code. You never need to reach for lower-level tools unless that is what you have set out to do.
This post walks through the building blocks of the directed execution model and the resources that show you how the pieces fit together.To get a preview of directed execution in action, try the new PEC with logical noise models tutorial on IBM Quantum Platform.
What is the directed execution model?
At its core, directed execution is a framework that lets you describe how a circuit should be transformed and randomized before it runs—without generating the circuit variants yourself. You define the transformations and randomization; IBM Quantum Compute Service prepares and runs the circuits efficiently.
Powering the directed execution model is a new primitive, Executor. The new client-side tools and primitives are all built on top of it, which lets us consolidate our server-side support without breaking your code.
The directed execution model: client-side packages and Samplomatic produce a template circuit and samplex, which the Executor primitive runs on IBM Quantum Compute Service.
Working directly with Executor is useful when your research depends on controlling exactly how your circuits run. If your work involves developing new error mitigation protocols, for example, studying the propagation of noise through a specific region of a circuit, or benchmarking hardware behavior across thousands of circuit variants, Executor is an invaluable tool.
At the same time, not all research calls for that level of control. To preserve the convenience you have grown accustomed to, the Sampler and Estimator primitives now run on top of Executor as well. We have adapted them to leverage Executor seamlessly behind the scenes, so their inputs and outputs remain the same. For most users, that means the only step you will need to take is updating your provider.
The difference is that the error mitigation they perform is no longer a black box. That logic now runs on the client, so you can see how it's implemented, adjust it, or write your own methods against Executor directly. This, in many ways, is the core goal and organizing principle of directed execution: convenience when you want it, control when you need it.
The directed execution model is built from a few key components. Let’s explore them in the order you will most likely use them.
Boxes and annotations: expressing intent
Directed execution builds on two capabilities first introduced in Qiskit SDK v2.0 and v2.1: boxes (the BoxOp instruction) and annotations. Boxes group instructions in your circuit for later processing; annotations tag those boxes with directives for the transpiler or later stages of the execution stack.
Some common annotations, pre-defined in Samplomatic, include:
- Twirl: applies Pauli or Clifford twirling to mitigate noise
- InjectNoise: injects noise in a controlled, configurable way for error mitigation studies
- ChangeBasis: controls qubit rotation into and out of specific basis states at execution time
You use boxes to define meaningful regions of your circuit, then add annotations that declare how the operations in each box should be transformed. For a hands-on walkthrough, see the Samplomatic transpiler guide, which covers both grouping operations into boxes and working with annotations.
Samplomatic: building the execution plan
The open-source Samplomatic library interprets your boxed and annotated circuit and turns it into a concrete execution plan with two outputs:
- A template circuit: a standard, parametric Qiskit circuit that acts as an inspectable blueprint for every circuit variant, with adjustable parameters the runtime fills in at execution time.
- A samplex: a structured, inspectable recipe for how randomization and classical post-processing should happen—not a bundle of pre-computed variants. It follows a tensor in/out model: tensors of input parameters in, tensors of randomized values out.
Because both are generated locally, you can inspect exactly how twirls, noise injections, and other transformations propagate through your circuit before committing anything to hardware. To see how, review the Samplex Inputs and Outputs guide, which shows how to set up and read a samplex, and the Debugging and Tracing guide, which shows how to inspect layouts and trace transformations before you run.
The Executor primitive
Once you have crafted your plan, the Executor primitive runs it. It's the low-level engine that the rest of the directed execution tools are built on.
Executor treats each template circuit as a tensor manipulator, consuming tensors of parameter values and producing tensors of results. That means it can scale to large families of variants with no manual assembly.
Rather than the list of PUBs (Primitive Unified Blocs) that Sampler and Estimator take as input, Executor accepts a QuantumProgram that can hold multiple items. If you’re unfamiliar, a PUB is the fundamental unit of work the primitives run—essentially a circuit bundled with the data needed to execute it. A QuantumProgram extends that model. It holds multiple items, and each item bundles a circuit, its parameter values, and the manipulations that will be applied during execution.
Once your program is defined, Executor runs it through shot loops. It’s built for scale, operating on the same high-performance runtime environment we built for the first generation of Sampler and Estimator, so it can handle workloads of 5,000 randomizations or more without sacrificing performance.
Executor also supports broadcasting. You can sweep across noise scales, basis changes, or parameter sets with familiar NumPy-style rules, all in a single job.
Tools built on directed execution
Boxes, Samplomatic, and Executor make up the directed execution model itself. Surrounding them is a growing ecosystem of open-source tools that build on it, turning low-level control into ready-to-use capabilities so you don’t have to implement noise learning or error mitigation from scratch. These include the client-side implementation of the Sampler and Estimator primitives, as well as a few additional packages:
A typical error-mitigation workflow in four steps, and the directed-execution package that handles each: Samplomatic, Qiskit Noise Learning, Qiskit Mitigation, and the Executor primitive.
The new Sampler and Estimator: local mode with real mitigation
The new client-side Sampler and Estimator—released last week as part of qiskit-ibm-runtime 0.50.0—don’t just replace the functionality of the original primitives, they also improve upon it. The transparency of the directed execution model means the mitigation they run is now inspectable and customizable instead of being hidden server-side. It also makes local mode far more capable.
Running your mitigation on the client means you can try it out locally before sending anything to a QPU. In the server-side Estimator, running against a local simulator ignores your resilience options entirely. The mitigation is a black box, so there’s nothing to reproduce. With the new client-side implementation, qiskit-ibm-runtime's local mode applies the same error mitigation you would get on hardware. For example:
# This will be the default Estimator in the near future. from qiskit_ibm_runtime.executor_estimator import Estimator from qiskit_ibm_runtime.fake_provider import FakeKingston estimator = Estimator(FakeKingston()) estimator.options.resilience_level = 1 estimator.run(pubs)
Here, resilience_level = 1 actually applies level 1 error mitigation (TREX) to your circuits on the simulator, where the server-side Estimator would simply ignore it. This change gives you the ability to prototype and compare mitigation strategies locally before spending QPU time.
Keep in mind that FakeKingston models a 156-qubit device, which is too large to reproduce on a local statevector simulator. Because the QPUs available to you are all well over 100 qubits, we recommend running Clifford (stabilizer) simulations for fast, approximate checks against your error-mitigated circuits.
Qiskit Noise Learning—client-side noise characterization
Many quantum error mitigation techniques depend on knowing exactly where noise occurs in your circuits. Qiskit Noise Learning is a client-side, open-source package for Pauli-Lindblad noise learning that works directly with boxes and annotations.
In the original version of Estimator, noise learning and injection ran server-side; you couldn't see or customize the noise map. Now, that characterization runs on the client, giving you per-region visibility, full customization capabilities, and support for both Pauli-Lindblad and TREX protocols.
Qiskit Noise Learning is to NoiseLearner what Executor is to the primitives—the same underlying capability, exposed so you can look at it, customize it, and extend it. Just as with the primitives, we will continue to support a convenient NoiseLearner-style interface for those who do not require those capabilities: convenience when you want it, control when you need it.
To see the full API and some helpful examples, be sure to review the Qiskit Noise Learning documentation.
Qiskit Mitigation
Qiskit Mitigation is an open-source package of quantum error mitigation methods for building mitigation pipelines directly with Samplomatic. It includes implementations of methods such as probabilistic error cancellation (PEC), probabilistic error amplification (PEA), twirled readout error extinction (TREX), and gate-folding zero-noise extrapolation (ZNE).
Beyond those core methods, Qiskit Mitigation is also home to the advanced building blocks that make sophisticated workflows practical—and it exposes them directly, ready to call. You can compute postselected noise channels from circuit symmetries or spacetime checks to cut PEC's sampling overhead, add bit-flip-check postselection to filter non-Markovian noise, calculate expectation values with advanced error mitigation, and more.
However, you don't have to build any of this by hand to benefit from it. The new client-side Sampler and Estimator are built on these same implementations, so whether you want to call a high-level primitive or assemble your own pipeline by hand, Qiskit Mitigation lets you work at the level that best suits your needs. And because it's designed for modularity, you can change one part—for example, swap in a custom extrapolator for a ZNE workflow—without rewriting the entire protocol.
Who directed execution is for
Because the packages, libraries, and capabilities that power directed execution are all modular, this new model is able to meet you wherever and however you work:
- Applied researchers can keep using the drop-in Sampler and Estimator with familiar options like resilience_level—no changes needed. Learn more in the Sampler and Estimator guides, or see the 0.50.0 release notes for details on the new client-side implementation.
- Algorithm developers can inspect and tune the methods in Qiskit Mitigation—as illustrated in the PEC with logical noise models tutorial.
- Hardware experts can compose the full workflow by hand—applying PEC on one region of a circuit and PEA on another. For a detailed example of this, read the recent operator Loschmidt echo demonstration from Algorithmiq and IBM—a quantum-advantage result that builds its full mitigation-and-verification pipeline directly on the directed execution stack.
Gaining more control over your circuit executions requires just a little extra code. And if you don’t need it, you don’t have to worry about it.
A closer look: PEC with shaded lightcones
For an example of directed execution in action, let’s see how it handles a workflow that wasn’t possible with the original Sampler and Estimator: combining probabilistic error cancellation (PEC), shaded lightcones (SLC), TREX, and postselection in a single pipeline.
The example shown here is just a high-level overview. You can find the complete, runnable code in the full PEC with shaded lightcones tutorial.
1. Map the problem. Define your observable and the measurement bases you'll need.
observable = SparsePauliOp.from_sparse_list(target_obs_sparse, num_qubits=num_qubits) bases_virt, reverser_virt = get_measurement_bases(observable)
2. Optimize. Transpile the circuit and group its instructions into annotated boxes with Samplomatic. Then compute the shaded-lightcone bounds that identify which errors you can safely leave unmitigated.
from samplomatic.transpiler import generate_boxing_pass_manager from qiskit_addon_slc.bounds import compute_forward_bounds, merge_bounds boxed_circuit = generate_boxing_pass_manager( twirling_strategy="active", inject_noise_strategy="individual_modification", measure_annotations="all", ).run(isa_circuit) forward_bounds = compute_forward_bounds(boxed_circuit, noise_model_paulis, isa_observable, ...) merged_bounds = merge_bounds(boxed_circuit, forward_bounds, backward_bounds, noise_model_rates)
3. Execute. Learn the noise on each unique layer, turn the bounds into per-error scales, then build the template circuit and samplex and run the whole program through Executor in a single job.
# Learn the noise on each unique layer noise_learner = NoiseLearnerV3(backend, noise_learner_options) refs_2_plm = noise_learner.run(unique_2q_instructions).result().to_dict(unique_2q_instructions) # Turn SLC bounds into per-error scales local_scales, sampling_cost, _ = compute_local_scales(boxed_circuit, merged_bounds, refs_2_plm, ...) # Build the template circuit + samplex, then execute template_circuit, samplex = samplomatic.build(boxed_circuit) program = QuantumProgram(shots=shots_per_randomization, noise_maps=refs_2_plm) program.append_samplex_item( circuit=final_template_circuit, samplex=samplex, samplex_arguments=samplex_arguments, shape=(num_randomizations,), ) results = Executor(backend).run(program).result()
4. Post-process. Apply TREX and postselection to the raw results to recover mitigated expectation values.
mask = post_selector.compute_mask(datum, strategy=post_selection_strategy) res = executor_expectation_values( meas, reverser_virt, ..., postselect_mask=mask, rescale_factors=trex_scale_factors, gamma_factor=gamma, )
The result: SLC cut PEC's sampling overhead by roughly 3.4x while maintaining comparable accuracy. For the full noise-model setup, every parameter, and the analysis, follow the tutorial.
Experiment with error-correcting codes today
Directed execution is not just for error mitigation—it is already the foundation for hands-on error-correction research. The same client-side control that lets you shape hardware noise into Pauli noise for mitigation also lets you build and study error-correcting codes on today's hardware.
For example, IBM's recent spacetime mitigation of logical errors layers PEC on top of postselected QEC to sharply cut sampling overhead, and Qiskit Paulice brings postselected quantum error correction to the platform today. Researchers are also running full error-correcting codes: one recent study implemented distance-5 surface codes on IBM Quantum Nighthawk, improving the logical error rate per round by up to 2.8x by identifying and routing the code around a handful of underperforming components.
That control even reaches below the circuit level. Through pulse-level access, you can govern the timing of gates, perform fast qubit resets, and read out soft (pre-classification) measurement information—levers you can use to tune the performance of your QEC circuits. Together, these capabilities make IBM Quantum Compute Service a place to explore the full continuum from quantum error mitigation to quantum error correction.
What’s next: one platform, from mitigation to correction
Executor is the initial implementation of the directed execution model. You can look forward to it gaining additional capabilities over time.
Eventually, it will evolve into a more generic execution interface—one that can flexibly shift classical pre- and post-processing between client and server, extending that client-side transparency from the pre-processing it covers today to post-processing as well.
And because it is the most flexible framework we have, new error mitigation and correction research lands on Executor first. It’s a platform built to extend far into the future.
Migrating with AI assistance
If you're moving existing code onto the client-side primitives, you don't have to do it by hand.
Alongside this release, we are publishing our first official Qiskit AI skill: migrate-qiskit-ibm-runtime, a migration helper that ports your qiskit-ibm-runtime code onto the new client-side Sampler and Estimator, flagging breaking changes as it goes. It handles migrations from both V1 and legacy server-side V2 primitives. This initial release (0.1.0) covers every migration action from qiskit-ibm-runtime 0.1.0 through the latest 0.50.0, including changes to the IBM Quantum Compute Service API over the years.
It's open source and lives in the Qiskit/skills GitHub repository. Add it to your AI coding assistant, point it at your code, and let it handle the mechanical work. It's also the lowest-friction way to get started: migrate first, then explore the tools outlined in this blog post at your own pace.
Get started with directed execution
The fastest way to understand the directed execution model is to use it.
- Upgrade your environment. Make sure you are on the latest version of qiskit-ibm-runtime to get Executor and the new client-side Sampler and Estimator. This is the single step that puts your workloads on the directed execution model, whether or not you ever call Executor directly.
Upgrade your environment. Make sure you are on the latest version of qiskit-ibm-runtime to get Executor and the new client-side Sampler and Estimator. This is the single step that puts your workloads on the directed execution model, whether or not you ever call Executor directly.
- Dig deeper. Review the directed execution model documentation for more on Samplomatic, Executor, Qiskit Noise Learning, and Qiskit Mitigation.
Dig deeper. Review the directed execution model documentation for more on Samplomatic, Executor, Qiskit Noise Learning, and Qiskit Mitigation.
- Try it out. Work through the PEC with shaded lightcones tutorial. It uses directed execution end-to-end, combining PEC, SLC, TREX, and postselection on the Executor primitive.
Try it out. Work through the PEC with shaded lightcones tutorial. It uses directed execution end-to-end, combining PEC, SLC, TREX, and postselection on the Executor primitive.
Already using Sampler and Estimator? Nothing breaks—your code keeps working, and the advanced capabilities enabled by directed execution are there when you are ready to explore them.









