Redis Data Structures
Redis is often described as a key-value store, but the values are what make it powerful. Each key holds a typed data structure: a string, hash, list, set, sorted set, stream, and more. Each type comes with atomic server-side commands. Instead of fetching a blob, modifying it in your app, and writing it back, you tell Redis "increment this counter", "add this member with score 42", or "pop the next job". The operation runs atomically in memory in microseconds.
Choosing the right structure is most of Redis design. A leaderboard is a sorted set, a rate limiter is a string counter with a TTL, a job queue is a list or a stream, and a session is a hash. This page maps each type to its commands, costs, and typical uses.
TL;DR
- Strings: bytes up to 512 MB; counters (
INCR), cached blobs, locks (SET NX PX). - Hashes: field-value maps; objects like users and sessions, with per-field reads and updates.
- Lists: ordered sequences; simple queues (
LPUSH/BRPOP) and capped recent-items feeds. - Sets: unique unordered members; tags, membership tests, and set algebra.
- Sorted sets: unique members ordered by score; leaderboards, rate limiting windows, priority queues, time indexes.
- Streams: append-only logs with consumer groups; durable event processing.
- Specialized: bitmaps, HyperLogLog (approximate distinct counts), geospatial indexes, and JSON documents.
Quick Example
A leaderboard, a session, and a recent-activity feed:
Each command is atomic. Two clients calling ZINCRBY at once can't lose an update.
Core Concepts
Strings
The most basic type, binary-safe and holding text, serialized JSON, integers, or raw bytes.
Hashes
A map of fields to values under one key, ideal for objects:
Small hashes are stored in a compact encoding (listpack), so many small hashes are very memory-efficient. Redis 7.4+ also supports per-field expiration (HEXPIRE).
Lists
Linked sequences with O(1) pushes and pops at both ends. LPUSH + BRPOP makes a simple blocking queue; LMOVE moves an item to a processing list for at-least-once handling. Index access (LINDEX, LRANGE deep into the list) is O(n), so lists suit head and tail operations, not random access.
Sets
Unordered collections of unique strings with O(1) add, remove, and membership:
SINTER, SUNION, and SDIFF compute set algebra server-side. SRANDMEMBER and SPOP pick random members.
Sorted Sets
Each unique member has a floating-point score, and members stay ordered by it. Range and rank queries are O(log n + m). This is the most versatile Redis type:
- Leaderboards:
ZINCRBY,ZREVRANGE,ZRANK. - Time indexes: score = Unix timestamp, then
ZRANGE key min max BYSCOREfor "events in the last hour". - Sliding-window rate limiting: add a timestamped entry per request, trim old ones with
ZREMRANGEBYSCORE, count withZCARD. See rate limiting. - Priority and delayed queues: score = run-at time,
ZPOPMINthe next due job.
Streams
An append-only log of entries with auto-generated time-based IDs. Consumer groups let multiple workers share a stream with acknowledgements, pending-entry tracking, and redelivery, a lightweight Kafka-like model inside Redis. Details in Redis Pub/Sub & Streams.
Specialized Types
Keys and Expiration
- Naming: use a consistent colon-delimited scheme (
user:42:sessions,cache:product:991) so keys are readable and scannable. - TTL:
EXPIRE,SET ... EX, andPEXPIREmake keys self-cleaning. Expiry applies to the whole key (except hash fields withHEXPIRE). - Scanning: use
SCANwithMATCHto iterate keys incrementally.KEYS *blocks the server and must never run in production. - Atomic multi-step logic: combine commands with
MULTI/EXECtransactions or Lua scripts and Functions (EVAL,FCALL) when an operation spans several keys.
Best Practices
Pick the Structure That Matches the Query
Design from access patterns. If you need "top N by score", use a sorted set, not a serialized list you sort in the app. If you update single fields, use a hash, not a JSON string you rewrite whole.
Avoid Big Keys
A single hash, list, or set with millions of elements makes commands like HGETALL, DEL, or SMEMBERS block the single-threaded command loop and complicates cluster balancing. Shard large collections across keys (followers:42:0…followers:42:15), paginate with HSCAN/SSCAN/ZSCAN, and delete with UNLINK (asynchronous).
Set TTLs on Cache and Ephemeral Data
Anything that isn't a source of truth should expire. Keys without TTLs accumulate until memory fills and the eviction policy starts removing data you care about.
Pipeline Round Trips
Latency is usually network-bound. Send batches of commands with pipelining, or use variadic commands (MGET, HSET with many fields, ZADD with many members), to cut round trips dramatically.
Common Mistakes
Storing Objects as JSON Strings, Then Rewriting Them
Using KEYS in Production
KEYS pattern scans every key in one blocking call and can freeze a large instance for seconds. Use SCAN cursors, or maintain explicit index sets.
Using Lists as Reliable Queues Without Acknowledgement
RPOP removes a job immediately. If the worker crashes, the job is lost. Use LMOVE into a processing list, or Streams with consumer groups, which track unacknowledged messages.
FAQ
Which Redis data type should I use for caching?
Usually strings holding serialized values with a TTL. Use hashes when you frequently read or update individual fields of a cached object. See Redis caching patterns for strategies like cache-aside and stampede protection.
How much memory does Redis use per key?
Roughly 50–100 bytes of overhead per key, plus the value. Small hashes, sets, and sorted sets use compact encodings, so grouping many small values into hashes can dramatically reduce memory. MEMORY USAGE key reports the real size of a key.
Are Redis operations atomic?
Each individual command is atomic: Redis executes commands one at a time on its main thread. For multi-command atomicity use MULTI/EXEC (optionally with WATCH for optimistic locking) or a Lua script/Function, which runs without interleaving.
What's the difference between a set and a sorted set?
Both hold unique members. A set is unordered, with O(1) membership checks and set algebra. A sorted set attaches a score to each member and keeps them ordered, enabling rank and range queries at O(log n) cost per operation.
Related Topics
- Redis — The database overview
- Redis Caching Patterns — Using these structures as a cache
- Redis Pub/Sub & Streams — Messaging with Redis
- Data Structures — The underlying computer science
- Rate Limiting — Sorted-set and counter-based limiters