IL-0523 U.S. Department of Health and Human Services · 2023-09-07database
TANF-app production deployments were blocked for two months when a search-index migration ran out of database disk space
TANF-app is a Django application whose production database is a PostgreSQL instance on cloud.gov. The team counts the incident, from 7 September to 9 November 2023, as several incidents combined. A previously deployed search_indexes migration, 0016, had been deleted and later recreated, which caused the first deployment failures and made fixing deployments more complex. When the sprint 82 release ran on 20 September, the large migration search_indexes 0017 grew the database's temporary space beyond the instance storage and failed with a disk space error, and production stayed blocked for two months while staging problems and blocked pipelines added delay.
In November the team reproduced the disk failure in its raft environment by lowering the instance storage to 20gb, and listed ways out: split large migrations into smaller ones, raise the postgres tmp_file_limit, increase the instance storage in cloud.gov, or wipe the temp table space by creating a new instance from a backup. On 8 November the production instance size was increased and the migrations were re-run, which exposed a second problem: the migration failed converting a blank string to an integer. T3 rows submitted with a single case and no space-filling for the second case had passed through the value_is_empty check during parsing because of a Python substring quirk and were stored as blank strings. Correct field types in the models would have kept the migrations from failing.
On 9 November, to avoid creating a new database, the team backed up the production database, truncated all of the search_indexes tables, whose data it was not worried about losing, and redeployed the sprint 82 release. Production was restored to sprint 82 and deployments could move forward. The blank-string parsing bug was fixed in a separate pull request.
- Severity
- –
- Scope
- TANF-app production deployments were blocked from 7 September to 9 November 2023
- Users affected
- –
- Region
- –
- Time to detect
- –
- Time to resolve
- 63d
Symptoms
On 20 September 2023 the sprint 82 production deployment of TANF-app failed with a disk space error while it ran a large search-index migration, search_indexes 0017, against the production PostgreSQL database on cloud.gov. Production could not be deployed again until 9 November.
The deployment trouble had begun on 7 September with the failed sprint 80 deployment. A search_indexes migration that had already been deployed, 0016, was deleted, and makemigrations and migrate were commented out in the deployed environments to force manual migrations. The sprint 82 release uncommented them and recreated the broken 0016. Between the two deployments, develop pipelines were blocked for various reasons, and after 20 September staging problems kept the release from reaching production.
On 1 November the team tried to reproduce the failure in its raft environment with 700k to 1m rows each of t1, t2, t3, t4 and t5. During the migrations the database size grew up to 8x and fell back to its starting level when they finished, and temp_files grew by about 4gb after completion, but the migrations ran even with far more records than production. The team put this down to a difference in some database settings. On 6 November, lowering the raft database instance storage to 20gb reproduced the failure after several migration runs, as the temp space eventually exceeded the instance size.
On 8 November the production database instance size was increased and the migrations were run again. They then failed with a new error about converting a blank string to an integer. Every character field in T3 had some records with the value '' (blank string) instead of None.
Symptom Deploys failingNode disk full
Root cause
Root cause Faulty deployment
- Trigger
- The sprint 82 deployment on 20 September 2023 recreated the deleted search_indexes migration 0016 and ran the large migration search_indexes 0017 against the production database.
Detection
The sprint 82 production deployment failed with a disk space error, and the large migration search_indexes 0017 was identified as the cause.
Remediation
- Increased the production database instance size and re-ran the migrations
- Created a backup of the production database
- Truncated all of the search_indexes tables
- Redeployed the sprint 82 release
- Fixed the bug that stored empty fields as blank strings
Action items
- Write troubleshooting steps for database problems into the technical documentation
- Write wiki pages and operations playbooks that outline common problems and responses
- Add a database section and the cf revisions command to the failed-deployment troubleshooting document
- Keep a GitHub repository of changes made directly to production
- Save terminal output from production debugging sessions
- Create Django migration best practices to enforce in code reviews
- Do not edit migrations that have been merged to develop; write a new migration instead
- Rename auto-generated migrations to more descriptive names
- Use one auto-generated migration per model change and regenerate when a pull request makes successive changes
- Organise a discussion on database seeding and backups for testing
Lessons
The work was unplanned and pulled in many developers from a small team, so the team wants documentation and playbooks that let fewer people step away from current work. Large datasets and unexpected edge cases such as rows without space-fill had not been tested, and a copy of the production database with PII scrubbed would allow tests against real-world data. Deploying in-progress code to other environments and changing migrations afterwards had caused conflicts there.
Sources
References
Related cases
IL-0570Dropping an unused MySQL table stalled queries on its busy parent table and crowdworks.jp was hard to reach for a minuteCrowdWorks · 2026same root cause · shared Database, Schema migration
IL-0369Railway's backend API went down when a column migration waited on locks and replicas could not get database connectionsRailway · 2025same root cause · shared Database, Schema migration
IL-0554A database migration used up Sentry US's Postgres connections, and the site and event ingestion were down for 22 minutesSentry · 2024same root cause · shared Database, Schema migration
IL-0524An index migration locked Open Collective's whole Transactions table and degraded the service for nearly an hourOpen Collective · 2023same root cause · shared Database, Schema migration
IL-0391GoCardless API requests timed out for about 15 seconds while a Postgres migration waited for an AccessExclusive lockGoCardless · 2015same root cause · shared Database, Schema migration
IL-0356Every domain hosted on Railway returned HTTP 404 to new connections for five minutes because route lookups failedRailway · 2026same root cause · shared Database
IL-0136A deployment that cleared an internal service's caches at peak traffic sent 20 times the normal load to the Azure OpenAI metadata backend in Sweden Central, and health checks that depended on its database restarted instances in a loop for almost six hoursMicrosoft Azure · 2026same root cause · shared Database
IL-0510MIT Learn's RDS PostgreSQL ran out of storage after a release and learn.mit.edu returned 503s and 504s for hoursMIT Open Learning · 2026same root cause · shared Database
IL-0380A compaction change in InfluxDB Cloud us-east-1 dropped data from compacted files, and queries missed data for weeksInfluxData · 2026same root cause · shared Database
IL-0547Buildkite annotation queries timed out and drove database CPU up across shards after a migration removed an indexBuildkite · 2025same root cause · shared Database
IL-0315Railway's backend API went down when an index build locked a billion-row Postgres table and used up every connectionRailway · 2025same root cause · shared Database
IL-0327After a blue/green upgrade of CircleCI's workflows database every query hit disk, and workflow starts lagged or failedCircleCI · 2025same root cause · shared Database
IL-0324Three MediaWiki deployments lost Memcached after a PHP 8.1 rollout and overloaded the External Storage database clusterWikimedia Foundation · 2025same root cause · shared Database
IL-0307Supabase's Postgres connection pooler Supavisor 2.0 dropped connections for about 80% of us-east-1 tenantsSupabase · 2025same root cause · shared Database
IL-0552CircleCI's archival database ran out of storage, slowing workflow and job starts and the display of workflows in the UICircleCI · 2025same root cause · shared Database
IL-0571STORES reservation returned bursts of 504 errors when a smart-list query held a database process for over 20 minutesSTORES · 2024same root cause · shared Database
IL-0293Cloud Bigtable in us-central1 had higher latency and connection errors for about 32 hours from low-rate packet lossGoogle Cloud · 2023same root cause · shared Database
IL-0567Aurora MySQL behind Cookie Run: OvenBreak hit 100% CPU after a sales-ranking feature launch, and players could not playDevsisters · 2023same root cause · shared Database
IL-0483Replicate's website and API returned slow responses and HTTP 500s for two hours as PostgreSQL connections ran outReplicate · 2023same root cause · shared Database
IL-0371Half of new connections to Render Postgres databases with point-in-time recovery failed while their backup jobs ranRender · 2023same root cause · shared Database
IL-0328A field type change in the database of CircleCI's job distribution service left all jobs stuck in "not running"CircleCI · 2021same root cause · shared Database
IL-0566Hot ranges after a Cookie Run: Kingdom guild update drove CockroachDB nodes to 100% CPU, forcing emergency maintenanceDevsisters · 2021same root cause · shared Database
Check your cluster for this
For AI tools and scripts
- This case as JSON: https://incidentlib-api.benchlet.com/cases/IL-0523
- The cases most like it: https://incidentlib-api.benchlet.com/cases/IL-0523/similar
- MCP server (Streamable HTTP, no key):
https://incidentlib-mcp.benchlet.com/mcp
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.