Incident Library

IL-0301 37signals · 2022-06-27database

Basecamp 3's primary database went into total gridlock at the top of the hour and Basecamp 3 went down twice

Basecamp 3's primary database runs at very high concurrency, with thousands of connections from the Rails application servers and hundreds of execution threads on a large many-CPU server. At 13:00 UTC on June 27, 2022, when scheduled notifications go out in massive batches, a rush of demanding queries caused heavy lock contention. Queries waiting on locks held database resources and sometimes their own locks, and new queries kept arriving and opening new connections and threads that waited on the same locks, until the server was overwhelmed. 37signals found no single trigger: Basecamp 3's steady growth had moved the primary database close to its limits, and a review of the past year of database metrics found several quiet performance regressions that had added load without setting off any alarm.

The team paused parts of Basecamp 3, which slowed the pile-up, and terminated thousands of queries, which made it grow faster because the rollbacks wait on the same locks. The team then failed over to a replica by the book. Basecamp 3 came back, and then the database tipped over again from a different mix of factors, again lock contention under high concurrency. The team put Basecamp 3 into maintenance mode and set hard limits on database query time, which let the congestion clear, and then brought features back step by step with the query limits in place. The all-clear came at 15:49 UTC, nearly three hours after the start, with 103 minutes of downtime. No data was lost, and HEY, Basecamp 2 and Basecamp Classic were not affected.

Severity
–
Scope
Basecamp 3 was slow, showed errors and was down for 103 minutes in total between 13:00 and 15:49 UTC; HEY, Basecamp 2 and Basecamp Classic were not affected and no data was lost
Users affected
Basecamp 3 users
Region
–
Time to detect
–
Time to resolve
2h 49m

Symptoms

At 13:00 UTC on Monday, June 27, 2022, Basecamp 3 became extremely slow, then showed error pages, and then stopped working altogether. Basecamp 2 and Basecamp Classic kept working normally.

Between 13:00:00 and 13:00:30 UTC the Basecamp 3 primary database went from normal to completely congested. Queries piled up behind locks, and new queries kept arriving, opening new database connections and threads that waited on the same locks, until the server hardware was overwhelmed by thousands of threads. The database had not crashed, but it could not make progress.

The outage came in waves. After a failover to a replica, Basecamp 3 came back and paused features were re-enabled, and then the database tipped over again with the same kind of lock contention under high concurrency. Basecamp 3 was back around 15:45 UTC, and the all-clear came at 15:49 UTC with 103 minutes of downtime in total.

The first countermeasures did not stop it. Pausing and disabling parts of Basecamp 3, such as delaying progress report emails, only slowed the growth of the pile-up. Terminating thousands of bottlenecked queries made it grow faster, because each terminated query rolls back its whole transaction, and the rollback waits on the same locks.

Symptom Lock contention or deadlockDatabase overloadHigh latencyHigh error rateService outage

Root cause

Trigger
At 13:00 UTC, when Basecamp 3 sends scheduled notifications in massive batches, a rush of demanding queries reached the primary database and started a cascade of heavy lock contention.

Detection

The team saw the Basecamp 3 primary database become completely congested within 30 seconds of 13:00 UTC and responded immediately.

Remediation

Action items

Lessons

A system running just past its limits can flip from stable to unstable without any particular trigger, and steady growth plus small regressions that raised no alarm had brought Basecamp 3's primary database to that point. Under lock contention, terminating queries does not relieve the database, because rolling back their transactions waits on the same locks. The team struggled to respond with confidence because there was no single clear cause and little visibility into the database's internals.

Sources

Related cases

Check your cluster for this

kubegap audits a Kubernetes cluster for conditions like the ones in this case, Database among them, read-only, from Claude Code or Codex. Its checks cite public reports like this one.

For AI tools and scripts

The API needs no key. The MCP server offers search_incidents, get_incident, list_incidents, get_topic and vocab; both are explained on API and MCP.