SD System Design In Depth
0%
design system-designobservabilityreliabilitydesign

Design: observability and SLOs

Module 6.3: High-Scale Media & Operations Designs Updated Sep 18, 2026
📄 Cheat Sheet
SREcon18 Europe - Real World SLOs and SLIs: A Deep Dive
USENIX SREcon18 Europe - Real World SLOs and SLIs: A Deep Dive Watch on YouTube ↗

A worked, practitioner-level session on choosing SLIs, setting SLOs and running them in production. This matches the case-study goal of designing observability around a user promise.

0:00 / --:--

Designing Observability and SLOs

An observability system connects a user's result to the work that produced it. It should help an operator answer three questions: is the service meeting its promise, which part failed, and did the repair work?

Without observability, operating a distributed system is like flying a plane blindfolded. If the checkout button stops working, you need to know immediately, and you need data to tell you whether it's the payment gateway, the inventory database, or a network partition.

The Three Pillars of Observability

  • Metrics: Aggregated numbers measured over time (e.g., requests per second, CPU usage, error rates). They are cheap to store and great for alerting. Tools: Prometheus, Datadog.
  • Logs: Discrete events recording what happened (e.g., "User 123 failed authentication because password expired"). They are expensive to store in high volume but crucial for deep debugging. Tools: ELK stack (Elasticsearch, Logstash, Kibana).
  • Traces: The lifecycle of a single request as it travels across multiple microservices. They show where the request spent its time. Tools: Jaeger, OpenTelemetry.

Service Level Objectives (SLOs)

Metrics don't mean anything without targets. We define:

  • SLI (Service Level Indicator): A carefully defined quantitative measure. Example: The proportion of HTTP GET requests to /api/cart that return HTTP 200 within 200ms.
  • SLO (Service Level Objective): A target value for the SLI. Example: 99.9% of requests over a rolling 30-day window must meet the SLI.
  • SLA (Service Level Agreement): An explicit contract with consequences (usually financial) if the SLO is not met.

Error Budgets

If an availability SLO is 99.9% over a 30-day window, the remaining 0.1% is about 43.2 minutes of unsuccessful eligible time. Event-based SLIs budget failed events rather than literal downtime.

An error-budget policy aligns product and operations on what to do when burn is excessive. Slowing risky launches is common, but freezing every release is not inherent to the metric; urgent security and reliability repairs may need to continue.

Architecture of a Monitoring System

A typical monitoring pipeline using Prometheus looks like this:

flowchart LR App1["App Instance 1"] -->|Exposes /metrics| Prom["Prometheus Server"] App2["App Instance 2"] -->|Exposes /metrics| Prom Prom --> AlertManager["AlertManager"] AlertManager --> PagerDuty["PagerDuty / Slack"] Prom --> Grafana["Grafana Dashboards"]

Applications instrument their code to maintain counters in memory. The Prometheus server "scrapes" (pulls) these metrics periodically. It evaluates recording rules and alerts. If an alert condition is met (for SLO-based alerting, e.g., the error budget burning 14.4x faster than sustainable over both the last hour and the last 5 minutes), it fires a webhook to an alerting service to wake up an on-call engineer.

Worked example: SLOs for a checkout service

SLIMeasured atGood eventSLO (28 days)Budget
AvailabilityLoad balancer logsResponse not 5xx, excluding client aborts99.9%About 40 min of full outage, or 0.1% of requests
LatencyLoad balancer histogramCompleted in under 400 ms99% of requests1% of requests may be slower
CorrectnessAsync order-audit jobOrder total matches the recomputed total99.99%1 in 10,000 orders

With 2 million checkouts in 28 days, the availability budget is 2,000 failed requests. A bad deploy that fails 5% of requests for 20 minutes, at about 50 requests per minute, uses about 50 of them, or 2.5% of the budget. A 1-hour 1.44% error ratio (a 14.4x burn) triggers the fast page.

Prometheus rules for the fast-burn page

Recording rules precompute error ratios over several windows, for example job:checkout_errors:ratio_rate5m and job:checkout_errors:ratio_rate1h, each defined as the rate of 5xx responses divided by the rate of all responses. The alert fires when both the 1-hour and the 5-minute ratios exceed 14.4 x 0.001. A slower ticket-level alert compares 6-hour and 30-minute windows against 6 x 0.001. Tools such as Sloth, Pyrra and OpenSLO generate these rules from a short SLO specification.

Sizing the metrics backend

  • 1.2 million active series, scraped every 15 s, is 80,000 samples per second. Prometheus's compressed TSDB typically uses about 1 to 2 bytes per sample, so about 7 to 14 GB per day.
  • Local Prometheus retention defaults to 15 days. Long-term storage and a global query view come from Thanos, Cortex or Mimir, backed by object storage.
  • The biggest cost risk is cardinality. One label containing user IDs can multiply series by 100,000. Enforce limits on series per metric at ingestion.

From page to fix

flowchart LR A["Burn-rate page"] --> D["SLO dashboard: which endpoint and region"] D --> R["RED metrics per dependency"] R --> T["Exemplar trace from a slow bucket"] T --> L["Logs by trace_id"] L --> F["Mitigate: roll back, fail over or shed load"] F --> P["Postmortem, budget consumed recorded"]
Check yourself Question 1 of 3
Symptoms not causes recall
From: Designing Observability and SLOs

A team pages on CPU above 80%. Why does the lesson prefer paging on SLO burn rate instead?

Error Budget and Multi-Window Burn-Rate Alerts

Burn rate = observed error rate ÷ allowed error rate (1 − SLO). A burn rate of 1 uses exactly the whole budget over the SLO window. Each alert fires only when both its long and short window are at or above the threshold: the long window gives significance, and the short window makes the alert stop soon after the incident ends. Traffic is assumed uniform, with a resolution of one minute.

Error budget remaining at the end of each day
Alert timeline

Key Takeaways

Combine metrics (for alerting), logs (for detail), and traces (for context) for full observability.
Define strict SLIs that measure user-facing symptoms, not just underlying system causes.
Use Error Budgets to balance feature velocity with system reliability.
Use distributed tracing with correlation IDs passed in HTTP headers to track requests across microservices.
Design alerts to trigger on symptom-based SLO burn rates rather than individual CPU spikes.
Was this lesson helpful? Spot an issue or have a suggestion? Let us know on GitHub.
Report an issue