Blog

SLA vs SLO vs SLI: one example from measurement to promise, and why the SLO must be stricter than the SLA

Follow one API from SLI to SLO to SLA: what to measure, how to turn a target into an error budget, and how much buffer to keep between goal and promise.

In the SLA vs SLO vs SLI question, the three terms form a chain: the SLI (service level indicator) is a measurement, the SLO (service level objective) is the internal target you set for that measurement, and the SLA (service level agreement) is the contractual promise to customers, with consequences such as service credits if you miss it. The SLO should always be stricter than the SLA, so you notice and fix problems while they still cost you nothing.

Most explanations stop at definitions. This guide follows one service through all three layers, with the actual numbers, queries and the reasoning behind each choice.

SLA vs SLO vs SLI in one sentence each

  • SLI: a ratio of good events to valid events, for example the share of HTTP requests that succeeded fast enough.
  • SLO: a target for that ratio over a time window, for example 99.9% over 28 days. Missing it triggers internal action, not payments.
  • SLA: a contract that names a (usually lower) target, how it is measured, what is excluded and what the customer gets if you miss it.

If you want short definitions of related terms like MTTR or multi-region consensus, the monitoring glossary covers them. The rest of this article is about how the three connect in practice.

The running example: an invoicing API

Imagine a small SaaS company that sells an invoicing API. Customers call POST /v1/invoices from their own backends. If the API fails or is very slow, their checkout flows break. The team has one load balancer, a few application servers and a managed database.

We will take this API from raw measurement to a signed customer promise.

Step 1: Define the SLI

An SLI answers one question: from the user's point of view, was this event good or bad? For the invoicing API, a request counts as good if it returns a non-5xx status and completes in under 500 ms. Client errors like 400 or 404 are excluded from the bad count because they reflect the caller's input, not your service.

The resulting SLI is a ratio:

SLI = good requests / valid requests

good  = status not 5xx AND latency < 500 ms
valid = all requests except health checks and internal traffic

With Prometheus and a latency histogram, the 28-day value looks like this:

sum(increase(http_request_duration_seconds_bucket{job="invoice-api",code!~"5..",le="0.5"}[28d]))
/
sum(increase(http_request_duration_seconds_count{job="invoice-api"}[28d]))

Two decisions matter more than the query itself:

  • Where you measure. Load balancer logs see requests your app never received. Application metrics miss requests that died at the proxy. Measure as close to the user as you can.
  • What counts as one event. Request-based SLIs weight busy hours more heavily. Time-based SLIs (was the service up in this minute?) treat 3 a.m. the same as peak traffic. Pick the one that matches how customers experience failure.

Step 2: Set the SLO and derive the error budget

The team decides on this SLO:

service: invoice-api
sli: requests non-5xx and under 500 ms / valid requests
objective: 99.9%
window: rolling 28 days
owner: platform team

The inverse of the SLO is the error budget: the amount of badness you are allowed. For 99.9% over 28 days, that is 0.1% of the window. In time, 28 days are 40,320 minutes, so the budget is about 40 minutes of full outage. In requests, if the API serves 10 million valid requests in 28 days, the budget is 10,000 bad requests.

The budget turns the SLO into something you can alert on. The burn rate tells you how fast you are spending it: a burn rate of 1 uses exactly the budget over the full window. If 5% of requests start failing, the burn rate is 50 (5% divided by 0.1%), and the whole 28-day budget is gone in about 13.4 hours. A complete outage has a burn rate of 1000 and empties the budget in roughly 40 minutes.

A practical alert pair for this SLO:

  • Page when the last hour burned more than 2% of the 28-day budget (burn rate above about 13.4).
  • Open a ticket when the last 6 hours burned more than 5% of the budget (burn rate above about 5.6).

Finally, write down what happens when the budget runs out. A common error budget policy: pause risky deploys and feature launches until the SLI recovers, and run a postmortem for any single incident that consumed more than 20% of the budget. The blameless postmortem template fits that step well.

Step 3: Write the SLA customers can hold you to

The SLA is not the SLO with a signature. It is a separate, simpler definition that a customer can verify and a non-engineer can read. For the invoicing API, the team commits to:

Monthly Uptime Percentage: 99.5% per calendar month

Downtime: a minute in which the API returns 5xx errors
or no response to external checks from at least two regions.

Exclusions: scheduled maintenance announced 48 hours in advance,
failures caused by the customer, and force majeure.

Service credits (example):
  below 99.5%  -> 10% of the monthly fee
  below 99.0%  -> 25% of the monthly fee

Claims: submitted within 30 days of the end of the month.

Notice what changed compared to the SLO:

  • The target is lower: 99.5% instead of 99.9%.
  • The window is a calendar month, because invoices and credits are monthly.
  • Latency is gone. Slow but successful responses are hard to prove from the customer's side, so the contract only covers availability.
  • The measurement is external: checks from multiple regions, not your internal metrics.

In a 30-day month, 99.5% allows 216 minutes of downtime, or 3 hours and 36 minutes. In a 31-day month it is about 223 minutes. If you want the full table of what each percentage allows, see how much downtime 99.9% uptime allows per month.

Why the SLO must be stricter than the SLA

The SLO exists to warn you long before the SLA costs money, so it must be noticeably stricter than the promise you sign. In the example, the internal budget is about 40 minutes per 28 days, while the contract tolerates about 216 minutes per month. That gap of roughly five times is deliberate, for several reasons.

Your measurement and the customer's measurement differ

Internal metrics, external checks and the customer's own logs never agree perfectly. DNS problems, a regional network issue or a CDN edge failure may show up for customers before your application sees anything. Buffer absorbs that disagreement.

You need time to react

Burning through the SLO budget should trigger a deploy freeze and reliability work. If SLO and SLA were equal, the first time you learned about a problem would be the moment you owed credits.

Missing an SLO should be cheap

A missed SLO is a signal to change priorities. A missed SLA is a financial and trust event. Keeping them apart lets you set ambitious internal goals without legal risk.

Windows do not line up

A rolling 28-day SLO and a calendar-month SLA can disagree near month boundaries. One bad incident on the 30th counts fully against one SLA month but is spread across two SLO evaluations. Margin covers these edge cases.

How to choose the numbers

  1. Measure first. Run the SLI for four to eight weeks before committing to any target. Without history, every number is a guess.
  2. Set the SLO slightly below a normal period, not your best one. If you achieved 99.95% in an average month and 99.99% in a quiet one, 99.9% is defensible. Setting the SLO at your best month guarantees constant budget exhaustion.
  3. Check your dependency ceiling. Serial dependencies multiply. If your API needs a database and a payment provider that each manage 99.95%, the combined ceiling is about 99.9% before your own code fails once.
  4. Translate the budget into minutes and test it against your response. 40 minutes per 28 days with one-minute check intervals and a five-minute on-call response leaves room for only a handful of incidents. If that is unrealistic for your team, lower the SLO.
  5. Derive the SLA from the SLO, never the other way around. Pick a target several times looser in allowed downtime, and only promise credits you can afford to pay in a bad month.
  6. Review quarterly. If you never touch the budget, the SLO may be too loose and you could ship faster. If you exhaust it every month, either the system or the target needs work.

Common mistakes

  • Promising 99.99% in the SLA because it sounds good. That is about 4 minutes per month, less than many teams need to acknowledge a page.
  • Using CPU or memory as SLIs. Users do not experience CPU. Measure requests, responses and latency.
  • One SLO for everything. A read endpoint and a payment endpoint deserve different targets. Start with one or two SLOs for the paths that matter most.
  • No exclusions defined. Without written rules for maintenance and customer-caused errors, every SLA discussion becomes a negotiation.
  • An SLO without a policy. If nothing changes when the budget is gone, the SLO is decoration.

Measuring the SLA from the outside

Internal metrics are good for the SLO, but the SLA in the example is defined by external checks from multiple regions. You can run those checks yourself from a few servers in different locations, or use a hosted service. m0nitor is one option: its uptime monitoring checks websites, APIs and servers on a fixed interval from distributed probes in several regions, and scheduled maintenance windows can be recorded so they line up with the exclusions in your contract. Whatever you use, make sure the measurement method in the SLA text matches the one you actually run.

FAQ

Should the SLA be higher or lower than the SLO?

Lower. The SLA is the contractual floor, the SLO the internal goal. In the example, the SLO is 99.9% over 28 days and the SLA is 99.5% per month, which leaves roughly five times more allowed downtime in the contract than in the internal target.

Can you have an SLO without an SLA?

Yes, and most services do. Internal services, free tiers and early products often have SLOs to guide engineering decisions but no contractual promise. Start with SLIs and SLOs, and only add an SLA when customers need a written commitment.

What is a good SLI for a website or API?

The share of requests that return a non-5xx status within a latency threshold that users would accept, such as 500 ms for an API. For a simple website, the share of one-minute intervals in which external checks from multiple regions succeeded is a practical start.

How do you calculate an error budget?

Multiply the window by one minus the SLO. For 99.9% over 28 days: 40,320 minutes times 0.001 equals about 40 minutes. For request-based SLIs, multiply the expected number of valid requests by the same factor, for example 10,000 bad requests out of 10 million.

Product

  • Pricing
  • Features
  • Integrations
  • Security
  • Free network check

Features

  • Uptime monitoring
  • Status pages
  • Alert workflows
  • Incident management
  • Dependencies
  • AI assistant
  • Global infrastructure
  • On-call schedules
  • Enterprise SSO

Use cases

  • Websites for free
  • Cron jobs
  • SSL certificates
  • Databases
  • IP blacklists
  • GDPR compliance

Resources

  • What is a status page?
  • Documentation
  • API
  • MCP server
  • Monitoring glossary
  • Free tools
  • SLA calculator
  • SSL checker
  • DNS lookup
  • Blog
  • Changelog
  • About
  • Contact

Compare

  • Free uptime monitoring
  • UptimeRobot
  • Better Stack
  • Pingdom
  • StatusCake
  • Uptime Kuma
  • Hyperping
  • Atlassian Statuspage
  • Instatus
  • Cachet
  • Freshping