Rust is secure by design: why Discord left Electron behind, and why more software should follow
Nathan Chadwick · · 7 min read
TLDRRead the short version
- Rust is secure by design: the ownership and borrow checker shut down whole classes of memory bugs at compile time that C and C++ leave to runtime and hope.
- Memory safety defects still dominate critical software vulnerabilities. Choosing a safer systems language is a control, not a style preference.
- Discord proved the performance case twice: Read States moved from Go to Rust to kill GC latency spikes, and the desktop client is leaving Electron for a Rust rebuild that uses a fraction of the RAM.
- The industry should port hot paths, security-critical code, and resource-heavy clients to Rust where the risk or cost of the old stack is clear.
- AI now makes large ports practical: it can translate modules, generate tests, explain unsafe boundaries, and accelerate rewrites that used to stall on headcount.
On this page
- Rust is not a fashion. It is a safer default for serious software.
- Secure by design, not secure by discipline
- Why this matters more than ever
- Discord: the case study people should actually read
- Why more of the industry should port to Rust
- Where AI changes the rewrite economics
- The honest caveats
- What to do next
Rust is not a fashion. It is a safer default for serious software.#
Most programming language debates are taste. Rust is different.
It is one of the few mainstream systems languages that makes a large class of catastrophic bugs illegal by construction. Not "caught by a linter if you remember to run it." Not "mitigated by ASLR and a prayer." Illegal. The compiler refuses to ship them.
If you care about security, reliability, or the cost of running software at scale, that is worth sitting with.
Secure by design, not secure by discipline#
C and C++ built the modern world. They also built a vulnerability landscape that never really healed.
Buffer overflows. Use-after-free. Double free. Out-of-bounds reads. Data races that only appear under load. These are not exotic research bugs. They are the recurring root cause behind decades of CVEs in browsers, kernels, network stacks, codecs, and privilege boundaries. Memory-unsafe languages keep paying the same tax because the language model allows the mistake in the first place.
Rust flips the model.
Ownership, borrowing, and lifetimes are not academic ornament. They are the security model:
- You cannot freely alias mutable state in ways that create data races
- You cannot keep using memory after it has been freed
- You cannot casually overrun a buffer and call it "undefined behaviour"
- Safe Rust makes whole families of exploit primitives fail at compile time
That is what "secure by design" actually means. The safe path is the default path. Escape hatches exist (unsafe), but they are explicit, reviewable, and meant to be small. In C and C++, every function is potentially an escape hatch.
You still have to think. Logic bugs, auth bugs, and supply-chain mistakes do not vanish. But eliminating memory unsafety removes one of the highest-yield attack surfaces in systems software. For security-critical components, that is not a nice-to-have. It is architectural risk reduction.
Why this matters more than ever#
Attackers do not need a novel idea when the old classes of bugs still ship.
Memory corruption remains a favourite path into privilege escalation, remote code execution, and sandbox escapes. Meanwhile the amount of software touching untrusted input keeps growing: parsers, agents, plugins, browsers-in-apps, side cars, edge services, IoT, and AI tooling glued onto old runtimes.
Every year the industry rediscovers the same lesson: patching faster is good, but designing so the bug class cannot exist is better. National cyber agencies and major vendors have been saying the quiet part out loud for years: move critical code toward memory-safe languages. Rust is the practical systems answer that does not force you into a garbage-collected runtime everywhere.
Discord: the case study people should actually read#
Discord did not adopt Rust because a conference talk made it sound cool. They adopted it because production pain demanded it, twice.
First: backend performance without GC spikes#
Discord's famous Read States rewrite moved a hot-path service from Go to Rust. The service tracks what you have read across channels and messages. It sits in the critical path of feeling "snappy."
Go was fast most of the time. Then garbage collection created latency spikes that no amount of GC tuning fully fixed, because the collector still had to scan a huge live cache. Shrinking the cache reduced spikes but hurt hit rates and made p99 worse. Classic garbage-collector trap: you are fighting the runtime instead of the product problem.
Rust removed that class of spike. Ownership meant memory could be freed predictably when cache entries left, without a stop-the-world scan of millions of live objects. The result was better latency behaviour under real load, with the same job done more predictably.
That is the systems argument in one paragraph: when your service is memory-heavy and latency-sensitive, a language with manual-feeling control and compile-time safety beats "mostly fine until the GC runs."
Second: leaving Electron for a Rust desktop client#
Discord also spent years living with the Electron tax. Electron made cross-platform shipping easy. It also meant shipping a Chromium-shaped desktop footprint. Memory climbed. Users noticed. Discord publicly tested restarting the Windows client when usage blew past multi-gigabyte thresholds because "normal" Electron usage was already heavy.
So they went further. Discord's CTO has been clear that the company has used Rust since 2018 across infra, voice, and parts of the client, and that the goal is a full desktop client in Rust. Electron goes away. The early Windows rebuild has been shown running around 290MB of RAM, against an Electron app that could balloon toward 1GB–4GB depending on usage. Startup gets faster because you are not lifting a whole embedded browser stack just to open chat.
That is the product argument: memory safety and performance are not opposites. Done properly, Rust gives you both. Users feel it as a lighter, quicker app. Operators feel it as lower machine cost and fewer "why is this eating my RAM" support tickets.
Discord is not a toy example. It is a high-scale consumer product choosing Rust for the bits where latency, memory, and reliability are the product.
Why more of the industry should port to Rust#
Not everything needs a rewrite. Blind rewrites are how companies invent new outages.
But a lot of software does belong on a migration path:
- Security boundaries: parsers, protocol handlers, privilege helpers, crypto-adjacent glue, sandbox brokers
- Hot paths: caches, fan-out services, media pipelines, realtime state
- Resource-heavy clients: desktop shells that are currently Electron-shaped and permanently hungry
- Long-lived infrastructure: the code that will still be running when today's team has moved on
The industry pattern is familiar. Ship quickly in a convenient stack. Accumulate memory bugs, GC cliffs, or browser-app bloat. Patch forever. Hire more people to operate the mess. Rust breaks that loop for the components where the mess is most expensive.
Porting also compounds. Once a company has Rust services, shared libraries, CI, and people who can review unsafe, the next migration is cheaper. Discord's path shows that: client experiments and server NIFs first, then a critical service, then the desktop client itself.
If your organisation builds systems software, edge software, or anything that handles hostile input at scale, "we will stay on C/C++ forever" is increasingly a risk acceptance decision. Treat it like one. Write it down. Cost it honestly.
Where AI changes the rewrite economics#
The historical objection to Rust ports was headcount and time. Rewrites were slow, experts were scarce, and migrating a million-line C++ tree felt impossible.
AI changes the shape of that work.
Used properly, modern coding agents and models can:
- Translate modules from C, C++, Go, or TypeScript/Electron native bridges into idiomatic Rust drafts
- Generate characterisation tests before and after so behaviour does not silently drift
- Explain borrow-checker errors in plain language so juniors can unblock instead of thrashing
- Flag
unsafeblocks and suggest safer encapsulations - Map FFI boundaries, replace ad-hoc parsers, and propose crate equivalents for common libraries
- Help prioritise what to port first by spotting the hottest or most vulnerability-dense files
AI will not replace design judgement. You still need humans who understand ownership, concurrency, and threat models. What AI does remove is a lot of the mechanical grind that made ports stall: boilerplate conversion, test scaffolding, documentation of call graphs, and first-pass rewrites of self-contained components.
That means the old excuse is weaker. You do not need a 50-person Rust guild to start. You need a clear boundary, a test harness, a memory-safety goal, and a workflow where AI accelerates the conversion while engineers own the review.
The smart pattern looks like this:
- Pick a component with clear inputs/outputs and painful memory or latency behaviour
- Lock behaviour with tests and fixtures
- Use AI to draft the Rust port and the FFI/shim layer
- Keep
unsafesmall and reviewed - Ship behind a flag, compare latency/memory/error budgets, then cut over
- Repeat on the next boundary
That is how organisations move without betting the company on a big-bang rewrite.
The honest caveats#
Rust has a learning curve. Compile times can sting. The ecosystem is excellent in many domains and merely fine in others. Not every CRUD app needs it. Not every team should abandon a productive managed language for a blog-post ideology.
The claim is narrower and stronger: for systems work, security-critical parsing, performance-sensitive services, and desktop clients drowning in Electron overhead, Rust is one of the best engineering bets available. Secure by design. Fast when it matters. Proven in production by companies that feel memory and latency in their support queues.
What to do next#
If you maintain C or C++ in a hostile-input path, put Rust on the roadmap for the next boundary rewrite. If you run Go or Node services that spend their life fighting GC or heap growth, profile honestly and ask whether ownership would remove the cliff. If your desktop app is an Electron process users resent, watch what Discord is doing and stop pretending the memory bill is inevitable.
And if the blocker has been "we cannot afford the rewrite," revisit that assumption with AI-assisted conversion in the plan. The industry does not need another decade of the same memory CVEs and the same bloated clients. It needs more software that cannot express the bug in the first place.