Incident Library
Applied filters SymptomSustained high node CPUFactorChange with a delayed effectClear allEvery case under the filters, with no sentence; newest first.
Suggested filters Search, and the values found in your words appear here.

Graph

  • Root cause
  • Component
  • Symptom
  • Contributing factor
  • Case

Cases3 cases

1 to 3 of 3

  1. Symptoms

    On the afternoon of 28 October 2021 (13:37 PST), Vault performance at Roblox degraded and a single Consul server showed high CPU load. Consul cluster metrics showed that writes to its key-value (KV) store had a 50th percentile latency of 2 seconds instead of the usual under 300 ms. Players were not yet affected.

    Trigger

    On 27 October at 14:00, one day before the outage, Roblox enabled the Consul streaming feature on the backend service responsible for traffic routing and, to prepare for end-of-year traffic, added 50% more nodes to traffic routing.

    Root cause
    Component
    Contributing factor
    Detection

    Roblox engineers began investigating when Vault performance degraded and a single Consul server had high CPU load, before players were affected. Consul cluster metrics then showed elevated KV write latency.

    Remediation
    • Replaced one Consul cluster node on the suspicion of degraded hardware
    • Replaced all Consul nodes with 128-core machines with faster NVMe SSDs
    • Shut down the Consul cluster and reset its state from a snapshot taken at the start of the outage, with access blocked by iptables
    • Blocked external traffic, disabled all non-essential Consul use, scaled services down and lowered health check frequency from 60 seconds to 10 minutes
    • Moved the Consul cluster back to 64-core servers
    • Disabled the streaming feature for all Consul systems, which brought KV write latency back to 300ms
    • Kept the slow Consul servers from staying elected as leader
    • Redeployed the caching system and fixed its wrong scheduling data and failed deployments
    • Restarted the stopped services at the right capacity levels
    • Let players back in with DNS steering in roughly 10% steps while checking database load, cache performance and stability
    Action items
    • HashiCorp builds laboratory benchmarks and scale tests that reproduce the streaming contention
    • HashiCorp improves the design of streaming so it does not contend under extreme load
    • Compact the BoltDB database with existing BoltDB tooling
    • Remove the circular dependency between the telemetry systems and Consul
    • Extend telemetry with targeted alerts on Consul and BoltDB performance and with visibility into traffic between services and Consul
    • Run the backend in an additional, geographically distinct data center and in multiple availability zones
    • Split critical services into their own dedicated Consul clusters
    • Move data that core services keep directly in the Consul KV store to a more suitable storage system
    • Delete obsolete KV data from Consul
    • Upgrade to a Consul version that replaces BoltDB with bbolt, in Q1
    • Redesign cache deployment so the cache system can be brought up quickly from a standing start
    • Deploy Nomad enhancements that make it easier to turn up large jobs after a long period of unavailability
    • Use mechanisms for faster machine configuration changes
    • Reintroduce streaming only after a new implementation has been tested at Roblox's scale and workload
    Lessons

    Two mostly unrelated problems deep inside Consul, contention in streaming under very high read and write load and BoltDB freelist growth, were hard to diagnose, and that difficulty was the main reason the outage lasted so long. A single Consul cluster serving every workload made the impact larger, and monitoring that depended on Consul hid the cause when it was needed most. Faster hardware did not help and may have hurt, because the contention was worse on NUMA machines. HashiCorp had benchmarked streaming at a similar scale, but the problem needed both a large number of streams and a high churn rate. Restarting a platform from a fully stopped state, including warming caches, took a long time and needed tools built for bootstrapping rather than incremental change.

  2. Symptoms

    Two or three days after Enigmo created EKS managed node groups and moved its pods there from the old node groups, the cluster suddenly became unstable: pods restarted again and again or could not stop and stayed around indefinitely, node CPU and memory load rose high, and the nodes became unusable from the cluster.

    Trigger

    Enigmo created EKS managed node groups that used an AMI containing the bug and moved its pods onto them, as preparation for upgrading EKS from 1.15 to 1.16.

    Root cause
    Component
    Contributing factor
    Remediation
    • Changed the managed node groups' AMI version to the fixed release
    • Ran the managed node group update through CloudFormation
    • Watched the pods across all namespaces during the update
    • Force-deleted every pod that stayed in Terminating with kubectl delete --grace-period=0 --force
    Action items
    • Check the latest releases of the cluster's modules quarterly or monthly and upgrade them regularly
    Lessons

    As long as a team uses Amazon EKS or Kubernetes, it has to keep track of upgrades of the cluster and of modules such as ingress controllers, because a release with breaking changes can be announced without warning after a long stable period. Checking releases and upgrading on a regular schedule keeps the effect of each upgrade on the service small.

  3. Symptoms

    On 10 July 2019 the Stripe API failed a substantial majority of requests twice, from 16:35 to 17:02 UTC and from 21:14 to 22:47 UTC. In the first period automated monitoring detected within a minute that a database cluster had failed to elect a new primary.

    Trigger

    The primary node of a database cluster failed at 16:35 UTC while one shard had several stalled nodes. The second period was set off by rolling the election protocol back to the previous minor version at 20:42 UTC.

    Root cause
    Component
    Contributing factor
    Detection

    Automated monitoring detected the failed election within a minute, and the team was alerted at 16:36 UTC. The second period was announced at 21:14 UTC by automated alerts that some shards in the cluster were unavailable.

    Remediation
    • Restarted all nodes of the database cluster, which forced a successful primary election
    • Updated the production configuration and restarted the database cluster's nodes
    • Ramped traffic back up, putting services for user-initiated API requests first
    Action items
    • Alert when nodes stop reporting their replication lag
    • Alert when a shard enters a state that could trigger the election fault
    • Work with the database maintainers on a fix for the underlying fault
    • Add circuit breaking on failed operations to particular database clusters
    • Use fault isolation to contain the impact of a single failed shard
    • Limit the resources used by clients that keep retrying failed requests
    • Add procedures and tooling that make rapid configuration changes during incident response safer
Check your cluster for this

These 3 cases involve In-memory cache and Coordination and key-value store. 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 cause2