Incident Library

IL-0270 Discord · 2023-11-06database

Discord's ScyllaDB authentication cluster overloaded during an OS upgrade, and logins failed for about 50 minutes

Discord's scylla-authentication ScyllaDB cluster holds user session data and sits behind the Rust authentication service that validates every API request. Like Discord's other Scylla clusters, it replicates data across three zones of the cloud provider and uses quorum reads so that it can lose one zone, and each node mirrors fast NVMe Local SSDs, which are cleared on reboot, with a slower persistent disk in a RAID array. Syncing that RAID takes about 40 minutes at instance startup before Scylla can start. From 3 November the persistence infrastructure team upgraded the operating system of the Scylla clusters one zone at a time: detach the persistent disks, terminate the instances, start new instances with the upgraded OS, rebuild the RAID, bring Scylla back and wait a set time before the next zone. While a zone is out, the cluster has a third less compute and no room for another failure, and the detached capacity cannot return for at least 45 minutes. More than a hundred nodes had been upgraded this way. Because scylla-authentication had not had a full zonal restart recently, the team first took zone [b] offline for ten minutes as a test, saw no degradation, and started the upgrade at 9:16 AM.

Zone [b] finished at 10:42 AM. One of its two nodes, scylla-authentication-b-2, had rebuilt its RAID much more slowly than the other because one of its NVMe Local SSDs was degraded, which hurt that node's disk I/O. The operator checked the cluster and advanced to the next zone, and at 10:52 AM the script drained zone [c]. The cluster was left with one degraded node and one healthy node in zone [b], both with fairly empty row caches, zone [c] offline and two healthy nodes in zone [d]. Discord had found that for some clusters the ScyllaDB row cache hit rate must reach a certain level before restarting nodes is safe, and the procedure had not checked the hit rate of the restarted zone [b] nodes; the earlier ten-minute test had given false confidence. Discord's write-up names the cluster as underprovisioned. It overloaded, authentication lookups timed out, and application retries made the overload worse.

Discord shed load by turning off typing events and read markers at 11:05 AM, which restored authentication for about half of users. Restarting nodes to clear abandoned queries risked breaking quorum completely, so at 11:35 AM, with the zone [c] RAID rebuild five minutes from done, the team chose to wait. The two zone [c] nodes came back at 11:41 AM, the two zone [b] nodes were restarted one at a time, and by 11:43 AM user activity was back to normal. Right after the incident the cluster was doubled in size, and after some analysis scylla-authentication-b-2 was rebuilt on new disks. The outage affected availability only; the authentication service returned no incorrect results, and no outside actor or unauthorized access was involved.

Severity
–
Scope
Discord authentication: users could not connect, log in, read or send messages; availability fell to about 25%, then about 50% of users could use Discord until 11:43 AM PST
Users affected
Discord users; about 50% could use the service from 11:05 AM until recovery
Region
–
Time to detect
4m
Time to resolve
51m

Symptoms

On 6 November 2023 at 10:52 AM PST, when an upgrade script drained all connections from zone [c] of the scylla-authentication ScyllaDB cluster, Discord's availability, measured as the share of HTTP requests that return a 200-level response, fell at once to about 25%. Users could not connect, log in, read or send messages.

The first alerts fired at 10:56 AM, but an incident call was already running. A graph of time spent by downstream service showed that the Rust authentication service, which checks that every API request comes from an authenticated user, was taking far longer than normal on each request, and the authentication alerts fired moments later. The scylla-authentication cluster was saturated with queries and showed high latency; all four remaining nodes were overwhelmed, with load at 100% on some of their shards. Scylla's logs reported errors connecting to the two zone [b] nodes, scylla-authentication-b-1 and scylla-authentication-b-2.

The application retries requests that get server errors from the authentication endpoints, so once the cluster began timing out, the retries added a retry storm on top of the load. Turning off typing events and read markers at 11:05 AM brought authentication back for about 50% of users, and at 11:10 AM still only about half of users could use Discord.

The timing pointed to the authentication upgrade right away, but the script had already detached zone [c]'s data disks, so bringing that zone back meant about 45 minutes of instance provisioning and RAID rebuild. Restarting nodes to clear long-running queries abandoned by clients was considered, but with zone [c] offline a restart would break quorum, and restarting the wrong node could take the service down completely. A misleading error message in the authentication service sent the investigation on a detour. Earlier that morning, while zone [b] was being upgraded, scylla-authentication-b-2 had rebuilt its RAID array much more slowly than the other node, which the team had treated as a curiosity.

Symptom Service outageDatabase overloadHigh latency

Root cause

Trigger
During an OS upgrade that takes one zone of a ScyllaDB cluster offline at a time, the upgrade script drained all connections from zone [c] of scylla-authentication at 10:52 AM, while one node in the just-upgraded zone [b] had a degraded NVMe Local SSD.

Detection

An incident response call had already started when the first alerts fired at 10:56 AM, four minutes after the start. The time spent by downstream service graph showed the authentication service spending far more time on user requests than normal, and the authentication alerts fired moments later.

Remediation

Action items

Lessons

Taking a whole zone out of a three-zone cluster leaves no margin, so one additional slow node in another zone was enough to overload it. For some Scylla clusters the row cache hit rate of restarted nodes must reach a safe level before the next zone goes down, and a short zonal test beforehand gave false confidence. The small but critical authentication cluster needs to be run differently from Discord's much larger Scylla clusters, with more redundancy.

Sources

Related cases

Check your cluster for this

kubegap audits a Kubernetes cluster for conditions like the ones in this case, Database 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.