Skip to content

Baselines, SLOs, and error budgets

A load test result without a reference point is just a number. You need a baseline, a known-good result, to answer the question you care about: “is this better or worse than before?” Service level objectives (SLOs) give that reference point a formal structure. Error budgets tell you how much worse is acceptable before you need to act.

A baseline is a recorded performance result taken when the system is behaving as expected. It is your control. Every future test run is compared against it.

  • Representative load: run the baseline at the same VU count, think time, and location(s) as your ongoing tests. A baseline at 10 VUs doesn’t help you evaluate behavior at 100 VUs.
  • Stable conditions: the system under test should be in its normal state under production-representative load: caches warmed, connection pools initialized, typical data volume.
  • Tagged and noted: in MaxoPerf, add a run note and tag the baseline run so you can find it quickly when comparing.

After a clean run that reflects normal system behavior:

  1. Open the run-detail page.
  2. Add a note: “Baseline: deployment v1.4.2, 2026-06-07, 100 VUs, 15 min hold.”
  3. Tag the run as baseline so the Runs list can be filtered.
  4. Save the run URL to your team’s reference doc.

When you run later tests, use MaxoPerf’s Compare view to load the baseline next to the new run. Latency and throughput series share the same axes, so regressions stand out at once.

An SLO is a target for a service quality metric, expressed as a threshold over a time window. For performance testing, the most common SLO targets are:

  • p95 latency < 400 ms (at a defined load level)
  • error rate < 0.1%
  • throughput ≥ 150 RPS at 100 VUs

The SLO glossary entry has the formal definition and the relationship to SLAs.

A testable SLO has four parts: metric + percentile + threshold + load condition.

PartExample
Metricp95 latency
Threshold< 500 ms
Load conditionat 200 concurrent VUs
Optional: time windowaveraged over a 10-minute steady-state hold

“p95 latency for POST /v1/checkout must be under 500 ms at 200 concurrent VUs over a 10-minute steady-state run.”

You can test this in MaxoPerf: configure the test at 200 VUs with a 10-minute hold, then check the p95 latency on the Overview tab after the run.

MaxoPerf lets you configure failure criteria on a test. These are thresholds that fail a run automatically when breached. They turn SLOs into automated gates:

reporting:
- module: final-stats
summary: true
percentiles: [50, 90, 95, 99]
failed-labels: []
criteria:
- avg-rt > 500ms : stop as failed
- p95 > 1000ms : stop as failed
- fail > 1% : stop as failed

When any criterion is breached, MaxoPerf marks the run as Failed and stops it (or flags it, depending on configuration). Failure criteria are the machine-readable version of your SLO.

See the Failure criteria / pass-fail gates recipe for the full configuration walk-through.

An error budget is the amount of SLO miss you are willing to tolerate over a time window before taking action. It converts a percentage-based SLO into a concrete number.

Example: if your SLO is “p95 latency under 500 ms for 99.5% of runs per month,” your error budget is 0.5% of runs. You can have roughly 2–3 runs per month that breach the threshold before you run out of budget.

The error budget glossary entry defines the formal calculation. In performance testing, error budgets give teams a clear rule for escalation. Spend the budget investigating and fixing, instead of arguing about whether the result is a problem.

MaxoPerf doesn’t manage error budgets directly. That belongs in your observability platform or SLO tracker. MaxoPerf supplies the measurement:

  • Run results provide the p95/p99 latency and error rate data points.
  • Failure criteria mark each run as passed or failed against the SLO threshold.
  • The Comparing runs and baselines recipe shows how to track regression across many runs.

The strongest setup runs a performance test in CI on every merge, compares it to the baseline, and fails the pipeline if failure criteria are breached. It catches regressions before they deploy.

See CI-gated performance test for the full implementation. The Comparing runs and baselines recipe shows how to automate baseline comparison.

DoDon’t
Write SLOs with explicit percentiles, thresholds, and load conditions.Write vague SLOs like “latency should be acceptable”. They are not testable.
Tag baseline runs in MaxoPerf so you can find them for comparison.Treat every new run as the new baseline. You lose the historical record.
Set failure criteria on the test so runs self-assess against the SLO.Rely on manual post-run review to catch every regression.
Review SLOs after major architecture changes. The old baseline may no longer apply.Keep the same SLO threshold forever regardless of architectural changes.