How Discord handles trillions of messages with Elixir, Python and Rust
Discord is where millions of communities talk by text, voice and video. Its stack pairs Elixir for real-time connections with a Python API monolith, and over the years it has moved hot paths to Rust and storage from MongoDB to Cassandra to ScyllaDB.
Indexes messages for search across 40 clusters grouped into cells.
How they built it
Elixir from the first prototype
Discord's first prototype was written in Elixir, and that code became the base of its real-time infrastructure. Each user connects over WebSockets to a session process, which talks to guild processes on remote Erlang nodes that fan events out to everyone online.
The team chose Elixir to get the power of the Erlang VM with a more modern, friendlier language and toolset. To keep scaling, they built their own libraries and later brought in Rust through native functions.
Messages started in MongoDB and moved to Cassandra for scalability and low maintenance. By 2022 the Cassandra cluster had 177 nodes, frequent on-call pages, hot partitions and garbage collection pauses that caused latency spikes.
In May 2022 Discord moved its messages to ScyllaDB, the last of its databases to make the switch, and went down to 72 nodes. ScyllaDB is Cassandra-compatible and written in C++, with no garbage collector. In between, they added Rust data services that coalesce identical requests so a busy channel triggers one database query instead of thousands.
The Read States service, which tracks what each user has read, was written in Go. Every two minutes or so it hit latency spikes, caused by the garbage collector scanning a huge in-memory cache.
In 2019 Discord ported it to Rust, which frees memory as soon as it is no longer used. The Rust version had no spikes and beat Go on latency, CPU and memory. Rust also runs in the game SDK, Go Live video encoding and several backend services.
Search ran on two huge Elasticsearch clusters fed by a Redis queue. Under backlog Redis hit CPU limits and dropped messages, one bad node could fail whole batches, and some large servers hit Lucene's limit of about 2 billion documents per index.
The 2025 rebuild swapped Redis for Google Cloud Pub/Sub for guaranteed delivery, added a Rust message router, and split search into 40 smaller clusters managed on Kubernetes. Median query latency dropped from 500ms to under 100ms.
The web front end is React and Flux, and the desktop apps wrap it in Electron. iOS adopted React Native early, letting it reuse almost all the web's business logic, while an early Android attempt was dropped over touch performance.
In 2022, with faster Android phones and the Hermes JavaScript engine, Android moved to React Native too. Startup got slower on low-end devices at first, and the team cut median startup time in half during 2023.