What Is Chaos Engineering? Breaking Things on Purpose
Chaos engineering deliberately injects failures into production-like systems to find weaknesses before real outages do. How it works in practice.
Chaos engineering is the practice of deliberately injecting failures into a system — killing a server, cutting network connectivity, adding artificial latency — to find weaknesses before those same failures happen unexpectedly and take the system down for real. Instead of hoping your infrastructure is resilient, you test that claim directly, on purpose, usually while watching closely and with a way to stop immediately if things go wrong.
The reasoning behind it
Distributed systems fail in combinations that are hard to predict from reading the architecture diagram. A service might handle a dependency’s timeout gracefully in isolation, but combine that timeout with a retry storm from five other services all backing off at once, and the whole system can fall over in a way no one anticipated. Traditional testing — unit tests, integration tests, staging environments — mostly verifies that things work when everything behaves. It’s much weaker at surfacing what happens when something doesn’t.
Chaos engineering flips the default assumption. Rather than treating failure as an exceptional case to be handled defensively wherever someone remembers to add a try-catch, it treats failure as the expected condition to be tested for directly, the same way you’d test the success path. The practice was popularized by streaming and cloud companies running services at a scale where server failures weren’t hypothetical edge cases — they were a daily statistical certainty, and the only real question was whether the system noticed and recovered gracefully or fell over.
Common types of injected failure
Chaos experiments target different layers of a system, and most mature practices run all of these at some point:
- Instance termination — killing a running server or container to verify that traffic reroutes to healthy replicas and nothing depends on that specific instance surviving.
- Network faults — introducing latency, packet loss, or a full network partition between services to see whether timeouts, retries, and circuit breakers behave as designed rather than cascading into a wider outage.
- Resource exhaustion — deliberately consuming CPU, memory, or disk to confirm the system degrades predictably (shedding load, returning errors cleanly) instead of failing in an undefined way.
- Dependency failure — simulating a downstream API or database becoming unavailable, to check whether the calling service fails gracefully or drags every upstream caller down with it.
- Clock skew — shifting a system’s clock, which can expose bugs in anything relying on synchronized time across nodes, including TLS certificate validation and cache expiry logic.
Where it fits with everything else
Chaos engineering isn’t a replacement for other reliability practices — it’s a way of validating that they actually work under the conditions they were designed for. A few connections are worth calling out:
Observability comes first. You can’t learn anything from a chaos experiment if you can’t see what happened during it. Observability — metrics, logs, and traces that let you reconstruct system behavior after the fact — has to already be solid before chaos experiments are worth running; otherwise you’re breaking things blind.
It validates deployment safety nets. Techniques like blue-green and canary deployments exist to limit blast radius when something goes wrong during a release. Chaos experiments are a way to test that those safety nets actually catch failures, rather than assuming the rollback mechanism works because it was configured correctly on paper.
It’s a natural fit for orchestrated infrastructure. In a Kubernetes environment, killing a pod and confirming the deployment controller reschedules it — and that traffic doesn’t drop in the meantime — is one of the simplest and most common chaos experiments to start with, since the orchestration layer is already designed to expect and handle instance death.
Platform teams often own it. As organizations build internal developer platforms, chaos tooling frequently gets built into the platform itself, so individual teams can run standardized failure-injection experiments against their own services without each team building bespoke tooling.
Running an experiment safely
A responsible chaos experiment isn’t “randomly break production and see what happens.” It follows a fairly disciplined structure:
- Define a steady state. Pick a measurable signal — request success rate, latency percentile — that represents the system behaving normally.
- Form a hypothesis. State explicitly what you expect to happen: “if this database replica goes down, read traffic fails over within five seconds with no error rate increase.”
- Minimize blast radius. Start small — a single instance, a low percentage of traffic, a non-critical service — before expanding scope. Many teams start in staging entirely before ever touching production.
- Inject the failure and observe. Run the experiment, watch the steady-state metric, and confirm or refute the hypothesis.
- Have an abort path. Every experiment needs a fast, tested way to stop the injected failure immediately if the system’s behavior diverges badly from the hypothesis.
- Fix what broke, and automate the check. A surprising result is the actual point of the exercise — it’s a real weakness found before an outage found it instead. Turning validated experiments into regularly scheduled, automated runs is what keeps resilience from silently eroding as the system changes.
The takeaway
Chaos engineering tests resilience the same direct way you’d test any other requirement — by deliberately exercising the failure paths instead of hoping they’re never exercised for real. It depends on solid observability to be worth running at all, and it works best as a disciplined, hypothesis-driven practice with a tight blast radius and a fast abort path, not an ad hoc exercise in randomly breaking production. The organizations that do this well treat “does it survive a dependency failing” as a normal, recurring check — the same way they’d treat any other test that has to keep passing as the system evolves.
Keep reading
Chisato · · 4 min read Anatomy of an Outage: How a Bad Update Bricked 8.5M PCs
One faulty CrowdStrike update blue-screened 8.5 million Windows machines and grounded flights. A teardown of how a config file became a global outage.
Chisato · · 3 min read What Is a Runbook? Incident Response Playbooks
A runbook is a step-by-step document for handling a specific operational task or incident, turning tribal knowledge into a repeatable procedure.
Chisato · · 4 min read Connection Pooling vs Serverless Database Connections
Traditional connection pooling assumes long-lived servers. Serverless functions break that assumption — here's how proxies and edge drivers fix it.