ChaiCart Incident INC-0001 · Launch Day
09:00 — ChaiCart launched in 5 cities. A push notification went to 2.1 million users.
09:03 — Checkout success rate crashed from 99% to 38%. Customers see “Payment stuck on spinner…” for 30 seconds, then an error.
09:10 — The CEO is drafting an angry tweet. You have 25 minutes to find the killer before it's posted.
| Exhibit | Contents |
|---|---|
| A | Metrics dashboard (08:45 – 09:15) |
| B | Logs from all services |
| C | Three distributed traces |
| D | Change log & tickets |
| E | Witness statements |
| F | Bonus: a code snippet (for the brave) |
| — | Accusation Form (hand this in!) |
app → checkout-service → cart-service
↳ payment-service → orders-db (PostgreSQL) + PayFast gateway (external)
Also running: redis cache (menus & carts), log-server (collects logs)
“I was just sitting there. Nobody even talked to me.”
“Tiny config tweak. FinOps approved it!”
“My status page is green.”
“I've been this full for two days. Nobody cares.”
“Hit ratio 94%, same as always.”
“You planned for 5×. Don't blame me.”
All charts: 08:45 → 09:15, one point per minute. Dashed line = 09:00 launch push notification.
Collected from all services. Sorted by time. Not everything here is relevant!
[2 days ago] 18:02:11 INFO [payment-service] Starting payment-service v2.3.0 (build 51d0e2c) 18:02:12 INFO [payment-service] HikariPool-1 - configuration: maximumPoolSize=50 connectionTimeout=30000 18:40:03 WARN [log-server] Disk usage at 96% on /var/log (threshold 95%) [Launch day] 08:45:00 INFO [redis] Keyspace hits=94.2% evicted_keys=0 08:50:14 INFO [checkout-service] POST /api/checkout 200 (312 ms) trace=a1f3… 08:55:40 WARN [log-server] Disk usage at 97% on /var/log (threshold 95%) 08:58:02 INFO [payment-service] Starting payment-service v2.3.1 (build 7f3c9a1) 08:58:03 INFO [payment-service] HikariPool-1 - configuration: maximumPoolSize=5 connectionTimeout=30000 08:58:05 INFO [payment-service] HikariPool-1 - Start completed. 08:58:30 INFO [orders-db] connection closed: user=payment_svc (x45) 09:00:00 INFO [notification-service] Campaign LAUNCH sent to 2,104,332 devices 09:00:41 INFO [checkout-service] POST /api/checkout 200 (298 ms) 09:01:52 WARN [payment-service] HikariPool-1 - Pool stats (total=5, active=5, idle=0, waiting=31) 09:02:13 WARN [payment-service] HikariPool-1 - Pool stats (total=5, active=5, idle=0, waiting=87) 09:02:43 ERROR [payment-service] HikariPool-1 - Connection is not available, request timed out after 30000ms. 09:02:43 ERROR [checkout-service] POST /api/checkout failed: 504 Gateway Timeout from payment-service (30012 ms) 09:02:44 INFO [redis] Keyspace hits=94.1% evicted_keys=0 09:02:55 WARN [log-server] Disk usage at 97% on /var/log (threshold 95%) 09:03:10 INFO [orders-db] checkpoint complete: wrote 312 buffers (0.4%); active connections=5 09:03:12 ERROR [payment-service] HikariPool-1 - Connection is not available, request timed out after 30000ms. 09:03:14 INFO [payfast-client] Gateway health check OK (latency 204 ms) 09:03:30 WARN [frontend] Client error rate spike: "Payment stuck on spinner" x 1,284 09:03:41 INFO [checkout-service] POST /api/checkout 200 (18,902 ms) 09:04:02 ERROR [payment-service] HikariPool-1 - Connection is not available, request timed out after 30000ms. 09:04:05 INFO [orders-db] LOG: duration: 11.8 ms statement: INSERT INTO payments … 09:04:20 INFO [cart-service] GET /api/cart 200 (17 ms) 09:05:00 WARN [payment-service] HikariPool-1 - Pool stats (total=5, active=5, idle=0, waiting=214)
Each bar is a span. Bar length is proportional to duration within that trace. Striped = waiting.
| When | What | Details |
|---|---|---|
| 2 days ago 18:40 | Alert | OPS-311 “log-server disk > 95%” — acknowledged, “clean old logs after launch”. |
| Yesterday 18:00 | Deploy | frontend v5.0 — new launch banner & animations. Load tested: yes. |
| Today 08:30 | Config | redis — no change, health check only. |
| Today 08:58 | Deploy | payment-service v2.3.1 — FINOPS-482 “Right-size DB tier: reduce connection pool to lower DB cost”. Reviewer: cost-bot (approved). Load test: skipped — launch day rush. Rollout: 100% at once. |
| Today 09:00 | Marketing | Launch push notification to 2.1M users. Expected traffic: up to 5× normal. |
From payment-service. For teams who want the extra credit (+25): what makes the problem worse?
@Transactional // opens a DB connection for the whole method
public PaymentResult pay(Order order) {
paymentsRepo.insertPending(order); // ~12 ms on the DB
GatewayResponse r = payFast.charge(order); // ~205 ms external HTTP call
paymentsRepo.markResult(order, r.status()); // ~5 ms on the DB
return PaymentResult.from(r);
}
Team name: ______________________ Time handed in: ________
| The killer (who) | |
|---|---|
| The weapon (how exactly?) | |
| Accomplice (if any) | |
| Evidence – a metric | |
| Evidence – a log line | |
| Evidence – a trace | |
| Why the others are innocent | |
| Immediate fix | |
| How to prevent it next time |