AI SWE Prep
0/9in System Design
System Design

Observability & Reliability

Metrics, logs, and traces; SLOs and error budgets; and the failure patterns (timeouts, retries, circuit breakers) that keep systems up.

~14 minLesson 52 of 60
Your progressNot started

A system is reliable only if you can see what it is doing and shape how it fails. Observability gives you the evidence: metrics, logs, and traces. Reliability patterns turn that evidence into behavior: timeouts, retries, circuit breakers, bulkheads, and graceful degradation.

The senior move is to define reliability before the outage. What matters to users? How much failure is acceptable? What does the system do when a dependency is slow, wrong, or unavailable?

The mental model

Observability connects a user promise to machine signals.

user promise -> SLI -> SLO -> alert -> mitigation
"checkout works" -> successful checkouts / attempts -> 99.9% monthly

Reliability engineering starts with the promise, not the dashboard. If the chart cannot explain user pain or protect an error budget, it is decoration.

The three pillars

Pillar What it answers Example
Metrics What is happening over time? request rate, p95 latency, error rate, queue depth
Logs What happened in this specific event? structured error with user id, request id, dependency status
Traces Where did this request spend time? API -> auth -> database -> payment provider spans

Use all three together. Metrics tell you something is wrong. Traces tell you where. Logs tell you why this particular request failed.

SLI, SLO, and error budget

The three pillars of observabilitytap a column to focus
MetricsLogsTraces
Shapenumeric time seriesdiscrete eventscausal spans
Answersis it broken?what happened?where / why slow?
Cardinalitylowhighhigh
Costcheapcan explodesampled
Use metrics to detect, traces to localize, logs to explain — together, not alone.

An SLI is the measurement. An SLO is the target. The error budget is how much unreliability you are allowed before you slow down risky changes.

Term Example
SLI Fraction of checkout requests that complete successfully under 800 ms
SLO 99.9% of checkout requests meet that SLI over 30 days
Error budget 0.1% of requests may fail or be too slow

Time-based intuition helps: 99.9% monthly availability allows about 43 minutes of badness per 30 days. 99.99% allows about 4.3 minutes. Each extra nine is an engineering and product commitment, not a slogan.

Reliability patterns

Pattern What it prevents Key detail
Timeout Hanging forever on a dependency Set shorter than the user-visible deadline
Retry with backoff + jitter Transient failures Retry only safe/idempotent operations
Circuit breaker Repeated calls to a failing dependency Fail fast while probing for recovery
Bulkhead One dependency consuming all resources Separate pools/queues per dependency or tenant
Graceful degradation Total failure when optional features fail Return core experience without recommendations, avatars, etc.

Retries deserve suspicion. Retrying a slow dependency can multiply traffic into an outage. Use budgets: if the request deadline is 500 ms, three 500 ms retries are not a reliability strategy.

Pattern recognition

Variations

Worked problems

Reliability scenarios are about evidence and blast radius. Avoid vague answers like “add monitoring”; say exactly what you measure and what the system does.

ScenarioMedium
  • SLO
  • SLI
  • Error budget

Define SLOs for checkout

A checkout service takes payment and creates an order. Product asks for “five nines” because checkout is important. Define practical SLIs/SLOs and explain how the error budget guides engineering work.

Approach. Tie the SLO to user-visible success, not internal uptime. Use a latency threshold and a correctness threshold, then calculate the budget.

Show solution

Good SLIs:

SLI Why it matters
Successful checkout attempts / valid checkout attempts Captures user-visible failure
p95 or p99 checkout latency under 1.5 sec Captures slow-but-not-failed pain
Duplicate charge rate Captures correctness, not just availability

A practical initial SLO might be:

99.9% of valid checkout attempts complete successfully within 1.5 seconds over 30 days
0 duplicate charges caused by our system

For 10 million monthly checkouts, a 99.9% success SLO allows 10,000 bad attempts before the budget is exhausted. That sounds large, so you may choose 99.95% or 99.99% after looking at user harm and engineering cost.

If the service burns half its monthly error budget in one day, freeze risky launches and prioritize reliability work. If it has months of unused budget, the team may be over-investing in reliability relative to product speed.

ScenarioHard
  • Circuit breaker
  • Timeouts
  • Fallbacks

Add a circuit breaker to a flaky dependency

Your recommendation service calls a third-party ranking API. When that API slows or times out, your own p99 latency spikes and worker threads pile up. Design the failure behavior and sketch the circuit breaker logic.

Approach. Put a strict timeout around the call, track recent failures, open the circuit after a threshold, and return a fallback while probing recovery.

Show solution
import time

class CircuitBreaker:
    def __init__(self, max_failures=5, reset_after=30):
        self.max_failures = max_failures
        self.reset_after = reset_after
        self.failures = 0
        self.opened_at = None

    def allow(self):
        if self.opened_at is None:
            return True
        return time.monotonic() - self.opened_at >= self.reset_after

    def record_success(self):
        self.failures = 0
        self.opened_at = None

    def record_failure(self):
        self.failures += 1
        if self.failures >= self.max_failures:
            self.opened_at = time.monotonic()

def get_recommendations(user_id, breaker):
    if not breaker.allow():
        return cached_or_popular_recommendations(user_id)
    try:
        result = call_ranker(user_id, timeout_ms=150)
    except TimeoutError:
        breaker.record_failure()
        return cached_or_popular_recommendations(user_id)
    breaker.record_success()
    return result

The real design details:

  • The timeout must fit inside the page’s total latency budget.
  • The fallback should be acceptable product behavior, such as cached or popular items.
  • The breaker should expose metrics: open/closed state, failures, fallback rate.
  • Use jittered retries only if the operation is safe and the deadline allows it.

This prevents a slow optional dependency from consuming all worker capacity.

ScenarioMedium
  • Metrics
  • Traces
  • Logs

Debug a p99 latency spike

At 10:05, p99 latency for POST /orders jumps from 700 ms to 4 sec. Error rate rises slightly. CPU is normal, database latency is normal, and request volume is unchanged. How do you investigate, and what fix do you try first?

Approach. Start from service-level metrics, then use traces to find the slow span. Logs confirm whether the slow path correlates with errors, tenants, or a recent deploy.

Show solution

Investigation path:

1. Metrics: confirm latency spike, error rate, traffic, saturation.
2. Break down by endpoint, region, tenant, and status code.
3. Traces: compare a normal order trace with a slow p99 trace.
4. Logs: inspect request ids from slow traces for dependency errors/timeouts.
5. Change history: check deploys, config changes, dependency incidents.

Given CPU and database are normal, traces likely point to an external span: payment provider, tax calculation, fraud check, or shipping quote. If slow traces show payment.authorize taking 3.5 sec, the first mitigation is a tighter timeout plus controlled retry/fallback behavior that fits the checkout contract.

Do not blindly add instances. The app tier is not saturated. More instances may increase concurrent calls to the slow provider and make the incident worse.

The classic pitfall

Your progressNot started