Incident Library

IL-0524 Open Collective · 2023-04-04database

An index migration locked Open Collective's whole Transactions table and degraded the service for nearly an hour

On 4 April 2023 Open Collective deployed a migration that re-created indexes on the Transactions table with soft-deleted rows excluded, to improve performance. It had been tested locally and ran successfully on staging, and the pull request had been shared with the team but not reviewed. In production the index creation ran with CONCURRENTLY, but the numerous queries constantly hitting the table seem to have conflicted with it and the whole table locked. Because the old index was dropped before the new one was created, queries arriving in between used no index, which degraded performance further.

The deployment was triggered at 09:13 UTC and the degradation was noticed at 09:20. The team killed the migration, but the table remained locked. It put the frontend into maintenance mode to limit queries while showing users a clear message, closed the other connections to the database, cancelled the new index creation and restored the old index between 10:00 and 10:05 UTC. At 10:08 UTC the frontend was restored and the issue was confirmed resolved.

Severity
–
Scope
Open Collective's service was degraded while the Transactions table was locked, and the frontend was in maintenance mode for part of that time, from 09:20 to 10:08 UTC
Users affected
–
Region
–
Time to detect
7m
Time to resolve
55m

Symptoms

At 09:20 UTC on 4 April 2023, seven minutes after a deployment was triggered, Open Collective's service degraded: a migration in the deployment had locked the entire Transactions table in the production database.

The migration re-created indexes on the Transactions table so that soft-deleted rows were excluded, to improve performance. It dropped the old index and then created the new one, with CONCURRENTLY. The numerous queries constantly hitting the Transactions table seem to have conflicted with the migration and the table locked, and every query that arrived between the drop and the creation ran without an index, which added heavily to the slowdown.

Killing the migration did not end the problem, because the table remained locked. The migration had been tested locally and had run successfully on staging.

Symptom Lock contention or deadlockDatabase overload

Root cause

Trigger
A deployment ran a migration that dropped indexes on the Transactions table and re-created them with CONCURRENTLY, excluding soft-deleted rows.

Detection

The degradation of service was noticed at 09:20 UTC, seven minutes after the deployment was triggered.

Remediation

Action items

Lessons

Dropping the old index before creating the new one was too optimistic under constant production queries, even with CONCURRENTLY, and an unreviewed pull request let it through. Tests locally and on staging did not show the problem because there were no tools to run migrations in stressed environments. Putting the frontend in maintenance mode limited the impact while showing users a clear message.

Sources

References

Related cases

Check your cluster for this

kubegap audits a Kubernetes cluster for conditions like the ones in this case, Database, Schema migration 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.