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

Cases6 cases

1 to 5 of 6

  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

    From 11 November 2025 at 16:02 UTC, PostHog's event ingestion pipeline for US Cloud became severely degraded, and events for all customers in the US region were processed with delays from 10 minutes up to 2 days. Writes to the Postgres database that stores Person information could take multiple seconds per update, and the pipeline slowed until no standard scaling option helped.

    Trigger

    The 32-bit OID space used to track TOASTed values of the Persons table's properties column, a JSONb field that often exceeds the 2KB threshold for out-of-line storage, was nearly exhausted.

    Root cause
    Component
    Contributing factor
    Remediation
    • Created a new partitioned Persons table with a fresh TOAST table and OID space
    • Added database triggers to keep the old and new Persons tables in sync for live writes
    • Copied the existing Person data from the old table to the new one with a backfill script
    • Changed ingestion and application code to write to the new table and read from it first, with fallback to the old table
    • Deployed the web app changes to production under manual control rather than a fully automated rollout
    • Scaled ingestion workers to process the accumulated backlog
    • Paused ingestion when the MSK local disk reached about 85%
    • Reduced the local retention of the affected Kafka topic
    • Resumed ingestion after confirming there was enough disk headroom
    • Moved the backfill into Dagster to finish it over the weekend
    Action items
    • Add metrics and alerts for heavy disk read amplification per write
    • Add metrics and alerts for TOAST table statistics
    • Add metrics and alerts for other Postgres engine limits that matter at large scale
    • Write runbooks for engine-level Postgres limits, with decision trees for migrating versus repairing in place
    • Create customer communication runbooks with a clear escalation path and redundancies
    • Evaluate other data stores for the persons database
    • Complete the reconsolidation on the new Persons tables
    • Improve the backfill tooling and the safeguards for Kafka tiered storage
    • Design and operate Person-like tables so they avoid similar limits
    Lessons

    TOAST OID exhaustion degrades writes long before the hard limit of about 4 billion OIDs, it is rare even at large scale, and standard dashboards for CPU, memory, IOPS and lock contention did not immediately point at it, so diagnosis took a day and a half without monitoring of TOAST growth, OID usage or disk reads per write. Many core features depended on timely updates to the persons table, so its slowdown reached a wide part of the product. The first backfill approach lacked visibility for a long migration, the Kafka tiered storage settings and alerts were not tuned for a large backlog, and the people who normally handle customer communications were all unavailable.

  3. Symptoms

    When a Kafka cluster of PagerDuty's US Service Regions began failing at 03:53 UTC on 28 August 2025, the first alerts pointed to one failing broker. More brokers then ran out of memory, and PagerDuty's event APIs began rejecting incoming events with a response status code of 502 while notifications, webhooks, chat integrations and the REST API degraded.

    Trigger

    A new feature that recorded API key usage in a Kafka topic was being rolled out by configuration: 1% on 21 August, 5% and then 25% on 27 August, and 75% on 28 August. A logical error in the feature created a new Kafka producer for every API request instead of reusing one producer.

    Root cause
    Component
    Contributing factor
    Detection

    Alerts pointed to one failing Kafka broker at the start of the first incident, and alerts fired again at 16:38 UTC when Kafka performance degraded for the second time. Critical alerts about core API errors were buried among webhook pages.

    Remediation
    • Expanded the Kafka cluster and removed the first failing broker
    • Doubled the Kafka broker heap size and applied it with a rolling restart across the cluster
    • Added status page updates by hand through backup procedures when automated publishing failed
    • Recovered Kafka-dependent services, some by manual intervention, and backfilled lost data with scripts
    • In the second incident, doubled the heap again with another rolling restart
    • Rolled back the API usage feature with a pull request that stopped it from publishing Kafka messages
    Action items
    • Remove the dependency that blocked status page automation and simplify and republish the manual runbook
    • Run live drills regularly so status updates go out even when parts of the platform are degraded
    • Expand JVM and Kafka monitoring of heap, garbage collection and producer and consumer health
    • Strengthen service dependency mapping so cascading failures are easier to trace
    • Collect customer impact metrics into incident workflows automatically
    • Add stricter change management guardrails, with readiness checklists and slower ramp-up windows for major rollouts
    • Improve recovery mechanisms in the streaming systems
    • Automate communication workflows such as status page updates, internal and external syncs and reminders
    • Test major incident workflows monthly with chaos engineering, such as status page failover
    • Define clearer incident severity levels and roles, including dedicated communications liaisons
    Lessons

    PagerDuty found its message processing more intricate than it had thought: some services had to be restarted to pick up changes, some API activity produced far more messages than expected, and it was hard to tell which parts of the system put heavy load on Kafka. Because producers and JVM heap were barely observed, responders could not see the first failure until several downstream systems were affected, and no one on the call held a model of the whole system. Enabling the feature through configuration rather than a separate deployment was meant as a safety step but made the outage harder to link to the change. Runbooks and backfill scripts were imperfect but gave responders a head start, and the second incident was mitigated in about 50 minutes by repeating the first incident's steps.

  4. Symptoms

    On 2 August 2024, two minutes after Clever Cloud's data team started a minor rolling upgrade of its Apache Pulsar messaging cluster to release 3.3.1, monitoring showed connection problems with the messaging platform. Producing data into the event bus failed, the backlog grew while no new producers or consumers succeeded, and agents on hypervisors, log forwarders on load balancers and deployments were affected. At 10:20 CEST the Pulsar cluster was declared defective.

    Trigger

    At 10:06 CEST the data team began a minor rolling upgrade of Apache Pulsar to release 3.3.1 that also switched on a new balancer for bundle placement: the extensible load manager (loadManagerClassName=org.apache.pulsar.broker.loadbalance.extensions.ExtensibleLoadManagerImpl) with the TransferShedder load shedding strategy instead of the native OverloadShedder.

    Root cause
    Component
    Contributing factor
    Detection

    Monitoring showed connection issues to the messaging platform at 10:08 CEST, two minutes after the upgrade began, and engineers confirmed at 10:09 that producing data into the event bus failed. Monitoring did not catch the first broker's failure to create the system topic, because that broker stayed up.

    Remediation
    • Rolled back the new unload strategy while keeping Pulsar 3.3.1
    • Shut down the client proxies to release the brokers
    • Switched deployment notification events to RabbitMQ as a workaround
    • Stopped all brokers and started only one, which loaded the conflicting system topic so it could be deleted, then started all brokers
    • Restarted the messaging proxies, after which messages flowed again
    • Stopped the watchdog so it would not reload every failed component, and started components one by one
    • Disabled Metrics API ingestion to protect its storage cluster
    • Stopped the long-term storage for observability metrics (the Warp10/FoundationDB cluster) to free resources
    • Put all monitoring instances in all regions into maintenance so they stopped sending events to the orchestrator
    • Killed the overloaded small VMs one by one
    • Flagged 12 hypervisors to drain workload and shut down some load balancers to free CPU and memory
    • Cleaned zombie VMs to speed up recovery
    • Cleared the monitoring alert queue so queued events would not flood the orchestrator
    • Added parked hypervisors to EU-FR-1 to relieve the overloaded ones
    • Removed an overloaded RabbitMQ node from the cluster used by the orchestrator
    • Rolling-restarted every regional L7 load balancer and every L4 load balancer
    • Restarted all HV agents and the add-on provider APIs
    • Destroyed all dangling VMs stuck in the stopping state
    • Re-enabled Metrics API ingestion with a ramp-up QoS policy
    Action items
    • Track KPIs for Pulsar broker and cluster health, hypervisor load, I/O and kernel panic reboots, zombie VMs, RabbitMQ broker and cluster health and deployment queue consumption, each by time of event, detection, decision and resolution
    • Deal with too many monitoring alerts
    • Look at a backup bastion, because a regional bastion is vulnerable
    • Rework the control plane recovery process
    • Rework the correlation between monitoring and orchestration
    • Revisit fault domain separation against multi-tenancy
    • Rethink runtime images and the role of the hypervisor
    • Isolate waved release upgrades of Pulsar
    • Redesign runtime images with better hypervisor integration
    • Regionalise observability for redundancy
    • Set Vector's buffer.max_events and buffer.max_size for small VMs
    • Switch Vector's buffer.type from memory, the default, to disk
    • Change Vector's buffer.when_full from block, the default, to drop_newest
    • Tune journald verbosity and SystemMaxUse on small VMs
    • Add cgroups restrictions for better process control
    • Add I/O restrictions for the VM manager
    • Detect zombie VMs better
    Lessons

    The simulation process that validates non-minor releases was not applied to minor upgrades or to small configuration changes, and this one went straight to production. Running Clever Cloud on Clever Cloud turned into a chicken-and-egg situation: recovery needed the scheduler to carry out large actions while the control plane was itself slowed and the infrastructure had no free resources. Measuring each key indicator by time of event, detection, decision and resolution showed where the team had lacked visibility or reaction and challenged established rules.

  5. Symptoms

    On May 31, 2018 from 21:53 UTC the metrics APIs of AppOptics and Librato returned a 5xx for a majority of incoming metric data. APM metrics and traces sent from AppOptics APM were affected, and many alert notifications were delayed.

    Trigger

    A power event in one of AWS's availability zones in us-east-1 cut off nodes in several critical parts of the AppOptics and Librato infrastructure, including the ZooKeeper node that was then the leader of the ensemble coordinating the Kafka brokers.

    Root cause
    Component
    Contributing factor
    Remediation
    • Restarted one ZooKeeper node by hand to force a leader election, after which the ensemble regained quorum
    • Restarted every Kafka broker in a rolling restart until all partitions were back online
    • Worked through the backlog, including the backlog of alerts, and resumed normal operations
    Action items
    • Isolate the Kafka clusters better across availability zones and regions
    • Stop sharing one ZooKeeper ensemble across Kafka clusters
    • Run game days on this failure and check whether newer Kafka versions fix it
    • Put in place more checks that notify the team earlier about subsystems that need extra help to recover
    Lessons

    Running services across several availability zones and more than one Kafka cluster did not isolate the pipeline from the failure of one zone, because partitions of different clusters sat in the same zones and the clusters shared one ZooKeeper ensemble. More operational monitoring of the subsystems that needed help to recover would have led to a faster recovery.

Check your cluster for this

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

Breaking change in an upgrade1 case

Organisation
  1. IL-0572 About 10 million Pub/Sub messages backed up and Merpay accounting data was not written to Cloud Spanner for over a day

Capacity exhaustion2 cases

Organisation
  1. IL-0390 PostHog US Cloud event ingestion slowed to delays of up to 2 days as writes to the Persons Postgres table stalled
  2. IL-0275 Parse.ly's Kafka brokers hit network limits and failed one after another, stopping the analytics pipeline for hours

Faulty deployment1 case

Organisation
  1. IL-0214 PagerDuty's Kafka brokers ran out of JVM heap one after another, and the event APIs rejected events with 502 responses

Configuration change1 case

Organisation
  1. IL-0285 Clever Cloud's Pulsar brokers stalled in a minor upgrade, then hypervisors overloaded and crashed with kernel panics

Cloud provider outage1 case

Organisation
  1. IL-0588 AppOptics metrics APIs returned 5xx as Kafka partitions stayed leaderless after an AWS power event hit their ZooKeeper