When most people open Discord, they see channels, emojis. And voice rooms. Underneath that friendly UI is a distributed system that routes enormous volumes of real-time events, stores trillions of messages. And keeps millions of concurrent voice sessions alive across the globe.

Discord isn't just a chat app; it is a live case study in large-scale fan-out, eventual consistency. And polyglot service design. Engineering teams building anything from IoT telemetry dashboards to AI collaboration tools can learn from how Discord handles backpressure, shards stateful connections, and isolates failure domains.

In this post we walk through the platform's core architecture, its recent security and policy challenges and the practical lessons we have taken away from running similar real-time workloads in production. Read our guide to building WebSocket backends at scale

The Gateway handles stateful fan-out at scale

Text chat on Discord starts with the Gateway, a persistent WebSocket service implemented according to RFC 6455. Every client opens a long-lived connection, identifies itself with a token, and then receives a firehose of events: message creates, presence updates, typing indicators, guild member changes, and thread modifications. The payload format is usually JSON. But the Gateway also supports Erlang External Term Format for clients that can parse it.

Conceptual diagram of WebSocket gateway shards distributing real-time events across server nodes

Because a single process can't hold millions of connections indefinitely, Discord uses sharding. Each shard is responsible for a subset of guilds. And the client is told which gateway server and shard ID to use. Shards support resumable sessions via sequence numbers and a heartbeat/ack handshake. If a shard restarts, clients reconnect and replay missed events rather than reloading the entire world state. That pattern is the difference between a brief spinner and a full app restart.

In production environments, we found that naïve per-connection goroutines or GenServers quickly create memory bloat and head-of-line blocking. Discord's shard-per-process model, combined with explicit backpressure through heartbeat acks, is a cleaner design: it bounds the blast radius of a bad deployment and gives operators a coarse-grained unit for canary analysis. See our SRE incident response checklist

From Erlang to Rust: Discord's polyglot backend

Discord's backend is deliberately polyglot. The guild and channel orchestration layers run on the Erlang Virtual Machine through Elixir, taking advantage of lightweight processes, OTP supervisors. And hot code loading. When one guild misbehaves, the BEAM scheduler isolates the fault instead of cascading across the whole node. For performance-sensitive paths such as media proxying and image resizing, Discord uses Rust. Go and Python appear in tooling, ML inference, and operational services.

This split isn't accidental. Elixir buys you concurrency semantics and fault isolation; Rust buys you predictable memory layout and zero-copy networking. The cost is operational complexity: multiple runtimes, separate build pipelines, distinct memory profiles. And observability libraries that all need to speak the same trace ID format. Teams that copy the stack without copying the operational muscle often end up with the worst of both worlds.

When my team built a real-time notification mesh, we ended up with a similar split: Rust on the media path, Elixir for session coordination. And OpenTelemetry as the single source of truth. The lesson was that language choice matters less than a unified telemetry and deployment model. If your services can't share a trace, you don't have a system-you have a collection of binaries. Explore our cloud infrastructure consulting services

Storing trillions of messages without breaking the bank

Every message sent on Discord is assigned a 64-bit snowflake-style ID that embeds a timestamp, a worker identifier. And a sequence number. That ID becomes the primary key for time-ordered queries. Discord stores the hot message corpus in a ScyllaDB cluster, a C++ rewrite of Cassandra that lowers tail latency, and pushes older data toward object storage. The engineering team has published details on how they scaled this to trillions of rows.

Distributed database cluster storing petabytes of chat history

The read path is heavily optimized by channel-scoped queries and bounded time ranges. Because users rarely scroll back more than a few days, the system can serve recent messages from memory and replicated SSDs while archival reads hit cheaper tiers. Attachments, emojis, and avatars are cached through a CDN layer. But the metadata index still has to remain consistent enough that search and unread badges feel instant.

The architectural lesson here is simple but easy to ignore: don't index every field of every message. Use time-series partitioning, keep TTL policies for ephemeral data, and design your storage tiers around actual access patterns. We applied the same idea to a telemetry pipeline by writing hot metrics to Redis Streams and aging cold aggregates into Parquet on S3. The cost savings were immediate, and query latency stayed flat. Read our guide to data tiering and cost optimization

Discord Engineering: How Discord Stores Trillions of Messages

Voice and video routing with WebRTC and SFUs

Discord voice is built on WebRTC, described in RFC 8825, with ICE for NAT traversal, DTLS for key negotiation, and SRTP for encrypted media transport. Clients connect to regional voice servers rather than forming peer-to-peer meshes. Those servers act as Selective Forwarding Units, receiving encrypted audio and video streams and relaying them to the other participants.

SFUs are the right choice for group calls because they avoid the upload-bandwidth problem of mesh networks and the single-point-of-failure problem of Multipoint Control Units. Discord can place SFUs close to users, reduce latency. And apply server-side features like noise suppression and video quality adaptation. The trade-off is that Discord must operate a global fleet of low-latency UDP endpoints and monitor jitter, packet loss. And RTT in real time.

Running a production SFU taught us that media metrics aren't optional. You need per-track bitrate graphs, RTCP receiver reports, and automated failover between regions. One bad route can turn a stand-up into a robotic echo chamber. And users will blame your app before they blame their ISP. Instrument the path end-to-end, and keep a kill switch that can force a client to a different region.

Observability and incident response under load

Discord operates a public status page and publishes postmortems for major outages. In recent years, the platform has been affected by upstream issues such as Cloudflare routing incidents and AWS regional degradation. But it has also suffered self-inflicted bugs in gateway deployments and push notification pipelines. Real-time systems have narrow failure windows: a single bad opcode or rate-limit miscalculation can disconnect millions of clients at once.

Engineers reviewing incident response dashboards during a live outage

The SRE playbook is familiar but executed at scale: distributed tracing, RED metrics, SLO-based alerting, canary releases. And feature flags for graceful degradation. If presence updates start to lag, Discord can throttle or disable them without taking down chat. If a shard type shows elevated errors, traffic can be drained to a new build. The key is that every subsystem has a dial, not just an on-off switch.

From our own production incidents, the most expensive mistake was relying on dashboards that lagged behind reality. We now treat distributed tracing as the primary signal and metrics as the secondary confirmation. When a gateway latency spike hits, OpenTelemetry lets us follow a single event from the edge load balancer through the shard process to the database and back that's the only way to debug a system where state lives in millions of connections instead of a single database row.

Security, abuse. And phishing on a CDN platform

Discord is more than a messaging network; it's also a content-distribution and identity platform. Attackers routinely abuse Discord CDN links to host malware, distribute phishing pages through direct messages, and trick users into authorizing malicious OAuth2 bots. The invite system. Which makes onboarding frictionless, also makes bulk recruitment trivial for scammers.

The response is a mix of signals: file-hash matching against known malware, Safe Browsing-style URL scanning, rate limits on invites and direct messages, and machine-learning classifiers for spam. On the encryption side, Discord has begun rolling out end-to-end encryption for audio and video through the DAVE protocol, attempting to balance privacy with the ability to report abuse. Identity and access management relies on OAuth2 scopes, privileged gateway intents. And server-level permission hierarchies.

If your product allows users to upload files or generate shareable links, treat those as first-class security surfaces from day one. We learned this the hard way when a free file-upload feature in one of our apps became a malware-distribution vector within weeks. Hash every upload, scan outbound links. And design permission scopes with the principle of least privilege. Security can't be a backlog item; it's an architectural constraint.

Bots, webhooks, and the developer ecosystem

Discord exposes a REST API and a Gateway API. Which together power one of the largest third-party bot ecosystems on the internet. Bots authenticate with OAuth2 tokens, subscribe to specific Gateway intents. And can register slash commands that Discord renders as native UI elements. Webhooks provide a simpler HTTP path for notifications from CI/CD pipelines - monitoring systems, and game backends.

The platform enforces rate limits through response headers such as X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset-After. Global, per-route, and per-guild limits all apply. And exceeding them can temporarily ban your application. Slash commands require an HTTPS interactions endpoint that validates Ed25519 signatures. Which means bot developers must manage TLS termination and request verification correctly.

When my team built a Discord bot for on-call rotations, the most important design decision was idempotency. Retry storms after a 502 response can create duplicate pages and angry engineers. We implemented exponential backoff with jitter, idempotency keys for outgoing notifications. And a dead-letter queue for failed interactions. Those patterns matter on any platform with strict rate limits and at-least-once delivery semantics. Check out our guide to building resilient API clients

Discord Developer Documentation: Gateway

Platform policy and information integrity mechanics

Moderation at Discord's scale is a distributed classification problem. AutoMod scans messages using keyword lists, regex patterns, and ML classifiers for spam, harassment,, and and explicit contentUser reports feed into appeal workflows. And some categories trigger hash-based detection for child safety imagery. The platform must make decisions in milliseconds while preserving user privacy and minimizing false positives.

The engineering challenge is separating detection, decision. And enforcement into independent pipelines. Detection happens at the edge, decision logic applies policy rules, and enforcement executes mutes, kicks. Or content removal. Audit logs make every action reversible and reviewable. This three-stage design is the same pattern used by content networks and ad platforms. But the latency budget is tighter because users expect chat to feel instantaneous.

We adopted a similar split for a community product and immediately saw fewer accidental bans. When a single service tries to detect, decide, and enforce simultaneously, a classifier bug can lock out innocent users before a human can review it. Decoupling the stages also makes A/B testing new models safer: you can shadow-run a classifier and compare its decisions against production outcomes without affecting users.

Lessons for engineering teams building real-time platforms

Discord's architecture offers a blueprint. But not a cookie-cutter stack. The first lesson is to shard state early don't wait until a single node is drowning in connections to partition your users or rooms. Consistent hashing - geographic affinity. And resumable sessions are cheaper to design in at the beginning than to retrofit later.

The second lesson is to instrument before you improve. Real-time systems fail in subtle ways: partial partitions, slow consumers, and GC pauses all look like "the app is slow. " Distributed tracing, per-shard metrics. And synthetic user probes will save more user sessions than any caching layer. Finally, treat abuse, compliance, and policy as engineering requirements, and gDPR data export, message deletion,And audit logging aren't legal afterthoughts; they shape your data model and retention strategy.

We have applied these principles to mobile and web projects across Denver and remote teams. And the payoff is always the same: fewer 3 A. M pages, faster incident recovery. And a platform that can absorb growth without a rewrite. Contact our Denver engineering team for architecture reviews

Frequently asked questions

What protocol does Discord use for real-time text?
Discord uses the WebSocket protocol defined in RFC 6455. Clients open a persistent connection to the Gateway and receive events such as message creates, presence updates. And guild member changes.

How does Discord scale its gateway to millions of users?
The Gateway is horizontally scaled through sharding. Each shard handles a subset of guilds, supports session resumption with sequence numbers. And can be canaried or drained independently.

What database technology does Discord use for messages?
Discord stores the active message corpus in ScyllaDB, a C++ rewrite of Cassandra. And moves older data to object storage. The architecture is optimized for time-ordered, channel-scoped reads.

How does Discord encrypt voice and video?
Voice and video use WebRTC with DTLS for keying and SRTP for media encryption. Discord also began introducing end-to-end encryption for audio and video through the DAVE protocol.

What can engineering teams learn from Discord outages?
The main lessons are to shard state early, use feature flags for graceful degradation, enforce strict rate limiting. And rely on distributed tracing rather than lagging dashboards during incident response.

Conclusion

Discord's infrastructure shows what happens when consumer UX meets planet-scale backend engineering. Its combination of Erlang concurrency, Rust performance, and WebRTC media routing is impressive. But the real lesson is operational: shard state, instrument everything. And treat abuse as a first-class engineering concern.

If you're designing a real-time collaboration, gaming. Or AI copilot product, borrow the patterns rather than the entire stack. Start with WebSockets and a clear sharding strategy, add observability before you need it, and assume attackers will abuse any free feature the day it ships. Ready to architect your next real-time product? Review Discord's voice connection docs for implementation specifics, then reach out to our team for a production-readiness review.

What do you think?

Would you choose Elixir/BEAM or Go for a high-fan-out real-time gateway today,? And why?

How should platforms balance end-to-end encryption with the ability to detect abuse and illegal content?

What is the most underrated operational practice you have seen keep a real-time system alive during an incident?

.

Need a Custom App Built?

Let's discuss your project and bring your ideas to life.

Contact Me Today →

Back to Online Trends