Load Testing, Performance Testing and Chaos Engineering
Before the real sale arrives, send fake traffic and inject deliberate failures to check how much load and breakage the system can take.
49.1 Why is it used?
- Finding out on sale day that the DB falls over at 20K QPS is far too late; a load test tells you beforehand.
- Finding bottlenecks: a slow query, a small connection pool, too few threads, or network bandwidth.
- Capacity planning gets real numbers: how many req/sec one pod handles.
- Chaos engineering shows whether the system handles a server, AZ or dependency failure gracefully.
- Catch performance regressions after every release (p99 was 200ms before, why 600ms now?).
49.2 How it works
- Load test: run the system at expected traffic (say 50K RPS) and check latency and error rate.
- Stress test: keep raising load until the system breaks, to learn the breaking point and the failure behaviour.
- Spike test: suddenly go from 0 to 10x traffic (sale at 12 midnight or an IPL wicket) and see how fast autoscaling reacts.
- Soak/endurance test: run at normal load for 8-24 hours to catch memory leaks and connection leaks.
- Metrics: throughput (RPS), p50/p95/p99 latency, error rate, CPU/RAM, DB connections; look at p99, not the average.
- Chaos engineering: form a hypothesis ('if one AZ goes down, checkout keeps working'), inject the failure with a small blast radius, and observe.
- Failure types: instance kill, network latency/packet loss, CPU spike, dependency timeout, a whole AZ/region down (game day).
- 1.Load test: run at expected 50K RPS
- 2.Stress test: find the breaking point
- 3.Spike test: 0 -> 10x suddenly (sale at 12 midnight)
- 4.Soak test: 8-24 hours, catch memory leaks
- 1.k6 workers (multi-region): browse 70%, search 20%, checkout 10%
- 2.ALB -> App pods -> RDS DB
- 3.At 100K RPS the DB connection pool is full, p99 = 3 sec
- 4.Fix: bigger connection pool, RDS Proxy added, hot product pages in Redis cache
- 5.Retest: p99 = 300ms at 170K RPS
Look at p50 / p95 / p99 + error rate + DB connections, not the average; if k6 thresholds fail the CI pipeline goes red.
- 1.Hypothesis: if 1 AZ goes down, checkout keeps working
- 2.Inject: with a small blast radius (AWS FIS takes AZ-a down, ALB sends traffic to AZ-b and AZ-c; error rate only 0.2%)
- 3.Observe: metrics, alerts (+2s latency injected on the payment gateway, circuit breaker timeout + fallback, checkout does not hang entirely)
- 4.Fix + runbook: write down the findings
Netflix Chaos Monkey kills random instances in prod.
49.3 Tools
| Tool | Type | How it is used |
|---|---|---|
| Apache JMeter | Open-source load testing (GUI + CLI) | Build a test plan in the GUI and test HTTP, JDBC, JMS and more; Java based, old and very common. |
| k6 (Grafana k6) | Developer-friendly load testing | Script in JavaScript, run from the CLI, fits easily in a CI pipeline; results in Grafana. |
| Gatling | High-performance load testing | Script in a Scala/Java/Kotlin DSL; async engine, many virtual users from one machine, nice HTML report. |
| Locust | Python load testing | Write user behaviour in Python and generate load from many workers in distributed mode. |
| Chaos Monkey (Netflix) | Chaos engineering | Shuts down random instances in production so every service becomes failure-tolerant. |
| AWS Fault Injection Service (FIS) | Managed chaos service | Experiments such as EC2 stop, EKS pod delete, network disruption, AZ power interruption, with safe stop-conditions. |
| Gremlin / Chaos Mesh / LitmusChaos | Chaos platforms | Gremlin is SaaS; Chaos Mesh and Litmus are open-source chaos tools for Kubernetes. |
49.4 Comparison: JMeter vs k6 vs Gatling vs Locust
| Point | JMeter | k6 | Gatling | Locust |
|---|---|---|---|---|
| Script language | GUI / XML (.jmx) | JavaScript | Scala / Java / Kotlin | Python |
| Resource efficiency | Heavy, thread per user | Very efficient (Go engine) | Very efficient (async) | Medium, gevent based |
| Protocols | Most: HTTP, JDBC, FTP, JMS | HTTP, WebSocket, gRPC | HTTP, WebSocket, JMS | Mainly HTTP, custom ones can be written |
| CI/CD friendly | Possible but clunky | Very good, pass/fail via thresholds | Good | Good |
| Distributed load | Master-slave setup | k6 Cloud or k6-operator on K8s | In the enterprise version | Built-in master-worker |
| Learning curve | Easy start via the GUI | Easy if you know JS | Medium | Easy if you know Python |
| Best for | QA teams, multi-protocol | DevOps, perf tests in the pipeline | Very high load, detailed reports | Python teams, complex user flows |
49.5 When to choose which
- k6: the default for modern teams; a small perf test on every release in CI, and the pipeline goes red if thresholds fail.
- JMeter: when the QA team wants a GUI or needs to test non-HTTP protocols such as JDBC/JMS.
- Gatling: when you need to generate a very large load from one or two machines and want detailed reports.
- Locust: when you have a Python team and need to code a complex user journey (login -> search -> cart -> pay).
- Chaos: on AWS start with FIS; on Kubernetes use Chaos Mesh/Litmus; staging first, then controlled prod.
49.6 Real-world example
Netflix Chaos Monkey and a pre-sale load test (an illustrative scenario).
- Netflix publicly built Chaos Monkey, which kills random instances in production so engineers build failure-tolerant services.
- Using the same idea, an e-commerce team plans a 'game day' 3 weeks before the sale.
- The last sale peaked at 80K RPS; the target is 2x = 160K RPS, with a real user journey in the k6 scripts (browse 70%, search 20%, checkout 10%).
- Distributed k6 workers send load from multiple regions; at 100K RPS the DB connection pool fills up and p99 latency hits 3 sec.
- Fix: a bigger connection pool, RDS Proxy, and hot product pages in Redis cache; on retest p99 is 300ms at 170K RPS.
- Then AWS FIS shuts down the EC2/EKS nodes of one AZ; the load balancer sends traffic to the other 2 AZs and the error rate only reaches 0.2%.
- 2 sec of latency is injected into the payment gateway; the circuit breaker falls back on timeout and the whole checkout does not hang.
- All findings go into the runbook and sale day runs smoothly.
49.7 Interview tips
- Explain the difference between load, stress, spike and soak tests, and the chaos concept of 'hypothesis + blast radius'.
- Common mistake: the load generator machine itself becomes the bottleneck (CPU 100%) and you wrongly blame the server for being slow.
- Testing only one URL; if you do not test the real traffic mix and cache-miss scenarios, the result is false.
- Looking at average latency instead of p99, and running chaos in prod without a stop-condition or rollback plan. Number to quote: target 2x the last peak (80K -> 160K RPS).