An SLO is useful when two people can calculate it from the same data and agree on the result. That requires a defined user action, a rule for success, and a measurement window. The percentage comes after those choices.
This tutorial uses a hypothetical order-status API to build an SLO, calculate its error budget, and decide when failures need attention. The numbers are teaching examples, not Pingy measurements or recommended targets for every service.
Separate the measurement from the promise
A service level indicator (SLI) measures service behavior. A service level objective (SLO) sets the target for that indicator over a stated window. An error budget is the allowance for outcomes that miss the target.
A service level agreement (SLA) adds agreed consequences for missing a service commitment. An internal objective is often stricter than the customer commitment so the team has room to respond. Compare their measurement rules before comparing their percentages: a request success target and a contract based on eligible downtime can describe different things. Google's service-level terminology explains this distinction.
Write the internal SLO and customer-facing terms separately. Record the scope, exclusions, measurement source, window and owner for each. A dependency's advertised SLA is also a commitment under its own rules; it does not establish your application's measured availability.
Define one user action precisely
For the example API, the useful outcome is receiving the requested order's current status. A homepage returning HTTP 200 says little about that action. Start with a narrow specification that you can audit against individual events. Google's example SLO document shows how to record an objective alongside its implementation.
Here is our hypothetical starting specification:
| Item | Definition |
|---|---|
| Scope | Production order-status reads |
| Eligible | Authenticated reads of orders the caller can access |
| Good | Correct status returned within 800 ms |
| Bad | Every eligible read that misses either condition |
| Target | At least 99.9% good |
| Window | Rolling 30 days |
| Owner | API team |
Measure elapsed time at the client for this example. Count a timeout as bad even if the server finishes later. Record one outcome per eligible client attempt, including retries. Exclude synthetic checks and requests for which the caller lacks access, and retain the reason for each exclusion. That makes the denominator inspectable.
These choices need application instrumentation. HTTP status alone cannot establish that the returned order is correct. A team that currently has only edge logs should publish a narrower SLI describing what those logs capture, then add coverage. Keep the implementation's blind spots beside the objective.
This combined success-and-latency SLO counts an attempt that is both wrong and slow only once. Separate availability and latency objectives are another valid design, but each needs its own budget.
Count failures in the same units as the SLI
For a completed window containing 2,000,000 eligible attempts, a 99.9% target allows 2,000 bad attempts. If 800 were bad, the observed SLI is 99.96%, and 40% of the budget has been used:
allowed = 2,000,000 x 0.001 = 2,000
used = 800 / 2,000 = 40%
remaining = 2,000 - 800 = 1,200
Those 1,200 attempts are headroom in that measured window. The total changes as requests enter and leave a rolling window. AWS documents this behavior for request-based error budgets.
Add good and total counts across instances before dividing. An unweighted average of instance percentages gives a quiet instance the same influence as a busy one. Keep regional and operation-level views too, so a large volume of successful reads cannot conceal a smaller critical operation that is failing.
Downtime uses different units. For continuous time-based availability over exactly 30 days, 0.1% is 43.2 minutes and 0.5% is 216 minutes, or 3.6 hours. Google's availability table makes the equal-weighting assumption explicit. You cannot convert a request budget into those durations without assumptions about traffic and failure distribution.
For example, a hypothetical ten-minute failure at 100 eligible requests per minute costs 1,000 requests. The same duration at 10,000 per minute costs 100,000. A monitor that samples once per minute measures its samples; it does not observe every request between them.
Choose a target users can live with
Use incident history and support reports to judge the damage caused by a failed action. Compare that with the staffing, engineering work and infrastructure needed to reduce failures. Google's discussion of reliability risk frames this as a product and engineering decision with real costs.
Historical performance helps test whether a proposed target is achievable. It cannot settle whether users will tolerate that target. There is no universal requirement to wait 90 days or subtract a fixed margin from the best observed result. Start with a provisional objective, document the evidence you have, and set a review date.
Choose the window deliberately. A rolling window continuously includes recent failures; a calendar window aligns with a reporting period. Both are valid. Google's SLO implementation guide discusses these tradeoffs and recommends four-week rolling windows as a general starting point. Our example uses 30 days so its calculations are explicit. A calendar month may have a different length.
Watch how quickly the budget is being used
A monthly score can look acceptable while a new incident is consuming the remaining allowance. Burn rate compares the recent bad-event fraction with the fraction allowed by the SLO:
burn rate = recent bad fraction / (1 - SLO)
For the hypothetical 99.9% target, a 0.5% recent bad fraction gives a burn rate of 5. A sustained rate above 1 would miss the target over a full window. Google's burn-rate documentation explains that normalization and the role of fast and slow alerts.
Under constant request volume, a rate of 5 for one hour would consume about 0.69% of a full 30-day budget: 5 x 1 / 720. This is a planning estimate. With uneven traffic, calculate actual consumption from bad-event counts and the window's total requests. Do not present a fixed time-to-exhaustion as a promise, especially when some budget is already spent.
Google's SLO alerting chapter gives these starting points for a 30-day objective:
| Alert | Both windows | Burn rate |
|---|---|---|
| Fast page | 1 hour and 5 minutes | Above 14.4 |
| Slower page | 6 hours and 30 minutes | Above 6 |
| Ticket | 3 days and 6 hours | Above 1 |
Within each row, both windows must exceed the threshold. The short window checks that failures are still happening. Combine the two paging rows with OR and suppress duplicate notifications. These are starting values to replay against your own incident history, not guaranteed detection times.
Low traffic needs separate review: one failure can produce a large ratio. Check whether that failure justifies waking someone. Keep synthetic traffic distinguishable from customer traffic so successful probes cannot dilute customer failures.
Keep measurement gaps visible
Edge logs miss attempts that never reach the edge. Client telemetry can observe more of the journey, but its reporting path can fail too. External probes test selected routes, locations and request types. Google's comparison of SLI implementations describes these coverage limits.
Use these signals together. Multi-region monitoring can expose a regional failure while the aggregate request SLI still passes. A successful health check covers only what that check exercised.
For the example API, flag missing telemetry as incomplete evidence. With zero eligible requests, the ratio is undefined; investigate whether there was no traffic or collection failed. Record coverage gaps in the review instead of silently reporting perfect service.
Agree on the release policy before an incident
A budget needs an owner who can change priorities. Google's example error-budget policy pauses most releases after exhaustion, keeps exceptions for urgent and security fixes, and resumes when the service is within its objective again.
Write a policy for your service that names who makes that call, which changes may continue, and what evidence permits normal releases to resume. A healthy budget still requires safe rollout and rollback procedures. An exhausted rolling budget has no single reset date; recovery depends on the events entering and leaving the window.
Before adopting the example, replay a known incident through the calculation. Inspect several bad events and exclusions by hand. Confirm that the alert reaches the responsible team and opens the right runbook. If the SLI passed while users could not retrieve their orders, fix the scope or measurement before trusting the next report.