What is an SLO, SLI, and SLA?

"Uptime" is a vague word. SLOs, SLIs, and SLAs replace vague words with precise numbers that drive engineering decisions, on-call policy, and customer commitments. Together they form the reliability vocabulary used by Site Reliability Engineering teams at Google, Amazon, and every organisation serious about operating production services.

Service Level Indicator (SLI)

An SLI is a metric that quantifies a specific aspect of your service's behaviour from a user's perspective. The key word is "user's perspective" - not a server metric like CPU usage, but something that reflects whether the service is working correctly for the people using it.

Common SLI categories:

  • Availability: percentage of requests that returned a successful response (non-5xx)
  • Latency: percentage of requests served in under a defined threshold (e.g. 200ms)
  • Throughput: number of requests processed per second
  • Error rate: percentage of requests resulting in an error
  • Freshness: time since data was last updated (for data pipelines)

A well-defined SLI has a clear numerator and denominator. For example: "the number of HTTP requests that returned a 2xx or 3xx response, divided by the total number of HTTP requests, measured over a rolling 30-day window."

Service Level Objective (SLO)

An SLO is an internal target you set for an SLI. It answers the question: "how reliable does this service need to be?"

Examples:

  • 99.9% of API requests return a non-error response in a rolling 30-day window
  • 95% of homepage requests are served in under 300ms
  • The data pipeline processes events within 60 seconds of receipt, 99.5% of the time

SLOs are internal. They are not published to customers and there are no contractual penalties for missing them. But they drive engineering decisions directly: when you are close to breaching an SLO, reliability work takes priority over new features.

Error Budget

An error budget is the inverse of your SLO - it is the amount of unreliability you are permitted before you breach your target.

SLOAllowed downtime per monthAllowed downtime per year
99%7.2 hours87.6 hours
99.9%43.8 minutes8.76 hours
99.99%4.38 minutes52.6 minutes
99.999%26.3 seconds5.26 minutes

A 99.9% availability SLO does not mean you must have zero downtime. It means you have a budget of 43.8 minutes per month to spend on incidents, planned maintenance, and deployments that cause transient errors. When that budget is nearly consumed, the engineering team pauses risky feature work until the budget replenishes next month.

Error budgets also inform alerting. Instead of paging on-call when the error rate spikes for five seconds, SRE teams alert on "error budget burn rate" - how fast you are consuming your monthly budget. A 14x burn rate (consuming a month's budget in two days) is worth waking someone up at 3am. A 1x burn rate is not.

Service Level Agreement (SLA)

An SLA is a formal contract with external customers. It is usually a weaker commitment than your internal SLO - you do not want to promise customers something you can only just achieve yourselves.

A typical SLA might commit to 99.9% availability and credit the customer 10% of their monthly bill for each additional hour of downtime beyond the threshold. The SLA is a legal and commercial document. Breaching it has financial consequences.

The relationship looks like this: your SLI measures what is actually happening, your SLO is the internal target you aim for, and your SLA is the external promise you make to customers - set conservatively enough that you almost never breach it even when internal incidents occur.

Connecting SLOs to Observability

Measuring SLOs requires the underlying observability infrastructure to be in place first. You need to be able to query "what percentage of requests in the last 30 days returned a 2xx?" from a metrics or log store.

Here is an example Prometheus recording rule that computes a 30-day availability SLI:

# prometheus-rules.yaml
groups:
  - name: slo_rules
    interval: 1m
    rules:
      - record: job:slo_availability:rate30d
        expr: |
          sum(rate(http_requests_total{job="api", code!~"5.."}[30d]))
          /
          sum(rate(http_requests_total{job="api"}[30d]))

      - alert: SLOBudgetBurnRateHigh
        expr: |
          (
            job:slo_availability:rate30d < 0.999
          )
        for: 5m
        labels:
          severity: page
        annotations:
          summary: "API availability SLO breach imminent"
          description: "30-day availability is {{ $value | humanizePercentage }}, below 99.9% SLO"

This rule fires when the 30-day availability window drops below 99.9%, giving the on-call engineer a precise, actionable alert tied directly to the SLO rather than a raw error count.

Frequently Asked Questions