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 that actually matters: “is this better or worse than before?” Service level objectives (SLOs) give that reference point 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 compares against it.

  • Representative load: the baseline should be run 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 the state it would normally be in during 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 subsequent tests, use MaxoPerf’s Compare view to load the baseline alongside the new run. Latency and throughput series render on the same axes so regressions are immediately visible.

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.”

This is fully testable 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 — thresholds that automatically fail a run if breached. This is how SLOs become 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). This makes failure criteria 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 are out of budget.

The error budget glossary entry defines the formal calculation. In performance testing, error budgets give teams a clear criterion for escalation: spend the budget investigating and fixing, not arguing about whether the result is a problem.

MaxoPerf doesn’t manage error budgets directly — that belongs in your observability platform or SLO tracker. What MaxoPerf contributes is 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 most powerful setup: run a performance test in CI on every merge, compare to the baseline, and fail the pipeline if failure criteria are breached. This 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 they are findable 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.