Caching in C++: 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 Caching in C++?



In modern C++ development, application speed is often a critical factor. Caching can significantly reduce data access time, lower the load on databases, and speed up the execution of repetitive computational operations. In this article, we will take a detailed look at three main approaches to caching in C++: using external systems (Redis and Memcached) and built-in solutions available "out of the box".



Whether you are developing a high-load web server, a game engine, or a financial system, choosing the right caching strategy can boost performance tenfold. We will break down the pros and cons of each approach and provide ready-made code examples for quick integration.



1. Built-in Caching Solutions in C++



Before connecting external services, it is worth considering the capabilities provided by the C++ language itself and its standard library. Built-in solutions are ideal for single-threaded applications or cases where data does not need to be shared between multiple processes.



1.1. Simple LRU Cache Based on std::unordered_map



The LRU (Least Recently Used) algorithm is one of the most popular for built-in caching. It automatically removes the least recently used items when the cache reaches its memory limit.



#include <unordered_map>#include <list>#include <mutex>

template <typename Key, typename Value>class LRUCache {private: size_t capacity_; std::list<Key> items_; std::unordered_map<Key, std::pair<Value, typename std::list<Key>::iterator>> cache_; std::mutex mutex_;

public: LRUCache(size_t capacity) : capacity_(capacity) {}

void put(const Key& key, const Value& value) { std::lock_guard<std::mutex> lock(mutex_); auto it = cache_.find(key); if (it != cache_.end()) { items_.erase(it->second.second); cache_.erase(it); } items_.push_front(key); cache_[key] = {value, items_.begin()}; if (cache_.size() > capacity_) { auto last = items_.back(); items_.pop_back(); cache_.erase(last); } }

std::optional<Value> get(const Key& key) { std::lock_guard<std::mutex> lock(mutex_); auto it = cache_.find(key); if (it == cache_.end()) return std::nullopt; // Move the key to the front of the list items_.splice(items_.begin(), items_, it->second.second); return it->second.first; }};


Advantages: minimal overhead, no network latency, full control over data.

Disadvantages: data is not shared between threads (manual synchronization required), limited by the memory of a single process.



1.2. Using std::shared_mutex for Multithreading



For multithreaded applications, performance can be improved by using shared_mutex, which allows multiple threads to read simultaneously:



#include <shared_mutex>

class ThreadSafeCache { std::map<std::string, std::string> data_; mutable std::shared_mutex mutex_; public: std::string read(const std::string& key) { std::shared_lock lock(mutex_); auto it = data_.find(key); return (it != data_.end()) ? it->second : ""; } void write(const std::string& key, const std::string& value) { std::unique_lock lock(mutex_); data_[key] = value; }};


2. Caching with Memcached in C++



Memcached is a distributed in-memory caching system, ideally suited for storing small fragm

Blogs

Book Recommendations