Search documentationSearch

Measure throughput and efficiency

Break wall-clock time into queue, setup, compute and verification so you optimize the real bottleneck.

Before you start

A fixed test dataset and worker pool.

Per-phase timing reports and a repeatable throughput metric.

Measure useful throughput—how many validated results your workload produces per hour—and break wall-clock time into queue, setup, compute, and verification phases before tuning worker capacity.

1. Break wall-clock time into phases

When a calculation or benchmark feels slow, separate where the time actually goes before changing code or worker sizes:

PhaseWhat happensHow to measure it
1. Queue waitWaiting for a compatible worker with free CPU/GPU capacityJob admission timestamp → attempt start timestamp (ct-cli status JOB_UUID)
2. Environment setupChecking out code, syncing uv dependencies, and loading model checkpointsAttempt start → start of your calculation function
3. Scientific computeGeometry optimization, ML potential inference, MD integration, or ODE solvingtime.perf_counter() around the solver loop
4. Verification & scoringIndependent Hessian/IRC check or benchmark evaluator jobVerification/evaluator job duration
5. Artifact upload & saveUploading results/ files to storage and writing project recordsAttempt completion and save job duration

2. Record phase timings inside your job

The platform tracks job queueing and attempt duration automatically. To measure internal phases (like model loading vs. inference), record time.perf_counter() durations to a JSON file under results/:

python
import jsonimport timefrom pathlib import Path
t0 = time.perf_counter()model = load_model()t_load = time.perf_counter()
output = run_calculation(model)t_compute = time.perf_counter()
Path("results/timing.json").write_text(    json.dumps({        "model_load_s": round(t_load - t0, 3),        "compute_s": round(t_compute - t_load, 3),        "total_s": round(t_compute - t0, 3),    }))

Because results/timing.json is saved as a job artifact, your benchmark evaluator or reducer can aggregate model_load_s and compute_s across every item in a dataset.

3. Use throughput metrics that include failures

A candidate that runs 2× faster but fails verification 80% of the time reduces your real throughput. Always pair throughput rates with success/failure counts:

  • Transition-state search: Validated TSs per GPU-hour (alongside total attempts and failed verifications).
  • Structure optimization: Converged structures per minute.
  • Molecular dynamics: Trajectory integration steps per second and parsed frames per CPU-second.

4. Fix the actual bottleneck

Once you know which phase dominates wall-clock time, target that specific phase:

  • High setup/install time? Use the pre-installed native runtime profile (compute/runtime) instead of resolving environments per job (see Choose code and dependencies).
  • High queue wait time? Check worker pool capacity or connect additional machines (see Connect a worker).
  • High per-job startup overhead on tiny tasks? Batch more items per allocation or tune concurrency one variable at a time against a frozen benchmark dataset.