Cases4 cases
1 to 4 of 4
- 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.
- Trigger
A regular release deployed a query pattern change to the learning resource APIs that put an aggregation inside the main query.
- Root cause
- Component
- Contributing factor
- 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
- Rolled back the release's query pattern change
- Deleted the read replica so the database could flush its buffered WAL files
- Terminated all active queries running longer than 10 minutes with pg_terminate_backend, after the backup finished and with guidance from AWS Support
- Action items
- Explore enabling enhanced analytics on the production Learn database
- Document rollback steps on the platform engineering documentation site
- Make easy rollback part of the new release management framework
- Alert on DiskQueueDepth for production databases without making the alert too noisy
- Alert when API and site response times are more than 30% above normal
- Run a gameday on an example production database outage
- Adopt Rootly for incident management, with an automatic channel and an automatic incident transcript
- Write an outage runbook: start a call, have the on-call engineer watch metrics until they return to baseline, and give one person the communications
- Put the query that terminates long-running queries, and a version that finds them for selective termination, into a production Postgres runbook
- Open an issue on redesigning the Learn Resource View Event model, which is only used for counts
- Use anonymised production data generation tools to bring RC up to production data volume, on separate infrastructure for load testing
- Change the view count to use a precomputed column
- 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.
IL-0268AdGuard DNS resolvers in Amsterdam, Frankfurt and London overloaded and answered with timeouts and SERVFAILAdGuard DNS2025- Symptoms
Between about 15:30 and 18:00 UTC on 25 November 2025 some AdGuard DNS users saw slow or failed DNS resolution, with timeouts and SERVFAIL responses. Alerts fired for increased DNS error rates and server load, and a significant part of the traffic in several European locations, primarily Amsterdam, Frankfurt and London, had intermittent DNS failures for up to 2.5 hours.
- Trigger
A new version of AdGuard DNS, deployed on 25 November to improve how resolvers cache user data, had a bug that saved only the recently changed subset of user data into the local cache file. The first deployment failed partway on a network issue and left about half the servers on the new version; the second attempt made many resolvers start full synchronizations at once.
- Root cause
- Component
- Contributing factor
- Detection
Alerts for increased DNS error rates and server load fired during the second deployment attempt, between 15:30 and 16:00 UTC.
- Remediation
- Rolled back the buggy version on all servers
- Partially rerouted Amsterdam's traffic to other European locations
- Reduced connection concurrency and request pipeline depth in Frankfurt and London, from 5 to 1 in Frankfurt
- Adjusted limits to the actual hardware capacity
- Repaired corrupted cache files and user data snapshots to stop further full synchronizations
- Normalised the traffic distribution once the rollback was complete
- Action items
- Add automated tests that the full user dataset is correctly written to and restored from the local cache file, including detection of empty or truncated caches
- Add integration tests that simulate resolver startup with an empty or corrupted cache under realistic load
- Standardize server hardware profiles per location, or keep separate configurations per hardware class
- Review and adjust connlimit, cache sizes and connection limits for each standard node type
- Reevaluate and lower pipelining depth where needed
- Reevaluate how connections and goroutines are limited so resource use stays bounded with decent throughput after a connection break
- Monitor Go heap size, GC time, GC cycles per second and per-cluster request latency distributions
- Alert on sustained increases in SERVFAIL rate and request duration while upstreams are healthy
- Refine DNS resolver deployment and rollback procedures to avoid simultaneous cache invalidation across a large part of the fleet
- Document and rehearse playbooks for adjusting pipeline depth, connection limits and connlimit during live incidents
- Lessons
How nodes behaved depended on the interaction between available RAM, Go's garbage collector and the connlimit setting. On 64-GiB nodes a high limit let the heap grow large under heavy concurrency and pipelining, and the garbage collector then spent more and more CPU, a known worst case for high-memory applications in which memory is not exhausted but latency rises and throughput falls. On 32-GiB nodes the same configuration reached practical memory limits sooner because it had not been scaled down. Together with high pipelining and client retries, GC pressure, connection saturation and retries formed a feedback loop.
IL-0591Gitpod workspaces in all regions became IO bound and unresponsive for days after the ws39 workspace cluster releaseGitpod2022- Symptoms
From April 11, 2022 at 13:17 UTC customers and Gitpod staff reported that Gitpod workspaces were intermittently becoming unresponsive. CPU usage of nodes and pods looked normal, with nothing maxed out, and at 13:58 UTC the team found that the workspaces were IO bound rather than CPU bound.
- Trigger
The ws39 generation of workspace clusters, released to all regional clusters on April 8th at 20:08 UTC and to the XL clusters on April 9th at 17:45 UTC, split the 1TB disk into smaller RAID0 disks, changed CPU limiting and workspace networking, and moved to faster machine types.
- Root cause
- Component
- Contributing factor
- Detection
Customers and Gitpod staff reported on April 11th at 13:17 UTC that workspaces were intermittently unresponsive, and the team opened an incident in Slack through its incident.io integration. On April 17th the team noticed increased CPU load on the workspace nodes and opened an internal incident.
- Remediation
- Shifted workspace starts back to the ws38 clusters on April 11th
- Built ws39a clusters with c2d machines and local SSDs and moved traffic to them
- Requested a limit increase from Let's Encrypt
- Routed EU XL traffic to the regional EU cluster and built ws-eu39bxl to replace the crashed ws-eu39xl
- Cleaned up workspaces stuck in a stopping state so users could start them again
- Released ws40 with 1TB boot disks to get more IO bandwidth
- Removed the workspaces that consumed excessive CPU time for crypto-mining
- Blocked the fraudulent users behind the crypto-mining from using Gitpod
- Rolled back the ws-daemon change that broke CPU limiting and shipped the fix in the ws34 clusters
- Blocked ACME HTTP requests to workspace ports so Let's Encrypt rate limits would not be hit again
- Rolled out IO limiting with the ws41xl and ws41 clusters and moved traffic to them step by step
- Action items
- Invest in test automation so that test results stop releases like this one
- Vary the interval between traffic shifts to new clusters, with more time for larger releases
- Add a risk assessment stage, to be automated, that governs changeset size and rollout speed of workspace cluster rollouts
- Reduce the impact teams have on each other
- Add review criteria that find backwards incompatible changes before pull requests are merged, and split such pull requests
- Recommend rollback as the primary means of mitigation in the incident procedures, and look at automating it
- Make the status page show the workspace service as down when it is, and update the playbooks
- Keep incident communication in a single Slack channel and Google Meet
- Put 10% of the engineering staff on the on-call rotation from May 9th and use that time on observability, alerting and stability
- Lessons
Gitpod concluded that it should have committed to rolling back on April 11th instead of building and shipping fixes, which kept customers on degraded workspaces longer than necessary. A large release so soon after the previous one needed a risk assessment and slower traffic shifts, and backwards incompatible changes that block a rollback need to be found before pull requests are merged. Failure-free operations require experience with failure.
IL-0229bunny.net's DNS servers crashed in a loop on a corrupted routing database file and could not fetch a fix from its CDNbunny.net2021- Symptoms
On 22 June 2021, within minutes of an update released at 8:25 AM UTC, bunny.net's global fleet of close to 100 DNS servers kept crashing and restarting, more than 60% of traffic was lost, hundreds of Gbits of throughput disappeared, and over 750,000 websites were affected. After 10 minutes the team realised that the DNS servers were restarting and dying and that nothing could bring them back up in that state.
- Trigger
At 8:25 AM UTC bunny.net released an update meant to reduce the download size of the SmartEdge optimization database, and it uploaded a corrupted file to Edge Storage.
- Root cause
- Component
- Contributing factor
- Detection
About 10 minutes after the release, the team realised that the DNS servers were restarting and dying.
- Remediation
- Deployed by hand an update that disabled the SmartEdge system on the DNS nodes
- Routed all requests through Frankfurt instead of Madrid on a couple of DNS servers
- Migrated the deployment systems and files to a third-party cloud storage service
- Rewired the deployment system and DNS software to the new storage and deployed
- Synced the databases and deployed the newest file sets through the third-party service
- Action items
- Phase out the BinaryPack library as a hot-fix
- Test third-party libraries more extensively
- Migrate the internal APIs to an independent third-party service
- Find how to stop non-critical software from becoming a single point of failure across clusters
- Make the DNS system keep a local copy of all backup data with automatic failure detection
- Lessons
bunny.net had built its systems to rely on each other, including the critical parts of its internal infrastructure, so one corrupted file brought down several layers of redundancy with no way back. A part of the infrastructure treated as non-critical turned out to be a single point of failure for several clusters at once, which canary deployments did not catch. Building infrastructure inside its own ecosystem lets one failure cascade through all of it. In the rush to fix the outage the team made typos and mistakes, and the final deployment came after it calmed down and double-checked everything.
These 4 cases involve CDN and edge network and Container CPU limit. kubegap audits a Kubernetes cluster for gaps like these, read-only, from Claude Code or Codex; its checks cite public reports like the ones in this library.
By root cause1
Faulty deployment4 cases
- Component
- Contributing factor
- Organisation
IL-0510MIT Learn's RDS PostgreSQL ran out of storage after a release and learn.mit.edu returned 503s and 504s for hoursIL-0268AdGuard DNS resolvers in Amsterdam, Frankfurt and London overloaded and answered with timeouts and SERVFAILAdGuard DNS2025IL-0591Gitpod workspaces in all regions became IO bound and unresponsive for days after the ws39 workspace cluster releaseGitpod2022IL-0229bunny.net's DNS servers crashed in a loop on a corrupted routing database file and could not fetch a fix from its CDNbunny.net2021