Incident Library

IL-0510 MIT Open Learning · 2026-03-24databaseaws

MIT Learn's RDS PostgreSQL ran out of storage after a release and learn.mit.edu returned 503s and 504s for hours

The learning resource APIs of MIT Learn were slow, especially the featured resources API, and Sentry pointed at a large query that fetched all view events to count them. An engineer changed the query pattern so that the main query contained an aggregation. The team's two most senior engineers reviewed the change, it showed no issues locally or on the RC environment, and it went out in a regular release. DRF computes the count field of a paginated response by running SELECT COUNT * ($QUERY) over the whole query; with the aggregation inside, this worked on smaller datasets but not on production data. On the RDS PostgreSQL instance ol-mitlearn-db-production in us-east-1, the query thrashed temporary files, filled the storage and backed up the database's internal work so that new transactions could not be processed.

The change was rolled back and the database was declared up at 4:31, but the site returned 503 errors again at 4:51. The team deleted the read replica so the database could flush buffered WAL files, dropped the replication slot and ran VACUUM ANALYZE, without bringing DiskQueueDepth down. After an RDS backup finished, and with help from AWS Support, the team terminated every active query that had been running for more than 10 minutes with pg_terminate_backend. Free storage and DiskQueueDepth then returned to normal around 6:24 PM. The write-up gives the total outage as 3 hours and 35 seconds.

Afterwards the team changed the view count to use a precomputed column, and response times of the affected APIs went from ~13-15s to 150-200ms. AWS Support recommended testing ORM query changes with production-like data volumes and EXPLAIN ANALYZE, setting temp_file_limit and log_temp_files, and considering RDS Optimized Reads, which place temporary files on local NVMe storage instead of EBS.

Severity
–
Scope
learn.mit.edu returned 503 and 504 errors while the production database was out of storage
Users affected
–
Region
us-east-1
Time to detect
–
Time to resolve
3h

Symptoms

On 24 March 2026 learn.mit.edu went down shortly after a regular release. An engineer reported the outage with a linked Sentry issue, and Sentry soon showed many 504 responses from the site.

The MIT Learn production database had used up all of its usable storage, and the growth had started at 18:35 UTC. The PostgreSQL server was thrashing its temporary filesystem. The RDS FreeStorageSpace metric dropped, and later the CheckpointLag and DiskQueueDepth metrics looked unhealthy; the team treats DiskQueueDepth as the critical health metric for RDS.

The first suspects were the Qdrant cluster and a pgdump snapshot an engineer had just created, and both were ruled out within about ten minutes. The engineer who wrote the release's query pattern change then identified it as the cause. The database was declared up and stable at 4:31, but the site still returned 503 errors at 4:51, and when the site was reported back at 5:26, DiskQueueDepth was still unhealthy.

Deleting the read replica so the database could flush its buffered WAL files, dropping the replication slot and running VACUUM ANALYZE did not bring DiskQueueDepth down. Dropping the slot had minimal effect, and VACUUM ANALYZE started a number of additional queries and may have made the problem worse.

Symptom Service outageNode disk fullDatabase overloadLock contention or deadlock

Root cause

Trigger
A regular release deployed a query pattern change to the learning resource APIs that put an aggregation inside the main query.

Detection

An engineer reported the outage with a linked Sentry issue, and Sentry showed many 504 responses. The RDS FreeStorageSpace metric showed that the database had used up its storage.

Remediation

Action items

Lessons

The change was reviewed by senior engineers and showed no problems locally or on RC, but data scale and load in production are very different, and nothing in the system's health showed that adding a COUNT aggregation would make disk usage explode.

Sources

References

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.