Cases2 cases
1 to 2 of 2
IL-0313Decagon voice requests stalled for exactly 300 seconds behind self-managed PgBouncer and exhausted the SQLAlchemy poolDecagon2026- Symptoms
During the first production canary of Decagon's move from GCP's managed connection pooler to self-managed PgBouncer, a small number of voice requests stalled mid-conversation and timed out after exactly 300 seconds. Other requests failed much earlier because the SQLAlchemy connection pool was exhausted.
- Trigger
The move from GCP's managed connection pooler to self-managed PgBouncer enabled a different TLS path between PgBouncer and Postgres, which supplied the last of three conditions needed to expose the bug.
- Root cause
- Component
- Contributing factor
- Detection
Sentry errors ("SSL connection has been closed unexpectedly") and SQLAlchemy connection-pool timeouts during the production canary, followed by a comparison of application spans with Postgres query timings.
- Remediation
- Shortened the application name parameter so the ParameterStatus packet stayed below PgBouncer's small-packet parsing threshold
- Action items
- Fix PgBouncer upstream so it checks SSL_pending() before going back to wait on epoll()
- Lessons
Decagon's lesson is that an infrastructure migration does not only change one's own systems but can also expose latent bugs elsewhere in the stack: the move to self-managed PgBouncer supplied the last condition for a long-standing edge case involving SQLAlchemy, PgBouncer, OpenSSL and the PostgreSQL wire protocol.
IL-0241A database shard could not elect a new primary, and the Stripe API failed most requests in two periods on one dayStripe2019- 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
These 2 cases involve Database and Database proxy and connection pooler. 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
Software defect2 cases
- Contributing factor