Read States is the service that was moved from Go to Rust. Its primary function is to record the channels and messages we have read. Every time we sign in to Discord, send a message, and read a message, Read States is accessed.To put it simple, Read States is on a hot road. Therefore, Incredible speed and minimal latency are required for Read States service.
Discord is a communication platform with billions of read states for users and channels. However, there is only one read state that holds various counters, such as the number of mentions in a channel. These counters must be updated atomically and often reset to 0. To achieve this, each read state service maintains a LRU (least recently used) cache of read states, allowing for fast atomic counter updates. Each cache has millions of users and tons of millions of read states, with cache modifications occurring hundreds of thousands of times each second. This caching strategy helps to efficiently manage and update the vast amount of read states on Discord.
Before moving forward let's now talk on how RUST and GO manage their memories.
Memory is not instantly released in Go upon cache key eviction.Instead, every so often, the garbage collector runs to discover any memory that has no references and releases it. In other words, memory hangs out until the garbage collector can assess if it is genuinely out of use, rather than releasing immediately once it is no longer needed.The amount of effort Go must undertake to figure out what memory is free during garbage collection might cause the application to lag. Go will require garbage pickups to occur at least every two minutes.In other words, regardless of heap growth, go will still trigger a garbage collection if it has not run for 2 minutes.
With no runtime or garbage collector, Rust is amazingly quick and memory-efficient. It can power performance-critical applications, run on embedded devices, and interface with other languages with ease. Rust implements memory "ownership" as part of a rather novel approach to memory management. Rust essentially keeps track of who is able to read from and write to memory. It is aware of when an application is utilizing memory and instantly releases it when no longer required. Runtime memory problems are practically hard to have since it enforces memory restrictions at build time.You don't have to manually manage your memory.The compiler handles it for you. So, in the Rust version of the Read States service, a user's Read State is instantly released from memory when it is removed from the LRU (least recently used) cache.
The read state memory doesn't wait for the garbage collector to pick it up. Rust promptly releases it because it is no longer needed.No runtime process checks if it needs to be released.
The CPU utilization after switching this Read State service from Go to Rust is seen below.
Go is purple, Rust is blue. No alt text provided for this image
I absolutely adore the drive and mindset behind Discord's Backend Team.