Graph
Cases5 cases
1 to 5 of 5
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 queriesPostHog2025- Symptoms
On 21 October 2025 at 21:45 UTC a change to timeout handling was deployed to the feature flags service, and two minutes later automated monitoring reported higher error rates. The change was rolled back by 21:49, but error rates stayed high: about 38% of flag evaluation requests in the US datacenter returned errors. At 22:30 Redis metrics showed memory exhaustion on ElastiCache, at 22:35 Postgres connections spiked, and at 22:45 the team found a massive data transfer from Postgres into Redis. The main PostHog application was affected as well, because it shares the Redis instance with the flags service.
- Trigger
On 21 October a deployment meant to reduce timeout errors (PR #39821); on 24 October the deployment of IP-based rate limiting (PR #40074) that saw all traffic as coming from the load balancer's IP; on 28 October an unrelated routine deployment that rolled the feature flag pods in the US region.
- Root cause
- Component
- Contributing factor
- Detection
On 21 October automated monitoring detected higher error rates two minutes after the deploy. On 24 October no alert existed for 429 errors, and the team learned of the incident from customer reports that began at 18:10 UTC, a 62-minute detection delay. On 28 October on-call received a high error count alert. On 29 October the incident was reported with higher error rates and latency. No alert existed for CPU pressure, so the CPU saturation behind all three incidents was not seen directly.
- Remediation
- rolled back the timeout handling change within 2 minutes on 21 October, which did not stop the errors
- throttled connections and Redis writes on 21 October
- halted the rollout on 28 October, scaled the US flags pods to zero until Redis recovered, then scaled them back gradually
- rolled back hardware changes on 30 October at 00:03 UTC, which removed most errors but not the latency
- increased the pod resource requests and adjusted the Kubernetes fleet size so fewer pods ran on each node
- added retry limits to Envoy between the load balancer and the service
- moved database connection timeouts and other critical settings to runtime configuration and raised the timeout values
- added per-node and per-pod CPU alerts at 80% sustained for 5 minutes that page on-call
- Action items
- Form a strike team from the flags, ingestion and infrastructure teams to review the application and infrastructure for remaining bottlenecks
- Investigate separating the flags Redis instance from the application Redis instance
- Before re-enabling ArgoCD sync, align the flags service chart configuration with the values in ArgoCD and define the deployment and Redis strategy
- Make the feature flags team hard code-owners for flags-related code
- Build a dashboard of key flag metrics with runbook links and update the feature flag runbooks
- Add missing alerts on existing service and infrastructure metrics
- Make readiness checks validate dependencies that degrade under load, for example by pinging the database
- Rate-limit cache population so it cannot overwhelm Redis
- Monitor connection pools with automatic throttling near exhaustion and limit concurrent connections
- Build a production-scale load testing framework
- Build progressive rollout infrastructure to limit blast radius
- Document Postgres-to-Redis data flows and write runbooks for data transfer storms
- Lessons
Nodes that are small relative to pod requests let the scheduler pack many pods on each node, and the resulting CPU saturation showed up three different ways: excessive parallelism, connection pool exhaustion and slow queries. Treating each symptom separately let the problem return; right-sizing the pods and nodes fixed all three. CPU must be alerted on from the start. Unbounded Envoy retries and unbounded cache population amplified the overload, and a Redis instance shared with the main application spread a flags problem to the main application. A rollback did not end the incident, because the data transfer and resource exhaustion it had started kept running.
- Symptoms
Kibana stopped showing new application logs at 13:45. At 14:27 a user told the Cloud Platform team in the #ask-cloud-platform channel that Kibana had received no logs since then.
- Trigger
OpenSearch ran out of disk space and index writes were blocked.
- Root cause
- Component
- Contributing factor
- Detection
A user reported in #ask-cloud-platform at 14:27 that Kibana had received no logs since 13:45. The report records 12:10, when the ClusterIndexWritesBlocked alert first fired, as the first detection.
- Remediation
- restarted all fluent-bit containers (logs flowed for a few minutes, then the error came back)
- increased OpenSearch disk space from 8000 to 12000
- configured fluent-bit to stop sending logs to OpenSearch while the root cause was investigated
- Action items
- Look into index dating issues in OpenSearch and Elasticsearch
- Add high-priority alerts for Elasticsearch and OpenSearch
- Re-introduce OpenSearch into live logging
- Investigate the fluent-bit "failed to flush chunk" error
- Symptoms
At 09:14 on 4 August 2023, users of the Cloud Platform reported in the #ask-cloud-platform Slack channel that Kibana was missing their application logs for long periods.
- Trigger
The newer Fluent Bit version in use had changed its chunk drop strategy; the fix that followed handled memory buffer overflow.
- Root cause
- Component
- Contributing factor
- Detection
Users reported long periods of missing logs in Kibana in the #ask-cloud-platform Slack channel at 09:14; the incident was declared at 10:09.
- Remediation
- configured Fluent Bit to handle memory buffer overflow by writing buffered logs to the file system
- made Fluent Bit flush logs in smaller chunks
- Action items
- Push notifications from the logging clusters to #lower-priority-alerts (#4704)
- Add an integration test that checks logs are being sent to the logging cluster
- Symptoms
At 14:05 on 25 July 2023, a high-priority PagerDuty alert from Pingdom reported that the "Prometheus - live healthcheck" was DOWN. Prometheus on the live cluster was unavailable, and the Cloud Platform lost its monitoring for a while.
- Trigger
The growing number of namespaces and Prometheus rules raised Prometheus' memory needs beyond what its node instance size could hold.
- Root cause
- Component
- Contributing factor
- Detection
A Pingdom health check on Prometheus failed and raised a high-priority PagerDuty alert.
- Remediation
- drained the monitoring node, moving Prometheus to another monitoring node
- changed the node instance size to r6i.4xlarge
- raised the Prometheus memory limit to 100Gi
- set the Prometheus container limits to 12 CPU cores and 110Gi of memory
- Action items
- Add an alert on node memory usage and on a pod using up most of a node's memory (issue #4538)
IL-0013The conntrack table filled up on downsized GKE nodes and a high-traffic aggregation proxy saw climbing connection resetsloveholidays2020- Symptoms
Shortly after a round of changes, loveholidays saw connectivity problems and raised error rates on its aggregation service. The service is a proxy between two other services of more than 100 instances each, handles over 10,000 requests per second continuously and can spike to four times that.
- Trigger
Three changes together: a change in service architecture, halving the RAM of the nodes that run the aggregation service, and sharding a downstream service, which doubled the number of connections to track.
- Root cause
- Component
- Contributing factor
- Detection
Rising error rates and climbing connection reset errors in HAProxy, then node_exporter conntrack metrics compared with their limit.
- Remediation
- moved the aggregation service to nodes with more RAM
- limited the number of aggregation service pods per node
- Action items
- Alert when conntrack table use goes above 75%, with (node_nf_conntrack_entries / on (pod) node_nf_conntrack_entries_limit / on (pod) group_right kube_pod_info) > 0.75
- Lessons
The conntrack limit is tied to node memory, so resizing a node pool silently resizes the connection table, and on GKE the ratio did not match the commonly cited formula. A high-traffic proxy on small nodes can exhaust it, and the symptoms are connection resets and timeouts, so conntrack use needs its own metric and alert.
These 5 cases involve Node pool and Telemetry agent. 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
Capacity exhaustion5 cases
- Component
- Contributing factor
- Organisation
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 queriesPostHog2025IL-0042Application logs stopped reaching Elasticsearch and OpenSearch for hours and were lost when OpenSearch ran out of disk spaceIL-0043Application logs missing in Kibana after a newer Fluent Bit version changed its chunk drop strategyIL-0016Prometheus on the live cluster ran out of memory and was OOMKilled, and the monitoring node it ran on went NotReadyIL-0013The conntrack table filled up on downsized GKE nodes and a high-traffic aggregation proxy saw climbing connection resetsloveholidays2020