human layer
report · published via claude · Jun 19, 2026 · 2 min read · readonly

Checkout outage traced to one connection pool

Checkout was down for 47 minutes on June 18 because one deploy halved the payment-service connection pool while doubling its connection hold time. Every other system stayed green, which is exactly why it took 22 minutes to find. The fix is a config guard, not a heroic rewrite.

source → Grafana — checkout golden signals, 2026-06-18+1 more

source · 147-minute checkout outage caused by pool exhaustion after deploy 2026.6.18-3; detection was slow because platform signals stayed greenquery: “what took checkout down on June 18 and why did detection take 22 minutesGrafana — checkout golden signals, 2026-06-18PagerDuty incident #4211 timeline
47 min
Time to recovery · SLO budget: 43 min / quarter
3,120
Failed checkouts
$86k
GMV delayed · recovered within 24h
22 min
Alert to root cause · p50 last 5 incidents: 14

source → Grafana — checkout golden signals, 2026-06-18+1 more

source · 2the four numbers that size the incidentquery: “duration, failed checkouts, GMV impact, time to root causeGrafana — checkout golden signals, 2026-06-18PagerDuty incident #4211 timeline

The shape of the outage

Checkout errors went from 0.6% to 14% inside eight minutes of the deploy while the platform-wide rate never left its baseline. A failure this local to one service, this correlated with one deploy, should have taken minutes to attribute — the divergence between the two lines is the entire diagnosis.

Checkout failed alone — the platform line never moved

5xx rate by surface, % of requests, June 18

View source data
tCheckoutAll other traffic
13:500.40.3
14:000.60.3
14:109.80.4
14:2014.20.5
14:3011.60.4
14:401.10.3
14:500.50.3
source: Grafana checkout golden signals, 2026-06-18

source → Grafana — checkout golden signals, 2026-06-18

source · 3checkout 5xx peaked at 14.2% while platform-wide errors held at baselinequery: “5xx rate for checkout vs all other traffic, 13:50–14:50 June 18Grafana — checkout golden signals, 2026-06-18

Timeline

Detection was fast; attribution was not. The 13 minutes between the page and the pool discovery were spent ruling out the usual suspects on dashboards that were, correctly, all green.

TimeEventState
14:02deploy 2026.6.18-3 ships payment-service v241healthy
14:07checkout error rate crosses 2%, first alert firesdegraded
14:11on-call paged; platform dashboards green, checkout reddegraded
14:24pgbouncer pool for checkout identified at 100% saturationdown
14:31deploy rolled back; pool drains in four minutesdegraded
14:49error rate back under SLO; incident closedhealthy

source → PagerDuty incident #4211 timeline

source · 4six-step incident timeline from deploy to close, 14:02–14:49query: “ordered incident timeline with system state at each stepPagerDuty incident #4211 timeline

The moment it surfaced

The root cause did not come from a dashboard. It came from asking why the database looked idle while checkout was starving — the answer was in pgbouncer, one layer above every graph we were staring at.

Marion (on-call) ·

DB CPU is at 30%, no lock pileup, no slow queries. Why is checkout timing out against an idle database?

assistant ·

Because it never reaches the database. The pgbouncer pool for checkout is pinned at 100/100 connections since 14:02 — v241 halved the pool to 100 and doubled hold time by moving payment capture inside the transaction. Requests are queueing at the pooler, not the DB.

Marion (on-call) ·

So the DB graphs were always going to be green. Rolling back.

source → PagerDuty incident #4211 timeline

source · 5verbatim excerpt where pool exhaustion was identified: pool halved + hold time doubled by v241query: “why does checkout time out while the database is idlePagerDuty incident #4211 timeline

What we ruled out

Traffic was flat — no spike, no bot surge, checkout volume within 4% of the previous Tuesday. The database was healthy the entire time: CPU under 35%, zero lock contention, p99 query time unchanged. And it was not a bad payment provider — provider latency held at baseline before, during, and after. Three green systems, one saturated pooler between them.

source → Grafana — checkout golden signals, 2026-06-18

source · 6traffic spike, database health, and provider latency ruled out; saturation sat in the unalerted pooler layerquery: “which usual suspects were eliminated and on what evidenceGrafana — checkout golden signals, 2026-06-18

source → PagerDuty incident #4211 timeline

source · 7RCA document, deploy diff, pooler dashboard, and channel export, all linkedquery: “where is the primary evidence for this incidentPagerDuty incident #4211 timeline
warning

One guard, this sprint. Pool limits are still deployable without review — the same two-line change would take checkout down again today. The config guard (block any deploy that shrinks a pool below observed peak concurrency) is small, owned by platform, and closes the class, not the instance.

query · 8the recurrence risk is open until pool-size changes require reviewquery: “what still allows this exact incident to repeat

Action items

  1. Platform ships the pool-size deploy guard — blocks any config lowering a pool below trailing 7-day peak concurrency (owner: Iris, June 27).
  2. Alert on pgbouncer pool saturation above 80% for five minutes, paging the owning service, not platform (owner: Marion, June 24).
  3. Canary stage gains a concurrency-proportional check so pool-class regressions surface at 5% traffic (owner: Théo, July 4).
  4. Payment capture moves back out of the transaction; hold time returns to the v240 baseline (owner: pay team, June 25).