Caching in Rust: Redis, Memcached, and Built-in Solutions

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why Cache in Rust?

Rust is a systems programming language valued for its performance and memory safety. However, even the fastest programs can slow down with repeated I/O operations, complex computations, or frequent database queries. Caching allows you to store the results of expensive operations and return them instantly, which is critical for high-load web services, game engines, and real-time systems.

In this article, we will look at three approaches to caching in Rust: external systems (Redis, Memcached) and built-in solutions (lru-rs, moka). You will learn how to integrate them into code, what problems each tool solves, and how to choose the best option for your project.



1. External Caching: Redis and Memcached

External cache systems operate as separate services that the application accesses over the network. They are ideal for distributed systems where multiple processes or servers need to share a common cache.



1.1. Redis via the redis Crate

Redis is the most popular in-memory store, supporting complex data structures (lists, sets, hashes). The redis crate is used to connect to Redis in Rust.

Installation: add to Cargo.toml:

[dependencies]redis = { version = "0.25", features = ["tokio-comp"] }tokio = { version = "1", features = ["full"] }

Example of basic string caching:

use redis::AsyncCommands;

#[tokio::main]async fn main() -> redis::RedisResult<()> { let client = redis::Client::open("redis://127.0.0.1:6379/")?; let mut con = client.get_multiplexed_async_connection().await?;

// Write to cache for 60 seconds let _: () = con.set_ex("user:42", "Alice", 60).await?; // Read let val: Option = con.get("user:42").await?; println!("Cached value: {:?}", val); Ok(())}

Redis is excellent for caching sessions, API responses, and task queues. Its drawback is the need to install and maintain a separate server.



1.2. Memcached via the memcache Crate

Memcached is a lighter alternative to Redis, focused on simple key-value storage. The memcache crate provides both synchronous and asynchronous APIs.

Example with the memcache crate:

use memcache::{Client, MemcacheError};

fn main() -> Result<(), MemcacheError> { let client = Client::connect("memcache://127.0.0.1:11211")?; client.set("counter", 100, 30)?; // TTL = 30 seconds let val: Option = client.get("counter")?; println!("Value: {:?}", val); Ok(())}

Memcached is faster than Redis for simple get/set operations but does not support complex data structures. Choose it if you only need "key-value" with minimal overhead.



2. Built-in Caching Libraries

For single-process applications (CLI utilities, desktop programs, game servers), external caching is overkill. Built-in solutions work in the process's memory, require no network, and are maximally fast.



2.1. lru-rs — Simple LRU Cache

The lru crate implements a cache with Least Recently Used eviction. It is ideal for caching parsing results, configurations, or small objects.

use lru::LruCache;use std::num::NonZeroUsize;

fn main() { let mut cache: LruCache = LruCache::new(NonZeroUsize::new(3).unwrap()); cache.put("a", 1); cache.put("b", 2); cache.put("c", 3); cache.put("d", 4); // "a" will be evicted because the cache is full

println!("{:?}", cache.get(&"a")); // None println!("{:?}", cache.get(&"d")); // Some(4)}

Pros: minimalistic, predictable runtime, thread-safe when using

Blogs

Book Recommendations