Estudo de caso · Stack

Como o Discord dá conta de trilhões de mensagens com Elixir, Python e Rust

O Discord é onde milhões de comunidades conversam por texto, voz e vídeo. O stack junta Elixir para as conexões em tempo real com um monólito de API em Python, e com o tempo levou os trechos mais quentes para o Rust e o armazenamento do MongoDB para o Cassandra e depois para o ScyllaDB.
Copiar stackdiscord.com Chat de voz, vídeo e texto para comunidades · Estados Unidos · fundada em 2015

A stack da Discord

Abrir no montador

Biblioteca de interface

Framework full-stack

Hospedagem

  • Google Clouddiscord.com

    Hospeda a API no Google Kubernetes Engine.

  • Kubernetesdiscord.com

    Roda a API em Python em centenas de deployments.

Banco de dados

  • ScyllaDBdiscord.com

    Guarda trilhões de mensagens, no lugar do Cassandra desde 2022.

    Por quê: É compatível com o Cassandra, mas mais rápido, com reparos mais ágeis e sem coleta de lixo por ser escrito em C++.

Framework de celular

  • React Nativediscord.com

    Monta o app de iOS e, desde 2022, o de Android.

    Por quê: Deixa o celular reaproveitar quase toda a regra de negócio da web, e o Hermes com celulares mais rápidos tornou isso viável no Android.

Busca de dados

  • gRPCdiscord.com

    Expõe os serviços de dados em Rust, mais ou menos um endpoint por consulta ao banco.

  • Google Cloud Pub/Subdiscord.com

    Enfileira as mensagens que esperam para entrar no índice da busca.

    Por quê: Garante a entrega e aguenta filas grandes, enquanto o Redis perdia mensagens.

  • BigQuerydiscord.com

    Abriga o data warehouse.

  • Dagsterdiscord.com

    Orquestra os pipelines de dados, no lugar do Airflow.

    Por quê: Atendeu aos critérios deles: suporte a Kubernetes, automação declarativa, boa interface e migração fácil dos jobs que já existiam.

  • dbtdiscord.com

    Modela e transforma os dados no warehouse.

    Por quê: A quantidade de recursos em volta do dbt fez dele uma escolha óbvia.

Framework de servidor

  • Elixirdiscord.com

    Roda a camada em tempo real: sessões por WebSocket, servidores (guilds) e presença.

    Por quê: Dá acesso à força da máquina virtual do Erlang com uma linguagem e ferramentas mais modernas e amigáveis.

  • Pythondiscord.com

    Move o monólito da API, com mais de 1.700 endpoints e cerca de 700 tarefas em segundo plano.

  • Rustdiscord.com

    Move serviços em que a latência é crítica, como o Read States, e acelera o Elixir por funções nativas.

    Por quê: O Rust não tem coleta de lixo, o que acabou com os picos de latência que tinham no Go.

Busca

  • Elasticsearchdiscord.com

    Indexa as mensagens para busca em 40 clusters agrupados em células.

Como montaram

Elixir desde o primeiro protótipo

O primeiro protótipo do Discord foi escrito em Elixir, e esse código virou a base da infraestrutura em tempo real. Cada usuário se conecta por WebSocket a um processo de sessão, que conversa com processos de servidor (guild) em nós Erlang remotos, e eles espalham os eventos para todo mundo online.

O time escolheu Elixir para ter a força da máquina virtual do Erlang com uma linguagem e ferramentas mais modernas e amigáveis. Para continuar escalando, criaram bibliotecas próprias e depois trouxeram o Rust por funções nativas.

Fontes:discord.com discord.com

MongoDB, depois Cassandra, depois ScyllaDB

As mensagens começaram no MongoDB e foram para o Cassandra por escala e pouca manutenção. Em 2022 o cluster de Cassandra tinha 177 nós, chamava o plantão o tempo todo, sofria com partições sobrecarregadas e com pausas de coleta de lixo que geravam picos de latência.

Em maio de 2022 o Discord levou as mensagens para o ScyllaDB, o último dos seus bancos a mudar, e caiu para 72 nós. O ScyllaDB é compatível com o Cassandra e escrito em C++, sem coleta de lixo. No meio do caminho entraram serviços de dados em Rust que juntam pedidos iguais, para um canal movimentado gerar uma consulta ao banco em vez de milhares.

Fontes:discord.com

Rust onde a coleta de lixo do Go atrapalhava

O serviço Read States, que guarda o que cada pessoa já leu, era escrito em Go. Mais ou menos a cada dois minutos ele tinha picos de latência, causados pela coleta de lixo varrendo um cache enorme na memória.

Em 2019 o Discord reescreveu o serviço em Rust, que libera a memória assim que ela deixa de ser usada. A versão em Rust não teve picos e ganhou do Go em latência, CPU e memória. O Rust também roda no SDK de jogos, na codificação de vídeo do Go Live e em vários serviços do backend.

Fontes:discord.com

Refazendo a busca para trilhões de mensagens

A busca rodava em dois clusters gigantes de Elasticsearch, alimentados por uma fila no Redis. Com fila acumulada, o Redis batia no limite de CPU e perdia mensagens, um nó com problema derrubava lotes inteiros, e alguns servidores grandes chegavam ao limite de cerca de 2 bilhões de documentos por índice do Lucene.

Na reconstrução de 2025, o Redis deu lugar ao Pub/Sub do Google Cloud, que garante a entrega, entrou um roteador de mensagens em Rust e a busca foi dividida em 40 clusters menores, gerenciados no Kubernetes. A latência mediana das buscas caiu de 500 ms para menos de 100 ms.

Fontes:discord.com

Um código React para web, desktop e celular

O front web é em React e Flux, e os apps de desktop embrulham isso no Electron. O iOS adotou React Native cedo e reaproveita quase toda a regra de negócio da web, enquanto uma primeira tentativa no Android foi abandonada por causa do desempenho do toque.

Em 2022, com celulares Android mais rápidos e o motor JavaScript Hermes, o Android também foi para React Native. No começo o app abriu mais devagar nos aparelhos simples, e em 2023 o time cortou pela metade o tempo mediano de abertura.

Fontes:discord.com discord.com discord.com

Também detectado no site

Achado na página inicial com as regras abertas do Wappalyzer (HTML, scripts e cabeçalhos). Mostra o que roda no navegador, não o backend inteiro.

  • Cloudflare
  • Google Font API
  • Google Hosted Libraries
  • HSTS
  • HTTP/3
  • OneTrust
  • hCaptcha
  • jQuery