Guides
Your First Run on Real Quantum Hardware With Qiskit
A step-by-step guide to IBM's free Open Plan: account and limits, installing Qiskit, a Bell-state circuit, simulator and noisy-simulator runs, then the hardware job and how to read its noisy counts.

Gabriele Masetti ·
What You Need Before Touching a Quantum Computer
A first run on real quantum hardware takes about an hour and costs nothing. IBM's Open Plan gives anyone with an account time on its superconducting processors, and Qiskit, IBM's open-source Python toolkit, handles the rest. The useful lesson is seeing why the same four-line circuit gives clean counts on a laptop and slightly dirty counts on a chip.
You need a terminal, a working Python installation and an email address. No physics background is required beyond knowing that a qubit can be measured as 0 or 1. The code was run in a fresh virtual environment with Qiskit 2.6.0, qiskit-aer 0.18.0 and qiskit-ibm-runtime 0.50.0, and the numbers reported come from those runs.
One caveat shapes the whole guide. The local steps (building, simulating, transpiling, a noise model) were executed, and the outputs given come from those runs. The hardware step uses the exact calls IBM documents, and your counts will differ from any example, because every run on a real chip is a fresh draw from noisy physics.
What the Open Plan Gives You, and What It Does Not
IBM states the headline term in its plans documentation: users can "run your quantum circuits on the world's best QPUs for free (up to 10 minutes per 28-day rolling window)". The word that matters is rolling: minutes you spend come back 28 days after you spent them.
Open Plan instances can only be created in the us-east region, so the region menu on the dashboard matters when you create the instance. You can watch consumption on the Platform dashboard and the Workloads page. IBM describes the plan as meant for "those who are learning quantum computing and exploring IBM quantum technology."
A promotion adds headroom. IBM's documentation says that from 16 March 2026, active Open Plan users can opt in to an additional 180 minutes over the next 12 months. IBM's announcement post, published the same day, sets the conditions: a non-trial account that has used 20 minutes of runtime within any 12-month period can opt in, and after the 12 months the plan returns to 10 minutes.
Quantum Computing Report, an independent trade outlet, reported the offer on 20 March 2026 as a one-time deal for users who had used at least 20 minutes in a 12-month period, granted yearly rather than monthly. Both accounts agree on the numbers. Because IBM changes plan terms from time to time, treat the plans page as the authority on the day you sign up.
Ten minutes sounds stingy until you see what a small job consumes. IBM's pages describe the allowance as quantum processor time, and a two-qubit circuit with about a thousand shots is among the smallest jobs you can send. Check the Workloads page after your first run to see what it actually cost.
Creating the Account and Saving Your Key
Sign up at quantum.cloud.ibm.com with an IBM account. Choose the Open Plan when the platform offers its plans, and make sure you hold an instance on it. An instance is the object that holds your plan and your usage; every job you submit is attached to one.
Two credentials matter. The first is an API key, 44 characters long, that you create from the dashboard. IBM warns that "The token will not be visible again", so copy it somewhere safe immediately. The second is the instance's CRN, a long identifier you can copy from the Instances page. The CRN is optional, but it removes any ambiguity if you later hold more than one instance.
Save the credentials once, and every later session can reuse them. The call is the form IBM documents in its save-credentials guide, and the signature matches the installed library.
from qiskit_ibm_runtime import QiskitRuntimeService
QiskitRuntimeService.save_account(
token="<your-44-character-api-key>",
instance="<your-instance-CRN>", # optional
set_as_default=True,
overwrite=True,
)
IBM's guide says the credentials land in $HOME/.qiskit/qiskit-ibm.json. Treat that file like a password: do not paste it into notebooks you share, and do not commit it. On a public or shared machine, IBM points to a separate manual authentication route instead of saving the key to disk.
Installing Qiskit in a Clean Environment
Use a virtual environment so the packages do not collide with anything else on your machine. Three packages cover this guide. Qiskit builds and compiles circuits, qiskit-aer simulates them on your CPU, and qiskit-ibm-runtime talks to IBM's cloud.
python3 -m venv qenv
source qenv/bin/activate
pip install qiskit qiskit-ibm-runtime qiskit-aer
Check what you got, because Qiskit evolves quickly and version differences explain most beginner errors.
import qiskit, qiskit_aer, qiskit_ibm_runtime
print(qiskit.__version__, qiskit_aer.__version__, qiskit_ibm_runtime.__version__)
On the day of writing this printed 2.6.0, 0.18.0 and 0.50.0. IBM's Hello World page pins qiskit[all]~=2.5.2 and qiskit-ibm-runtime~=0.47.0 as compatible-release ranges and says newer versions work, though the Qiskit and Runtime versions installed here fall outside those ranges. If your output is newer still, the code should hold, since it uses only the primitives interface.
Building a Bell State
A Bell state is the smallest circuit that does something no classical bit pair can. A Hadamard gate puts qubit 0 into an equal superposition of 0 and 1. A controlled-NOT gate then flips qubit 1 whenever qubit 0 is 1, which ties the two qubits together so that measuring one tells you the other.
from qiskit import QuantumCircuit
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
qc.measure_all()
print(qc.draw(output="text"))
The drawing shows an H gate on the top wire, a CNOT linking the two wires, and a measurement on each. measure_all() adds a classical register named meas and a barrier before the measurements, and that register name matters later, because the result object stores your counts under it.
Ideally the outcome is "00" half the time and "11" half the time, and never "01" or "10". That prediction is the benchmark you will hold the hardware to. Each repetition of the circuit is called a shot, and a single shot gives one bit string, so you need many shots before a distribution appears.
Running It on a Local Simulator
Run the circuit on an ideal simulator first. Qiskit ships StatevectorSampler, which computes the exact quantum state and samples measurements from it, with no noise and no account.
from qiskit.primitives import StatevectorSampler
result = StatevectorSampler(seed=1).run([qc], shots=1024).result()
print(result[0].data.meas.get_counts())
My run printed {'11': 506, '00': 518}. The split is not exactly 512 and 512 because sampling is random, the same way 1,024 coin flips rarely land on exactly 512 heads. The important part is what is missing: no "01" and no "10". The simulator has no physics to go wrong.
The call pattern here is the one you will reuse on hardware. A sampler takes a list of circuits (IBM calls each entry a primitive unified bloc, or PUB), a shot count, and returns a result whose first element holds a data object. The attribute meas is the register name from measure_all(), and get_counts() turns the raw bits into a dictionary of bit strings and tallies.
Transpiling for a Specific Chip
A real processor does not understand h or cx. Each chip supports a short list of native operations, and its qubits are wired in a fixed pattern, so Qiskit must rewrite your circuit into that vocabulary and layout. IBM calls the result an ISA circuit, for instruction set architecture, and hardware primitives accept only circuits in that form.
You can watch this happen without an account, using one of the fake backends that ship with qiskit-ibm-runtime. They are frozen snapshots of real IBM devices, including their calibration data.
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
fake = FakeSherbrooke()
pm = generate_preset_pass_manager(backend=fake, optimization_level=1)
isa = pm.run(qc)
print(isa.count_ops(), isa.depth())
The output was OrderedDict({'rz': 7, 'sx': 4, 'measure': 2, 'ecr': 1, 'barrier': 1}) with a depth of 8. Your two gates became twelve native ones: seven Z rotations, four square-root-of-X pulses and one echoed cross-resonance gate, ecr, which is the two-qubit gate on that device. That single ecr is where most of the error will come from.
Simulating the Noise of a Real Device
Now add the imperfections. The Aer simulator can load a fake backend's recorded error rates and apply them to every gate and measurement, which gives a preview of what the hardware will do.
from qiskit_aer.primitives import SamplerV2 as AerSampler
noisy = AerSampler.from_backend(fake, seed=7)
r = noisy.run([isa], shots=1024).result()
print(r[0].data.meas.get_counts())
My run produced {'00': 503, '11': 474, '01': 27, '10': 20}. Forty-seven of 1,024 shots, about 4.6 percent, landed on outcomes the ideal circuit forbids. That is a simulation of Sherbrooke's recorded noise, not a measurement from the physical machine, so treat it as an illustration of scale.
Three effects produce those wrong counts. Gates are imperfect, and two-qubit gates are worse than single-qubit ones. Qubits lose their state over time through decoherence. Readout is imperfect too, so a qubit that finished in 1 is sometimes reported as 0. Error mitigation, which the runtime offers as options, can reduce but not remove these effects.
Submitting the Job to Real Hardware
The hardware path reuses the same three steps: choose a backend, transpile for it, run a sampler. The code follows the calls IBM documents in its Hello World guide and in the SamplerV2 reference, where the constructor is SamplerV2(mode=None, options=None) and run takes pubs and an optional shots. I could not execute it, since running it needs a live account.
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
service = QiskitRuntimeService() # reads the saved credentials
backend = service.least_busy(simulator=False, operational=True)
print(backend.name)
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa = pm.run(qc)
sampler = SamplerV2(mode=backend)
job = sampler.run([isa], shots=1024)
print(job.job_id())
counts = job.result()[0].data.meas.get_counts()
print(counts)
Passing the backend as mode runs the circuit as a single job. The call least_busy picks the operational device with the shortest queue, which is helpful on a plan where your minutes are limited. Keep shots modest: 1,024 is plenty to see the pattern, and the allowance is measured in processor time.
IBM is candid that waiting is part of the experience. Its Hello World guide states the rule plainly:
When you run your quantum program on a real device, your workload must wait in a queue before it runs. — IBM Quantum Documentation, Hello World guide, IBM
The call to job.result() blocks until the job finishes. For a long queue, print the job ID, close the notebook, and fetch the job later with service.job(job_id). The Workloads page shows the status and the processor time charged.
Reading Real Counts
When the hardware dictionary arrives, expect the shape you saw in the noisy simulation. "00" and "11" should dominate, each near half of your shots, and "01" and "10" should appear with small tallies. The dominant pair shows correlation, but does not by itself confirm entanglement; a pair of independent coins would spread evenly across all four outcomes.
Do not expect a perfect split between "00" and "11". On most superconducting devices, a qubit holding 1 relaxes toward 0 a little more easily than the reverse, so "00" often edges ahead. Run the same job twice and you will see two different dictionaries, both legitimate.
A useful habit is to turn the dictionary into a number you can compare across runs: the fraction of shots in the forbidden outcomes.
total = sum(counts.values())
bad = counts.get("01", 0) + counts.get("10", 0)
print(f"forbidden outcomes: {bad / total:.1%}")
That percentage is a crude health check for the whole pipeline, folding together gate error, decoherence and readout error. Re-run it on a different backend or a different day and it will move, so a single run proves little.
Spending Your Ten Minutes Wisely
Develop on the simulator and spend hardware time only on circuits you understand. A fake backend plus Aer lets you debug code, check the transpiled depth and rehearse the result handling with no queue. Hardware then confirms the behaviour.
Batch your questions. One job can carry several circuits as separate PUBs, so a single queue wait answers several questions at once. For instance, you can submit the Bell circuit and a three-qubit GHZ variant together and compare their forbidden-outcome fractions from the same device calibration.
Watch the dashboard after your first job. The Workloads page shows the processor time that job consumed, which tells you how many repeats the window can hold. With a rolling 28-day window, a burst of experiments leaves you waiting until the earliest of those minutes expires, so spread them out, or look into the 180-minute opt-in if you qualify.
The free plan has real limits. Access is to IBM's published fleet as the Open Plan allows it; IBM's March 2026 post says the Heron r2 processor ibm_kingston was opened to all Open Plan users. The qiskit-ibm-runtime release notes describe a limit on the number of pending jobs on the Open Plan, so check IBM's current documentation before you queue several at once.
Where to Go After the Bell State
Once the Bell state works, change one thing at a time. Add a third qubit and build a GHZ state, then compare how the forbidden fraction grows with the number of two-qubit gates. Switch optimization_level between 0 and 3 and read the transpiled gate counts. Try the estimator primitive, which returns expectation values of observables instead of raw counts, and which IBM's Hello World guide uses for its own example.
You will also meet error mitigation options, which run extra circuits to estimate and subtract noise. They multiply the processor time per job, so they interact directly with your allowance. Learn the unmitigated behaviour first, and then you will know what the mitigation is correcting.
The machine in front of you is imperfect by design, and the tooling is built around that fact. A circuit that is correct on paper becomes a noisy statistical experiment on hardware, and the skill is reading the distribution, since no single run gives the answer. Run your Bell state, save the counts, and keep the first dictionary you get: it is a record of what current superconducting hardware does with your two qubits.