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

Cases4 cases

1 to 4 of 4

  1. Symptoms

    From about 6:00 on the last business day of a month, Cloud Pub/Sub messages of the Merpay accounting event pipeline began to back up, new accounting data stopped being registered in Cloud Spanner, and the accounting system intermittently could not accept new data. The backlog grew to about 10 million messages.

    Trigger

    More than a month earlier the Cloud Functions of the pipeline had been moved from 1st gen to 2nd gen (based on Cloud Run) without setting --max-instances in the deploy command, which lowered the scale limit from effectively unlimited, the 1st gen default, to 100, the 2nd gen default. The month-end peak, which on that day continued for about 40 minutes, reached that limit.

    Root cause
    Component
    Contributing factor
    Remediation
    • Re-ingested the messages saved to GCS by the Dataflow subscription, avoiding data loss
    Action items
    • Set max-instances and the other scaling parameters of Cloud Run explicitly in the deploy definition, raising max-instances from 100 to 1000 in steps
    • Set min-instances to 1 to avoid cold starts, raise concurrency from 1 to 10, and set CPU to 1 and memory from 512MB to 1Gi
    • Use the dual CPU scaling mode of spanner-autoscaler v0.8.0 with a new Total CPU threshold of 70%
    • Lower the High priority CPU threshold from 60% to 55% so scale-up starts earlier
    • Forbid Spanner scale-down between 5:00 and 7:00
    • Reserve Spanner processing units on a schedule for periods with predictable load
    • Alert in Datadog when the Cloud Run instance count reaches 40% and 60% of its limit
    • Alert in Datadog when undelivered Pub/Sub messages exceed a threshold, lowering it step by step
    Lessons

    When moving to a new generation of a managed service, defaults that the team never changed can surface as problems under load, so parameters that only matter at peak, such as scale limits, concurrency and timeouts, should be set explicitly at every migration. An outage rarely has one cause; the fact that the previous month passed under the same conditions pointed to traffic continuity, and prevention needs to look at the trigger, the amplification and what turned it into damage. Capacity settings and the monitoring that shows when they are approached have to be designed together, and teams that run systems they inherited should review these settings and assumptions regularly.

  2. Symptoms

    On the event day of a global game, with close to 1000 rps per MySQL instance even after sharding and replication, a master instance stopped because of a host failure. MHA failed over automatically as usual and the service kept running, but one of the three replicas hit a replication error and could no longer follow the latest data.

    Trigger

    Under heavy load on a game event day, a MySQL master instance stopped because of a host failure, and MHA started an automatic failover.

    Root cause
    Component
    Contributing factor
    Remediation
    • Removed the replica that could not apply data from service
    Lessons

    MHA had not followed a mysqlbinlog change in MySQL 5.7.9, so under specific conditions bringing replicas up to date during failover failed. Running MySQL at large scale means meeting rare events like this, which only show when a master stops suddenly under load.

  3. Symptoms

    At 9:47 AM Eastern (14:47 UTC) on 7 February 2023, Daily's database alerts reported a performance problem under normal operational load: a high level of lock contention on a database that had been upgraded the weekend before and had run normally since Monday. Users could get websocket connection errors when joining calls, and REST API requests could time out or return 5xx errors.

    Trigger

    Database maintenance the weekend before had upgraded the database to a MySQL point release with a low-level behaviour change, and on 7 February, under normal load, that change produced the deadlocks Daily saw on Aurora MySQL 2.11.0.

    Root cause
    Component
    Contributing factor
    Detection

    Database alerts at 9:47 AM Eastern reported a performance issue with high lock contention on the newly upgraded database.

    Remediation
    • Disabled MySQL binlog replication to the old database and restarted the database to reduce load
    • The database restarted by itself at 10:47 AM, the SFUs dropped the stale meeting updates without restarting, and the platform recovered
    • Rate-limited the POST /rooms endpoint to the same limit as DELETE /rooms/:name
    • Updated an index on the affected table in production on the Saturday evening to work around the MySQL behaviour change
    Action items
    • Work with AWS so the Aurora MySQL 2.11.0 deadlock issue is documented, understood and fixed in a future release
    • Add more API request patterns to the testing workload used for infrastructure changes
    • Add production monitoring alarms on more fine-grained database metrics
    Lessons

    Daily tests infrastructure changes under production-like workloads, but its synthetic workload did not have the shape that triggers these deadlocks. A deadlock behaviour change in MySQL 5.7 that was already known turned out far more severe in production than either Daily or the AWS Aurora team expected.

  4. Symptoms

    From 13:30 UTC on 21 May 2021, CircleCI jobs on Docker, the Machine executor (including Windows, Mac, Arm and GPU) and remote Docker were delayed or blocked. Engineers had been paged at 13:00 for excessive delays in starting jobs, and the alerts showed CircleCI could not provision some types and classes of VM because it was hitting its CPU quotas in GCP.

    Trigger

    The upgrade of the RabbitMQ cluster from 3.8.9 to 3.8.16 on 20 May 2021, which brought in a 15 minute consumer acknowledgement timeout for all queue types.

    Root cause
    Component
    Contributing factor
    Detection

    Engineers were paged at 13:00 UTC on 21 May for excessive delays in starting jobs. Earlier, a 02:31 notification that a VM destroyer queue had no consumers was handled by restarting pods, and a 10:11 alert that a VM destroy queue was backing up notified once at its threshold and did not page.

    Remediation
    • Blocked Linux machine jobs from entering the work queue
    • Had GCP raise the CPU quotas
    • Deleted old VMs by hand
    • Cancelled some workflows to free resources
    • Reset the VM services deployment so the VM destroy queues had consumers again
    • Scaled up the RDS database instance, at 18:20 and again at 19:15
    • Turned down VM provisioning and blocked remote-docker jobs to shed load
    • Scaled down all pods that created and destroyed VMs
    • Deployed a revised distribution backend that kept remote-docker jobs out of the provisioning queues
    • Brought provisioning and distribution back one component at a time and reversed the mitigation code changes
    Action items
    • Make VM provisioning more robust to changes in load so it can recover from thundering herds
    • Make VM provisioning independent so its failure does not affect Docker jobs
    • Review and improve observability of RabbitMQ and the production queues
    • Batch requests to avoid hitting GCP API rate limits
    • Improve incident response for long-running incidents
Check your cluster for this

These 4 cases involve Database and Message broker. 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