Skip to main contentIBM Quantum Documentation Preview
This is a preview build of IBM Quantum® documentation. Refer to quantum.cloud.ibm.com/docs for the official documentation.

Monitor or cancel a job

This guide explains how to monitor job status, view usage information, and cancel jobs. You can access this information both through IBM Quantum® Platform and programmatically using Qiskit.

  • The code on this page was developed using the following requirements. We recommend using these versions or newer.

    qiskit-ibm-runtime~=0.46.1
    

Monitor a job

Use these methods to check the status of your submitted jobs, retrieve results, and view details related to the job and its execution.

The job instance provides several methods for monitoring:

Method
Description
job.status()Check the current job status
job.job_id()Get the unique job identifier
job.result()Retrieve job results (blocking call until complete)
job.wait_for_final_state()Block until the job reaches a terminal state
from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()

# Retrieve a job by ID
job = service.job("<job_id>")

# Get job ID (useful for saving for later retrieval)
print(f"Job ID: {job.job_id()}")

# Check current status
print(f"Status: {job.status()}")

# Wait for job to complete (blocking call)
job.wait_for_final_state()
print("Job completed")

# Get results
results = job.result()
print(results)

Why a job stays "In progress"

You might notice that a job (using either job mode or batch mode) you expect to take only a few seconds stays in the In progress status (called RUNNING in Qiskit) for much longer. This is normal, and it does not mean the job is consuming that entire time as usage. It happens because of how jobs are scheduled onto a QPU:

  • Every job requires classical pre-processing before it can run on the QPU. A job moves to In progress (RUNNING) as soon as this classical processing begins — not when it starts executing on the QPU.
  • Most of this classical processing runs in parallel, so multiple jobs can be In progress at the same time.
  • However, only one job at a time can run on the QPU. When several jobs finish their classical processing and are ready to execute, they must wait their turn for the QPU. This is known as QPU contention. When contention is high, a job can remain In progress noticeably longer than the few seconds of QPU time it actually needs.
  • Contention can also occur when a system-maintenance task, such as calibration, is running on the QPU. Your job stays In progress until the maintenance task completes and the QPU becomes available.

Because of this, the elapsed wall-clock time a job spends In progress is not the same as its usage. Both the estimated usage and the maximum execution time are based only on the time the QPU is locked to execute your job, and therefore exclude the multi-threaded classical processing described above. A long In progress time does not increase your reported usage or cost.

Session mode is different

The preceding behavior applies to job mode and batch mode. In session mode, during the session's active window, the user has exclusive access to the backend and no other jobs can run, including calibration jobs. Therefore, any QPU contention happens only among your own session jobs. In addition, because QPU capacity is reserved for the duration of the session, session usage is measured as the elapsed time while the session remains active, regardless of whether jobs are actively running. See Workload usage for more information.


View remaining usage

Track how much of your plan's usage quota remains.

Use the service.usage() method to get usage information for your current active instance.

from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()

# Get usage information for the current active instance
usage = service.usage()
print(usage)

View job metrics

Get an overview of your job submissions, including batch and session workload metrics.

Use the service.jobs() method with filters to retrieve information about your submitted jobs, such as how many have been submitted, what their statuses are, and when they were created. The following example retrieves all jobs submitted in the last seven days and calculates the total usage from those jobs.

from datetime import datetime, timedelta
from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()

# Retrieve all jobs in the last 7 days
seven_days_ago = datetime.now() - timedelta(days=7)
jobs = service.jobs(limit=None, created_after=seven_days_ago)

# To retrieve all jobs in a Session or Batch, use the session_id filter
# jobs = service.jobs(session_id="<session id>")

total_usage = 0
for job in jobs:
    total_usage += job.usage()

print(f"{len(jobs)} jobs were submitted in the last 7 days.")
print(f"Total usage was {total_usage} seconds")

Retrieve job results at a later time

You can save job IDs and retrieve results later, even after closing your session.

If you saved the job ID when you submitted the job, use service.job(<job_id>) to retrieve it later. If you don't have the job ID, or if you want to retrieve multiple jobs at once (including jobs from retired QPUs), use service.jobs() instead, with optional filters.

See the QiskitRuntimeService.jobs API documentation for available filters.

This example demonstrates retrieving recent results run on a specific backend.

from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()

# Uncomment the next line to retrieve a specific job by ID
# job = service.job("<job_id>")

# Optionally retrieve multiple jobs with filters
# Use `limit` to retrieve a specific number of jobs. The default `limit` is 10.
my_backend = "<your-backend>"
recent_jobs = service.jobs(backend_name=my_backend, limit=10)

print(f"Retrieved {len(recent_jobs)} recent jobs from {my_backend}\n")

# Get results from all jobs
for job in recent_jobs:
    print(f"Job ID: {job.job_id()}")
    print(f"Status: {job.status()}")

    # Retrieve results if the job is complete
    if str(job.status()) == "DONE":
        try:
            results = job.result()
            print(f"Results: {results}")
        except Exception as e:
            print(f"Error retrieving results: {e}")
    else:
        print("Results: Not available (job still running or failed)")
    print()

Retrieve backend properties

You can use job.properties() to retrieve backend properties, including error rates, at the time of the job execution.

This example demonstrates how to retrieve backend properties that were current at the time a job was executed, including T1T_1/T2T_2 times and error rates for a specific qubit (0).

from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()

# Retrieve a specific job by ID
job = service.job("<job_id>")

print(f"Job ID: {job.job_id()}")
print(f"Backend: {job.backend}\n")

# Fetch backend properties at the time of job execution
properties = job.properties()

if properties:
    print("Backend Properties at Job Execution Time:")
    print("=" * 60)

    # Get T1 (relaxation time) for qubit 0
    t1 = properties.t1(0)
    print(f"Qubit 0 T1 (relaxation time): {t1}")

    # Get T2 (dephasing time) for qubit 0
    t2 = properties.t2(0)
    print(f"Qubit 0 T2 (dephasing time): {t2}")

    # Get readout error for qubit 0
    readout_error = properties.readout_error(0)
    print(f"Qubit 0 readout error: {readout_error}")

    # Get all properties for a specific qubit
    print("All properties for qubit 0:")
    qubit_props = properties.qubit_property(0)
    for prop_name, prop_value in qubit_props.items():
        print(f"  {prop_name}: {prop_value}")
else:
    print("No properties available for this job")
Deprecated provider packages

service.jobs() also returns jobs run from the deprecated qiskit-ibm-provider package. Jobs submitted by the older (also deprecated) qiskit-ibmq-provider package are no longer available.


Cancel a job

Cancel a job that is queued or running. Once a job is canceled, it cannot be resumed.

Use the job.cancel() method to cancel a job programmatically.

from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()

# Retrieve the job
job = service.job("<job_id>")

# Cancel the job
job.cancel()

print(f"Job {job.job_id()} has been canceled")

Next steps

Recommendations