Skip to main contentIBM Quantum Documentation

Configure runtime compilation for Qiskit Runtime

Runtime compilation techniques transform your circuit to minimize errors. Runtime compilation adds some classical pre-processing overhead to your overall runtime. Therefore, it is important to achieve a balance between perfecting your results and ensuring that your job completes in a reasonable amount of time.


To ensure faster and more efficient results, as of 1 March 2024, circuits and observables need to be transformed to only use instructions supported by the system (referred to as instruction set architecture (ISA) circuits and observables) before being submitted to the Qiskit Runtime primitives. See the transpilation documentation for instructions to transform circuits. Due to this change, the primitives will no longer perform layout or routing operations. Consequently, transpilation options referring to those tasks will no longer have any effect. By default, all V1 primitives optimize the input circuits. To bypass all optimization when using a V1 primitive, set optimization_level=0.

Exception: When you initialize the Qiskit Runtime Service with the Q-CTRL channel strategy (example below), abstract circuits are still supported.

service = QiskitRuntimeService(channel="ibm_cloud", channel_strategy="q-ctrl")

Set the optimization level (V1 primitives only)

The optimization_level setting specifies how much optimization to perform on the circuits. Higher levels generate more optimized circuits, at the expense of longer compile times.

Optimization levels 2 and 3 behave identically to level 1.

Optimization LevelEstimator & Sampler

No optimization: typically used for hardware characterization or debugging

1, 2, 3

Light optimization:

  • Single-qubit gate optimization
  • Two-qubit gate optimization
  • Error suppression: dynamical decoupling

If using an IBM Cloud® Qiskit Runtime service instance with Q-CTRL performance management enabled, there is no need to specify runtime optimization or resilience levels, as the strategy includes an automatic preset.

Q-CTRL defaults to optimization_level=3 and resilience_level=1. Setting optimization_level or resilience_level equal to 0 will result in an execution error. Levels 1, 2, and 3 are permitted but will not impact performance. Setting other options will likewise not impact performance, and it may result in a runtime warning. For more information visit the Q-CTRL documentation(opens in a new tab).

Example: configure Estimator with optimization levels

from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.circuit.library import RealAmplitudes
from qiskit.quantum_info import SparsePauliOp
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
psi = RealAmplitudes(num_qubits=2, reps=2)
H = SparsePauliOp.from_list([("II", 1), ("IZ", 2), ("XI", 3)])
theta = [0, 1, 1, 2, 3, 5]
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
psi =
H = H.apply_layout(psi.layout)
estimator = Estimator(mode=backend)
job =[(psi, H, theta)])
psi1_H1 = job.result()[0]

Advanced runtime compilation options

In the V2 primitives, you can explicitly enable and disable individual error mitigation/suppression methods, such as dynamical decoupling.


Dynamical decoupling is not supported when the input circuits are dynamic.

from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import SamplerV2 as Sampler
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
sampler = Sampler(backend)
# Turn on dynamical decoupling with sequence XpXm.
sampler.options.dynamical_decoupling.enable = True
sampler.options.dynamical_decoupling.sequence_type = "XpXm"
print(f">>> dynamical decoupling sequence to use: {sampler.options.dynamical_decoupling.sequence_type}")

Next steps

Was this page helpful?
Report a bug or request content on GitHub.