Incident Library

IL-0217 Honeycomb · 2023-07-25databaseaws

Honeycomb's main MySQL database locked up under cache-miss reads and ran out of connections, a 68-minute total outage

Honeycomb runs several MySQL databases on RDS. A main database holds user accounts, permissions and data schemas; it holds no customer events, which Retriever stores, but the whole system needs it. A shared schema cache protects this database, and ingest traffic keeps that cache warm through last-written timestamps that Retriever writes to the database. When the shared cache is missing, services can run on their own local memory caches for a good while, as long as the database stays up. The switch to the other Retriever cluster on 24 July stopped these timestamp writes because of a feature flag bug: a host told to stop writing never retried, even when the flag was switched back, and only a full reboot fixed it. Frequent deploys that restarted hosts had hidden this flaw, and deployments had been paused during the investigation.

On 25 July the feature flag flip stopped the remaining writes, cache misses sent a surge of reads to the main database, and a deadlock in MySQL's internals, which Honeycomb thinks is non-deterministic and more likely under load, locked its threads until it ran out of connections. From 1:40 p.m. UTC every user-facing component of Honeycomb was down. Responders set up circuit breakers that denied all Shepherd traffic with a 5xx error to protect the database. The database host was hard locked, so they failed over to a replica, which brought the database and the services that depend on it back. They restarted all Retriever hosts, then marked the last-written timestamp of every schema that had seen traffic in the last day as "now", so the schema store reloaded the whole cache; this left incorrect values in the parts of the UI that show how fresh data is. They removed the circuit breaker, restarted query hosts that failed internal checks after the database faults, and Honeycomb was healthy again at 2:48 p.m. UTC.

No new data could be ingested during the outage, and data that users or customers had not buffered for replay was lost for good; the gap stays visible for as long as the data is kept.

Severity
–
Scope
Total Honeycomb outage of all user-facing components from 1:40 p.m. to 2:48 p.m. UTC: no data could be ingested, processed or accessed, alerting and querying were affected, and data not buffered by senders was lost
Users affected
all Honeycomb users
Region
–
Time to detect
–
Time to resolve
1h 8m

Symptoms

Hours after a routine switch between two clusters of Retriever, Honeycomb's storage and query engine, late on 24 July 2023, the internal SLO for Shepherd, the ingest service, began to burn slowly. The performance was only marginally slow and inconsistent, with no good explanation, so engineers treated it as minor and left it for the morning.

In the morning a chart showed that Retriever's database calls had suddenly stopped. These calls update the records of the last time data arrived for each field or dataset, and the caching mechanism uses those records to decide which dataset schemas to refresh and keep warm for ingest. Without them the ingest cache was undermined. Assuming the new cluster's writes were broken, engineers flipped only the writes back to the other cluster with a feature flag they had used often, but this did not help: because of a bug, a host told to stop writing never tried again, even after the flag was switched back, and only a full reboot moved its writes, so the flip stopped the last writes that were still keeping the system alive.

At 1:40 p.m. UTC on 25 July, just before a command to restart the query engine cluster was ready, the main MySQL database on RDS seized up. With the cache mostly not working, reads on the database had shot up and overloaded it, and a few ordinary writes then seemed to trigger a rare race condition in MySQL's internals that locked thread after thread until operations piled up. The database ran out of connections, services that could not get the data they needed died, and every user-facing component of Honeycomb went down, with no data processed or accessed.

The database host was hard locked: any interaction with a stuck thread waited on the same lock, so it could not be saved in place. Bringing ingest back without a warm cache would have overloaded the database or saturated its connections again. Earlier read-replica failovers had performed poorly, so the team expected a failover of the primary to be costly.

Symptom High latencyDatabase overloadLock contention or deadlockService outage

Root cause

Trigger
Late on 24 July Honeycomb switched between two Retriever clusters to avoid a subtle bug, and the new cluster stopped writing the last-written timestamps the schema cache depends on. On the morning of 25 July a feature flag flip meant to move those writes back stopped the remaining writes entirely.

Detection

Hours after the cluster switch, the internal SLO for the ingest service Shepherd started burning slowly. Engineers left it for the morning, when a chart showed that Retriever's database calls updating the last-written records had stopped.

Remediation

Action items

Lessons

Locally good decisions combined into the outage: the query engine wrote the timestamps because it already saw all the data, the shared cache helped scale ingest and untangle the main database, the cluster switch was done to avoid a bug, frequent deploys hid the feature flag bug, pausing deploys during the investigation kept hosts from restarting, and past near-misses made the team expect a slow failover. Feature flags, frequent deploys, pausing deploys during incidents and learning from near-misses all contributed, although they are among the practices Honeycomb trusts most. For a rare lockup of this kind a database failover is the fastest recovery. Several recent Honeycomb incidents started from trying to avoid a subtle bug.

Sources

Related cases

Check your cluster for this

kubegap audits a Kubernetes cluster for conditions like the ones in this case, Database, In-memory cache among them, read-only, from Claude Code or Codex. Its checks cite public reports like this one.

For AI tools and scripts

The API needs no key. The MCP server offers search_incidents, get_incident, list_incidents, get_topic and vocab; both are explained on API and MCP.