Redis
A product page keeps asking the database for the same description and display price. Each query is small, but thousands of visitors repeat it across several API instances. A dictionary inside one process helps that instance; the others still fetch and store their own copies.
Redis gives those instances a shared place to keep frequently used values. The application first looks for a cached product, loads it from the database on a miss, and stores the result for later requests. That cache-aside arrangement reduces repeated reads while leaving the database responsible for the product record.
Salvatore Sanfilippo, known as antirez, created Redis in 2009 while working on data-access performance for his startup. Redis keeps its working dataset in memory and exposes operations on familiar structures such as strings, hashes, sets, and sorted sets. Those operations can avoid transferring a whole object to the application just to change one field or score.
With a local Redis server and redis-cli installed, cache a display value for sixty seconds:
redis-cli SET product:42 '{"title":"Keyboard","price":79}' EX 60
redis-cli GET product:42
redis-cli TTL product:42 # Remaining lifetime in secondsEX attaches the expiry to the same operation that writes the value. When the key expires, a later lookup misses and the application can reload it. This is different from filling memory indefinitely: memory limits and an eviction policy determine what Redis does under capacity pressure.
A product update introduces the harder part. After committing the database change, the application can remove the cached copy:
redis-cli DEL product:42Concurrent readers can still race with that update and repopulate an older value. Expiry limits how long a particular cached copy lives; stricter freshness needs versioning or another coordination strategy. Checkout should validate the authoritative price and stock rather than trusting a display cache. If Redis is unavailable, falling back to the database also needs a limit so all the missed requests do not overwhelm it at once.
The data structures become useful when the job is more specific than retrieving JSON. A sorted set can maintain a leaderboard as scores change:
redis-cli ZADD game:weekly 120 alice 95 bob
redis-cli ZINCRBY game:weekly 30 bob
redis-cli ZRANGE game:weekly 0 9 REV WITHSCORESThe last command returns the highest scores first; Bob now has 125. Updating a score keeps the member in the right position without the application downloading and sorting the entire leaderboard. Hashes similarly let a service retrieve or update individual fields:
redis-cli HSET session:demo user_id 42 locale en
redis-cli EXPIRE session:demo 1800
redis-cli HGET session:demo user_id
redis-cli INFO memoryThe session example is deliberately a simple command sequence. If creating the hash and setting its expiry must succeed together, use a transaction or Lua script so an interrupted client cannot leave an immortal session.
Memory gives Redis its useful latency profile, but the amount of work in a command and the network round trips still matter. Persistence settings also matter: RDB snapshots and the AOF write log provide different recovery and performance tradeoffs, and asynchronous replication can lose recent acknowledged writes during failover. Configure those choices around what losing a cache entry, session, or score would actually mean.
Caches and invalidation develops the freshness and failure behavior behind the product-page example.