Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

Technology handbook

Redis caching solutions

Cache strategies, data structures, consistency, expiration, clustering, persistence and production diagnostics.

Topics
41
Sections
6

Learning module

Redis learning module

Redis is an in-memory data structure store used by millions of developers as a cache, vector database, document database, streaming engine and message broker.

  • One command thread makes every command atomic, and a slow one blocks everybody.
  • Use SCAN, never KEYS, on production data.
  • Cache-aside: write the database, then delete the key; add TTL jitter.
  • Replication is asynchronous, so a failover can lose acknowledged writes.

A primary database that cannot absorb every read: Without a cache, every page view hits the primary database: hot rows are re-read thousands of times per second, latency climbs under load, and features such as rate limits, sessions, counters and leaderboards turn into contended row updates. Redis serves that hot data from memory in sub-millisecond time with atomic operations on purpose-built types, so the database handles writes and complex queries while Redis absorbs the repetitive, latency-sensitive traffic.

Client hooks & events

Client error events

Attach an error listener at creation: an unhandled client error can take the process down.

  • Attach the client's error listener before initiating a connection.
  • Record the operation context without logging credentials.
  • Treat error notifications separately from per-command promise failures.

Connection lifecycle events

connect, ready, reconnecting and end are the states a pool's health check should read.

  • Distinguish connecting, ready, reconnecting and closed states.
  • Gate operations on the readiness guarantees of the chosen client.
  • Release listeners and connections during application shutdown.

Reconnect strategy

Supply a backoff function so a flapping server is not hammered by every instance at once.

  • Use bounded exponential reconnect delay with jitter.
  • Avoid a tight retry loop during a Redis outage.
  • Decide whether queued commands remain valid after reconnection.

reconnectOnError

Decide per error whether the client should reconnect, for cases such as a failed-over replica.

  • Use reconnectOnError only with a client that supports it.
  • Select the server errors that justify reconnecting deliberately.
  • Consider duplicate writes before automatically resending a failed command.

Keyspace notifications

Subscribe to expiry and eviction events instead of polling for keys that vanished.

  • Enable only the notification classes the application needs.
  • Subscribe to the correct database and event channels.
  • Notifications are ephemeral and cannot replace a durable event log.

Client-side cache invalidation

CLIENT TRACKING pushes invalidation messages so a local cache can drop a stale entry.

  • Enable tracking with a client and server that support it.
  • Remove local entries when invalidation messages arrive.
  • Define recovery behavior when the invalidation connection is lost.

Pub/Sub message handlers

A subscriber connection cannot run ordinary commands, which shapes how handlers are wired.

  • Use a dedicated subscription connection where the client requires one.
  • Keep message handlers fast and catch processing failures.
  • Resubscribe after reconnecting without assuming missed messages are replayed.

Server-side scripts as hooks

A Lua script or function runs atomically on the server, where a read-modify-write would race.

  • Execute bounded Lua scripts or registered functions near the data.
  • Pass accessed keys explicitly for cluster-aware execution.
  • Avoid slow scripts that block other server work.

Redis foundations

Keys and namespacing

Design stable keys that include entity and tenant boundaries; distinguish missing keys from empty values.

  • Include application, tenant and data purpose in key names.
  • Choose a predictable version suffix when payload shape changes.
  • Use SCAN rather than blocking key enumeration in production.

Strings and counters

Store byte strings and use atomic increments for counters instead of client-side read-modify-write.

  • Use GET and SET for byte strings or serialized values.
  • Use atomic INCR operations for counters.
  • Set expiry explicitly when a counter belongs to a time window.

Hashes

Group named fields for an entity and compare field-level updates with replacing one serialized value.

  • Store related fields in one hash when partial updates are useful.
  • Read or update only the fields the operation needs.
  • Bound hash size and avoid mixing unrelated ownership scopes.

Lists

Use ordered sequences for suitable queue-like patterns while checking reliability requirements.

  • Push and pop values from the intended end of the list.
  • Use blocking operations carefully with dedicated worker connections.
  • Prefer streams when acknowledgements and durable consumer tracking are needed.

Sets

Represent unique membership and use set operations when order is irrelevant.

  • Use sets for unique membership and set operations.
  • Check membership without downloading the entire set.
  • Watch memory growth when storing unbounded user-generated values.

Sorted sets

Associate members with scores for ranking, scheduling and bounded range queries.

  • Associate each unique member with a numeric ordering score.
  • Query bounded score or rank ranges for leaderboards.
  • Define tie-breaking and pagination behavior explicitly.

Streams

Store append-oriented event records and track consumer progress with the supported stream mechanisms.

  • Append events with ordered stream IDs.
  • Use consumer groups and acknowledge completed processing.
  • Inspect pending entries and reclaim abandoned work.

JSON and search capabilities

Check the deployed Redis capabilities before relying on document storage or secondary search features.

  • Check which JSON and search features the deployment supports.
  • Define indexes around actual query and filter patterns.
  • Measure write amplification and index memory separately from cached values.

Caching patterns

Cache-aside

Load the source of truth on a miss, populate Redis and define how writes invalidate cached values.

  • Read the cache before loading from the source database.
  • Populate misses with a bounded TTL.
  • Invalidate or refresh entries after authoritative writes.

Read-through caching

Place retrieval logic behind a cache abstraction so callers use one read contract.

  • Use a cache layer that loads missing values on behalf of callers.
  • Keep the loader's errors distinct from a valid missing record.
  • Coalesce concurrent loads for the same key.

Write-through caching

Coordinate source writes and cache updates and document what happens when one succeeds and the other fails.

  • Update the cache as part of the application's write path.
  • Define recovery when the database write and cache update disagree.
  • Keep the database as the explicit authority unless designed otherwise.

Write-behind tradeoffs

Buffer writes only when delayed persistence and potential loss match the business requirements.

  • Buffered writes reduce immediate database pressure.
  • A crash can lose unflushed updates without durable buffering.
  • Define ordering, flush retries and acceptable data-loss bounds.

TTL and expiration

Set expiry according to freshness requirements and understand that eviction is a separate mechanism.

  • Apply TTLs that match freshness and retention requirements.
  • Redis expiration removes a key rather than refreshing its content.
  • Add jitter when many keys would expire together.

Cache invalidation

Invalidate affected keys after changes without overlooking derived lists or aggregate views.

  • Invalidate keys affected by the committed domain change.
  • Use versioned keys when enumerating dependent entries is impractical.
  • Test races between stale loaders and fresh writes.

Cache stampede

Use request coalescing, jitter or controlled regeneration when many readers miss simultaneously.

  • Coalesce concurrent requests for the same missing value.
  • Use bounded locks or single-flight loading to protect the database.
  • Spread expirations and consider serving an acceptable stale value.

Negative caching

Cache absent results briefly when useful, with safeguards against hiding newly created data.

  • Cache confirmed absence for a shorter, deliberate lifetime.
  • Distinguish not-found from authorization and dependency failures.
  • Invalidate negative entries when the resource is created.

Stale-while-revalidate

Serve bounded stale data while refreshing when the product can tolerate temporary staleness.

  • Serve an acceptable cached value while refreshing asynchronously.
  • Track fresh and stale windows separately.
  • Stop serving stale data when its correctness window expires.

Hot keys and large values

Identify skewed traffic and oversized payloads before simply adding more capacity.

  • Measure key access skew and serialized payload size.
  • Split oversized records or cache a smaller projection.
  • Protect a hot key from concentrating all traffic on one shard.

Atomicity & messaging

Pipelining

Reduce network round trips for independent commands without assuming the batch becomes a transaction.

  • Batch independent commands to reduce network round trips.
  • Inspect each returned result for command-level errors.
  • Pipelining does not make the group atomic.

MULTI, EXEC and WATCH

Use Redis transactions and optimistic checks with an explicit response to concurrent modification.

  • Queue commands with MULTI and execute them with EXEC.
  • Use WATCH to detect concurrent changes before committing.
  • Redis transactions do not provide automatic rollback of runtime errors.

Lua scripts and functions

Move bounded atomic logic to the server without blocking it with expensive computation.

  • Keep server-side logic small and deterministic.
  • Use atomic scripts for read-modify-write sequences.
  • Bound loops and data sizes to avoid blocking the Redis server.

Locks and leases

Use unique ownership tokens and bounded leases; design for expiry while work is still running.

  • Acquire a lease with a unique ownership token and expiry.
  • Release only when the stored token still matches the owner.
  • Use fencing when stale owners could corrupt external resources.

Pub/Sub

Use transient broadcasting only where missed messages are acceptable or handled separately.

  • Publish messages to channels for currently connected subscribers.
  • Disconnected consumers do not receive a durable replay.
  • Choose streams or a queue when delivery tracking is required.

Rate limiting

Choose fixed-window, sliding-window or token-bucket semantics and update the state atomically.

  • Combine counters or sorted sets with an appropriate time window.
  • Make quota evaluation and updates atomic.
  • Scope keys to the authenticated subject and protected operation.

Redis operations

Memory limits and eviction

Select a maxmemory policy that fits the workload and monitor rejected writes or eviction churn.

  • Set maxmemory and an eviction policy that fits the workload.
  • Distinguish cache eviction from durability requirements.
  • Monitor memory fragmentation and rejected writes near capacity.

RDB and AOF persistence

Compare snapshot and append-log recovery tradeoffs instead of assuming in-memory data is durable.

  • RDB snapshots and AOF logs have different recovery trade-offs.
  • Configure persistence around acceptable data loss and restart time.
  • Test restoring backups instead of assuming persistence is sufficient.

Replication and failover

Understand replica lag and how failure recovery can affect recently acknowledged writes.

  • Replicas can lag behind the primary's acknowledged writes.
  • Plan client reconnection and role discovery after failover.
  • Understand that failover can lose writes not replicated in time.

Sentinel

Use monitoring and failover coordination for the supported primary-replica topology.

  • Sentinel monitors a non-clustered Redis primary and replicas.
  • Configure quorum and independent Sentinel instances.
  • Use Sentinel-aware clients to discover the current primary.

Redis Cluster and hash slots

Partition keys and account for cross-slot restrictions when designing multi-key operations.

  • Redis Cluster partitions keys across 16,384 hash slots.
  • Use hash tags when related multi-key operations need one slot.
  • Handle redirection and topology changes with a cluster-aware client.

Connections and pooling

Bound connection counts and choose clients appropriate to serverless or long-lived runtimes.

  • Reuse connections according to the client and deployment model.
  • Isolate blocking or subscription workloads when required.
  • Bound connection counts in serverless or highly concurrent applications.

ACLs and TLS

Restrict commands, key patterns and network access for each application identity.

  • Restrict users to required commands and key patterns.
  • Encrypt transport and verify the server's certificate.
  • Rotate credentials without exposing them in application logs.

Slow log and latency analysis

Separate command cost, network delay and connection saturation when diagnosing a slow cache.

  • Inspect slow commands alongside application-observed latency.
  • Check payload size, blocking scripts and network delays.
  • Profile representative workloads before changing server capacity.

Sources

  • Redis caching solutions official documentation

Ask follow-up questions on any topic in your dashboard.

Start learning