Module O-6·26 min read

Steady-state hypotheses, blast-radius control, latency and error injection, and GameDays that prove the A-6/A-7 breakers actually fire.

JJS
Written by Jatin Jain Saraf · Senior Software Engineer

Module O-6 — Chaos Engineering and Fault Injection

What this module covers: That every failure-handling path built across Phase 3 is untested code which runs for the first time during an incident — and that chaos engineering is the practice of running it deliberately instead. The experimental discipline: a steady-state hypothesis, a specific fault, the smallest possible blast radius, and a comparison. The prerequisites, stated honestly, because most teams attempt this before they can measure anything. Why latency injection is more revealing than error injection — systems generally handle errors and hang on slowness. Blast-radius control along six dimensions, and the automated abort tied to error-budget burn that is what makes a production experiment defensible rather than reckless. GameDays, which test the humans, the runbooks and the access that automated chaos cannot. Then the payoff pass: a table of the claims made in Phases 2 and 3 and the specific experiment that proves each one, because a circuit breaker that has never opened is a hypothesis and a fallback that has never run is a comment.


Every Failure Path Is Untested Code

Consider what Phase 3 built: circuit breakers, bulkheads, fallbacks, retry budgets, deadline propagation, load shedding, failover, degraded modes. Now ask a question about each one:

When did that code last execute in production?

For most systems the answer is "during the last incident," or "never." Which means the mechanisms you are relying on to survive a failure are the mechanisms least likely to work, because they have never run, and they will first run at the moment you can least afford a surprise. A fallback with a null-pointer error in it is worse than no fallback, because it creates the belief that you are protected (Module A-7).

Chaos engineering is the practice of making those paths execute on purpose, when you are watching, with a bounded blast radius. It is not "break things randomly." The distinction is that it is an experiment, and an experiment has a hypothesis.

The four steps:

  1. Define steady state as a measurable property of the system — an SLI, not an intuition. "99% of checkout requests succeed within 400 ms" (Module O-2).
  2. Hypothesise that steady state holds under a specific fault: "if the recommendations service returns 500s for all requests, checkout's success rate and latency remain within their SLO."
  3. Inject the fault in the smallest blast radius that can produce a signal.
  4. Compare. If steady state held, you have evidence rather than hope. If it broke, you have found a real weakness without a customer incident — which is the entire value proposition.

Two framings worth keeping. The goal is confidence, not breakage: you are buying evidence about the system's behaviour under conditions you cannot otherwise observe. And an experiment that finds nothing is a success — it is a validated claim, and treating "nothing happened" as a wasted afternoon is how the practice gets abandoned.

Analogy: a fire drill. Nobody runs one because they want a fire; they run one because the alarm, the routes, the muster point and the person with the register are all untested assumptions, and the day of an actual fire is the worst possible time to discover the rear door is chained shut. A drill has a hypothesis ("the building empties in four minutes"), a bounded scope (one floor, announced, at 10 a.m.), an abort condition, and a debrief. And crucially: a drill that reveals the chained door was a good drill, and the person who reports it must not be the person who gets blamed.


Prerequisites, Stated Honestly

Most teams attempt chaos too early, and the result is outages with no learning. You need four things first:

1. Observability (Module O-1). You cannot run an experiment you cannot measure. If you have no degraded-serve-rate metric, injecting a dependency failure teaches you nothing — the fallback might be working perfectly or not at all, and both look identical on an error-rate dashboard.

2. A defined steady state (Module O-2). Without an SLI, "did it still work?" is a matter of opinion, and there is no automated abort criterion.

3. A way to stop the experiment, instantly and reliably. A fault you cannot remove is an incident you caused.

4. Recovery you have already exercised manually. Do not discover your failover procedure inside an experiment; the experiment should validate a procedure you believe in, not substitute for writing one (Module O-7).

If you lack the first two, build them first. Chaos on an unobservable system is just an outage with extra steps.


Fault Types, and Why Latency Beats Errors

FaultValidatesBug it typically finds
Latency injectiontimeouts, bulkheads, deadlines (A-6, A-7)a missing timeout; a shared pool exhausted by one slow dependency
Error injection (5xx at a rate)retries, breakers, fallbacksbreaker thresholds wrong; a fallback that throws
Dependency unavailabledegradation (A-7)a fallback that depends on the failed thing
Instance / pod terminationstatelessness, draining (F-9, A-5)no drain delay → 502s on every deploy
Resource exhaustion (CPU/memory/disk)limits, OOM behaviouran unbounded queue or cache
Network partitionsplit-brain handling (A-1)two primaries; no witness
Packet loss / DNS failurediscovery, retries (A-5)a connection pool holding a stale address
Clock skewleases, tokens, ordering (A-1)a lease evaluated against a wall clock; JWTs rejected as not-yet-valid
Certificate expiryrenewal automationthe failure that takes someone down every year

Latency injection is the highest-value fault, and it is worth saying why. Most systems handle errors tolerably — an exception propagates, a retry fires, a fallback runs. Almost no system handles slowness well, because slowness is not an event: nothing throws, nothing is caught, and the effects accumulate. Adding 500 ms to one dependency reveals, in one experiment, whether you have a total timeout (Module A-6), whether that dependency has its own concurrency bulkhead (Module A-7), and whether the request path holds resources while it waits (Module P-4's pool). A dependency returning errors is a rehearsed scenario; a dependency that is merely slow is the one that takes systems down.

The clock skew row is worth a note too: it is easy to inject, almost never tested, and Module A-1 spent a section on why its failures are silent — a lease that is extended or expired by a clock adjustment, tokens rejected as not-yet-valid, ordering inverted between regions.


Blast-Radius Control, and the Automated Abort

This is the discipline that separates an experiment from an incident. Six dimensions to bound:

DimensionStartEscalate to
Environmentstagingproduction
Scopeone instanceone AZ, then a region
Traffic1% (or one test tenant)5%, 25%, all
Duration30 secondsminutes
Timinglow-traffic hours, team presentany time, unannounced
Fault intensity100 ms latency5 s, or full unavailability

Move along one dimension at a time, and only after the previous step held.

The automated abort is mandatory, and it is what makes a production experiment defensible. The experiment must halt itself the moment steady state degrades — driven by the SLO burn rate (Module O-2), not by a human noticing a dashboard:

text

Without this, you are relying on an engineer's attention as a safety control during the one activity where you have deliberately introduced a fault. With it, the worst case is a bounded, brief, self-limiting degradation — which is a defensible risk to take against the value of knowing whether your resilience works.

Three timing rules that are not negotiable. Never run an experiment during an active incident, during a launch or a change freeze, or when the error budget is already exhausted — because the budget is literally the currency you are spending, and spending it deliberately when you have none left is the case the policy exists to prevent (Module O-2).

Sign in to keep reading

The rest of this module is free — sign in with Google to unlock it and track your progress.

Sign in & Register

Discussion

0

Join the discussion

Loading comments...

© 2026 Jatin Jain Saraf (JJS). All rights reserved.