IL-0282 Amazon Web Services · 2015-09-20databaseaws
DynamoDB in US-East reached about 55% request errors as storage servers overloaded its metadata service
DynamoDB splits each table into partitions and spreads them over many storage servers for low latency and durability. The group of partitions assigned to one storage server is its membership, which DynamoDB's internal metadata service manages; the metadata service is replicated and runs across several datacenters. Storage servers ask the metadata service for their membership periodically, after a network disruption and at startup, and if no answer comes within a set time they retry and temporarily stop accepting requests. In the months before the event, customers had rapidly adopted Global Secondary Indexes (GSIs), which let a table be read by alternate keys and have their own partitions on the storage servers. Several GSIs on a table with many partitions could quickly double or triple its share of the membership lists. Rapid adoption by customers with very large tables raised the size of some membership lists significantly, and the processing time of some membership requests came close to the storage servers' time limit. AWS did not monitor membership size closely enough and had not given the metadata service enough capacity for these heavier requests.
At 2:19am PDT a brief network disruption sent many storage servers to the metadata service at once. Simultaneous requests for large memberships slowed processing past the limit, the affected storage servers became unavailable and retried, and the slowed metadata service then failed renewals for healthy servers too. By 2:37am the customer error rate had risen far beyond any level of the previous 3 years, and it settled at about 55%. The load blocked the administrative requests needed to add capacity, so at 5:06am AWS paused requests to the metadata service. With the retries gone, the metadata service could take administrative requests, significant capacity was added, requests were turned back on and storage servers returned to the customer request path. At 7:10am PDT error rates were low enough for most customers and dependent AWS services to resume. Amazon SQS, which refreshes cached queue information from a DynamoDB table, had significantly elevated errors after DynamoDB finished disabling traffic at 5:45am, and recovered at 7:10am with no queue data lost. EC2 Auto Scaling, which keeps its groups and launch configurations in DynamoDB, had increased API faults from 2:15am to 7:10am and then worked through a backlog of launch and termination activities until 10:52am. CloudWatch, which adds Auto Scaling group membership from a DynamoDB table to incoming EC2 metrics, had intermittent EC2 metrics from 2:35am to 5:45am and elevated PutMetricData errors from about 5:51am to 7:10am, and fully recovered at 7:29am. AWS Console logins from 5:45am to 7:10am were much slower because an API call that relied on DynamoDB, and did not need to succeed for login, had a very long timeout; a shorter timeout was already in testing but not yet rolled out.
After the main recovery a low error rate of 0.15%-0.25% remained. AWS did not see early enough that it fell disproportionately on a small number of customers, and posted to the dashboard later than it should have on Monday. The cause was a metadata partition that was still not taking its full share of traffic, and the team restored it on Monday.
- Severity
- –
- Scope
- The error rate of DynamoDB customer requests in US-East rose far beyond normal by 2:37am PDT and settled at about 55% until error rates came down at 7:10am PDT; Amazon SQS, EC2 Auto Scaling, CloudWatch and AWS Console login were also affected, and some customers saw high error rates and stuck tables into Monday
- Users affected
- DynamoDB customers in US-East and customers of AWS services that depend on DynamoDB
- Region
- US-East
- Time to detect
- –
- Time to resolve
- 4h 51m
Symptoms
Early on Sunday 20 September 2015, the error rate of customer requests to Amazon DynamoDB in the US-East Region rose far beyond any level of the previous 3 years by 2:37am PDT and settled at about 55%. Some other AWS services in the region that depend on DynamoDB were affected as well.
Inside DynamoDB, the storage servers that hold the partitions of customer tables could not get their membership, the list of partitions assigned to them, from DynamoDB's internal metadata service within the time they allow for it. A storage server that cannot renew its membership in time takes itself out of the request path and retries. After a brief network disruption at 2:19am PDT, many storage servers asked for their membership at the same moment, the answers for the largest membership lists ran past the time limit, and those servers stopped taking requests.
The overloaded metadata service then also answered too slowly for storage servers that the network disruption had not touched and that were checking in on their normal schedule, so many of them became unavailable as well. Unavailable servers kept retrying and held the load high, and servers that had renewed successfully failed their next renewal and dropped out again. Downstream, Amazon SQS returned significantly elevated errors, EC2 Auto Scaling returned API faults and then lagged in launching and terminating instances until 10:52am PDT, CloudWatch had delayed and missing EC2 metrics and elevated errors on PutMetricData calls, and logins to the AWS Console became much slower.
Engineers first tried to add capacity to the metadata service, but the administrative requests needed for that failed under the same load, and several attempts did not work. After the main recovery, an error rate of 0.15%-0.25% remained. It looked too low to post on the service dashboard, but on Monday more customers opened support cases about tables stuck in the updating or deleting stage and higher than normal error rates, because that low overall rate fell heavily on a small number of customers.
Symptom High error rateDatabase overload
Root cause
Root cause Capacity exhaustion
- Trigger
- At 2:19am PDT a brief network disruption affected a portion of DynamoDB's storage servers, and they all requested their membership data from the metadata service at the same time.
Detection
For the errors that remained after the main recovery, a growing number of customer support cases on Monday about tables stuck in the updating or deleting stage and higher than normal error rates showed that the low overall error rate was hitting some customers hard.
Remediation
- Paused requests to the metadata service, which cut the retries and relieved its load
- Added significant capacity to the metadata service once it could answer administrative requests
- Turned requests to the metadata service back on and returned storage servers to the customer request path
- Restored a metadata partition that was still not taking its full traffic, ending the remaining errors on Monday
Action items
- Significantly increased the capacity of the metadata service, which AWS had already done by the time of the summary
- Add stricter monitoring on performance dimensions such as membership size, to plan capacity ahead
- Reduce the rate at which storage nodes request membership data
- Lengthen the time allowed to process membership queries
- Segment DynamoDB into many metadata service instances, each serving only part of the storage server fleet
- Change SQS metadata caching so send and receive keep working without long access to the metadata table
- Partition work across the Auto Scaling servers to process a backlog of scaling jobs in parallel
- Prune older scaling activities that have been superseded
- Increase the capacity available to process scaling activities
- Change CloudWatch caching of DynamoDB group membership data to refresh only the smallest set of metrics
- Deliver CloudWatch metrics faster through write-through caching
- Roll out the shorter timeout on the DynamoDB-dependent API call in Console login
Lessons
A low overall error rate can hide disproportionately high error rates for a few customers, and AWS should have posted to the dashboard sooner. A call that does not need to succeed, like the DynamoDB-dependent API call in Console login, should fail quickly instead of blocking on a very long timeout. Splitting the metadata service into many instances, each serving part of the fleet, is meant to contain the impact of software, capacity or infrastructure failures.
Sources
- https://aws.amazon.com/message/5467D2/ · official-status · archived copy
Related cases
IL-0450Oracle RAC commits behind order APIs kept waiting over 0.1 s on log file sync while average host CPU had headroomToss Securities · 2026same root cause · shared Database
IL-0553CircleCI's orchestration database filled its transaction log volume, and no workflows or jobs started for 50 minutesCircleCI · 2026same root cause · shared Database
IL-0379InfluxDB Cloud queries in Azure West Europe slowed and timed out as storage pods fell behind and kept restartingInfluxData · 2026same root cause · shared Database
IL-0309Preset's RDS PostgreSQL 14.7 to 17.9 upgrade in US East 1 ran out of storage and took Superset down for six hoursPreset · 2026same root cause · shared Database
IL-0435Error rates rose as Aurora MySQL killed connections and declined queries to avoid OOM while load metrics stayed flatCyberAgent · 2026same root cause · shared Database
IL-0497Buttondown's database ran out of connections twice in one day and requests failed while health checks mostly passedButtondown · 2026same root cause · shared Database
IL-0288ZooKeeperWait rose to thousands of seconds on three redundant ClickHouse instances, degrading a CDN77 data pipelineCDN77 · 2026same root cause · shared Database
IL-0350Hosts in an IONOS TXL cluster lost connectivity when an InfiniBand fabric resweep failed on a full multicast tableIONOS Cloud · 2026same root cause · shared Database
IL-0305Replicas of one Intercom Vitess shard hit 100% CPU and fell up to 2.2 hours behind, serving stale inbox dataIntercom · 2026same root cause · shared Database
IL-0390PostHog US Cloud event ingestion slowed to delays of up to 2 days as writes to the Persons Postgres table stalledPostHog · 2025same root cause · shared Database
IL-0100PostHog's feature flags pods were packed onto Kubernetes nodes that were too small for their CPU requests, and CPU saturation above 90% caused three outages in ten days through Redis overload, connection pool exhaustion and slow queriesPostHog · 2025same root cause · shared Database
IL-0287One overloaded shard of MongoDB's internal monitoring database delayed Atlas metrics, alerts and cluster operationsMongoDB · 2025same root cause · shared Database
IL-0557Database transaction locks piled up on Storj's US1 satellite, and uploads and downloads failed with timeouts for 2 hoursStorj · 2025same root cause · shared Database
IL-0551Bitbucket Cloud's overloaded primary database failed over, and the website, API and Pipelines were slow for almost a dayAtlassian · 2025same root cause · shared Database
IL-0298Wikimedia edits failed for 38 minutes when sessionstore Cassandra nodes in both data centres crashed on full disksWikimedia Foundation · 2025same root cause · shared Database
IL-0312Gadget's main Postgres did not start again after a restart to raise max_connections, and the platform went downGadget · 2024same root cause · shared Database
IL-0544Wasabi's database cache stopped responding when its queueing service filled up, and S3 failed in all regionsWasabi · 2024same root cause · shared Database
IL-0447An every RDS for MySQL instance slowed badly when its gp2 EBS BurstBalance ran out and IOPS fell to the baselineevery · 2024same root cause · shared Database
IL-0375MongoDB Atlas cluster changes and alerts lagged for hours after a control plane metadata migration congested a databaseMongoDB · 2024same root cause · shared Database
IL-0110A Grafana Agent pod's high memory use and crash-looping Hangfire pods drove a Kubernetes node into system OOM and NotReady, twice in one dayDFDS · 2024same root cause · shared Database
IL-0550Bitbucket Cloud's database slowed until connection pools saturated and requests timed out, leaving Pipelines pendingAtlassian · 2024same root cause · shared Database
IL-0270Discord's ScyllaDB authentication cluster overloaded during an OS upgrade, and logins failed for about 50 minutesDiscord · 2023same root cause · shared Database
IL-0202A burst of queries and database writes exhausted connection pools and memory on Honeycomb's ingest hosts, and Kubernetes crash-loop back-off kept failed hosts offline so ingest capacity stayed too low to recoverHoneycomb · 2023 · sev1same root cause · shared Database
IL-0386After a move to Google Cloud, Postgres connection timeouts and memcached i/o timeouts spiked on GKE nodesincident.io · 2023same root cause · shared Database
IL-0326A retention clean-up job filled the disk of MailPace's managed Postgres, which stayed offline for just over two hoursMailPace · 2023same root cause · shared Database
IL-0546Buildkite jobs could not go to newly connected agents once agent IDs passed a 32-bit integer foreign key's limitBuildkite · 2023same root cause · shared Database
IL-0500UToronto JupyterHub logins and server starts returned 500 errors when the hub's sqlite database disk filled up2i2c · 2022same root cause · shared Database
IL-0301Basecamp 3's primary database went into total gridlock at the top of the hour and Basecamp 3 went down twice37signals · 2022same root cause · shared Database
IL-0206Consul agents in GitLab.com's GKE pods were repeatedly OOM-killed, so the Rails pods lost database replica discovery and sent every query to the primaryGitLab · 2022same root cause · shared Database
IL-0302Peak load on GitHub's mysql1 MySQL cluster maxed out its database proxy's connections and stopped writes in March 2022GitHub · 2022same root cause · shared Database
IL-0212Many Slack users could not connect because a Vitess keyspace for channel membership was overloaded by cache-miss queriesSlack · 2022same root cause · shared Database
IL-0456Inflearn went down six times during a January 2022 free-course event as slow queries piled up on Aurora PostgreSQLInflab · 2022same root cause · shared Database
IL-0321GCP snapshots on all Patroni nodes stalled GitLab.com's primary PostgreSQL disk, Patroni failed over and 5xx spikedGitLab · 2021same root cause · shared Database
IL-0496Ably's Cassandra hit 100% CPU in every region and queries timed out globally, and the load returned on two more eveningsAbly · 2020same root cause · shared Database
IL-0443A Repro Aurora MySQL reader restarted unexpectedly and writer insert latency rose about sevenfold for a day or moreRepro · 2019same root cause · shared Database
IL-0037Image registry rate-limited a whole region after a crash-looping DaemonSet with imagePullPolicy Always pulled through three NAT instancesDatadog · 2019same root cause · shared Database
IL-0297Mezmo users could not sign in and log indexing lagged after the auth cache's Redis servers were OOM killedMezmo · 2019same root cause · shared Database
IL-0211A Mandrill PostgreSQL shard shut down at transaction ID wraparound and email sending was impaired for about 40 hoursMailchimp · 2019same root cause · shared Database
IL-0064CPU-heavy pods packed onto one Google Cloud node drove it to kernel panics, and the crash moved from node to node until the site was downMoonlight · 2019same root cause · shared Database
IL-0300Basecamp 3 went read-only for almost five hours when its events table reached the ceiling of 2,147,483,64737signals · 2018same root cause · shared Database
IL-0334Instapaper's RDS MySQL bookmarks table hit the 2TB ext3 file size limit, inserts failed and the service went downInstapaper · 2017same root cause · shared Database
IL-0333A downsized RDS PostgreSQL database maxed out its CPU at US peak and failing ELB health checks took buildkite.com downBuildkite · 2016same root cause · shared Database
IL-0383PagerDuty's shared Cassandra cluster degraded during a repair, delaying notifications and losing incoming eventsPagerDuty · 2014 · sev1same root cause · shared Database
IL-0320Postmark's primary MySQL disk filled but MySQL kept running, so MySQL-MMM never failed over and sending was delayedPostmark · 2011same 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-0282
- The cases most like it: https://incidentlib-api.benchlet.com/cases/IL-0282/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.