Why Redis is Fast
Redis routinely handles 100K–1M+ operations per second on modest hardware.
Introduction
Redis routinely handles 100K–1M+ operations per second on modest hardware. That speed comes from deliberate design choices, not magic.
Data lives in RAM, so there is no disk seek on hot paths. There is no SQL parser, query planner, or ORM. A single thread processes commands without lock contention on the keyspace.
Understanding why Redis is fast helps you avoid patterns that silently destroy performance — large values, O(N) commands, and chatty clients without pipelining.
Understanding the topic
Key concepts
- RAM access is ~100ns vs ~100µs for SSD — orders of magnitude faster for hot data.
- Single-threaded command processing eliminates lock overhead per key.
- Compact encodings (intset, listpack, embstr) reduce memory and improve cache locality.
- I/O multiplexing (epoll/kqueue) lets one thread serve thousands of connections.
- Pipelining amortizes network round-trip time (RTT) — often the real bottleneck.
- Simple data structures (hash table, skip list) give predictable O(1) or O(log N) behavior.
flowchart TBsubgraph disk["Disk DB path"]D1[SQL parse] --> D2[Planner] --> D3[Disk I/O]endsubgraph redis["Redis path"]R1[RESP parse] --> R2[Memory lookup] --> R3[Reply]end
Step-by-step explanation
- Client sends one or more commands over a persistent TCP connection.
- The event loop detects readable sockets and reads input buffers.
- Commands are parsed and dispatched to type-specific C functions.
- Memory is allocated via jemalloc/tcmalloc — tuned for small allocations.
- Results are buffered and flushed when the socket is writable.
- Background threads optionally handle AOF fsync, lazy free, and module work.
Syntax reference
Common commands
- redis-benchmark — rough local throughput test.
- Real bottlenecks are often network RTT and value size, not Redis CPU.
# Benchmark local throughputredis-benchmark -t set,get -n 100000 -q# Compare pipelined vs sequential (conceptual)# Without pipeline: N commands × RTT# With pipeline: 1 RTT + processing
Informative example
Pipelining 1000 GETs — one round trip instead of 1000:
List<Object> results = redis.executePipelined((RedisCallback<Object>) conn -> {for (int i = 0; i < 1000; i++) {conn.stringCommands().get(("key:" + i).getBytes());}return null;});
Without pipeline, 1000 commands at 1ms RTT ≈ 1 second. Pipelined ≈ 1ms RTT plus processing.
Real-world use
Real-world use cases
- Hot path API caching — every saved millisecond × millions of requests.
- Real-time counters — INCR on page views without DB row locks.
- Session lookup — O(1) GET/HGETALL on every HTTP request.
- Leaderboard updates — ZADD at gaming/sports scale.
- Rate limiting — atomic INCR with microsecond accuracy.
Best practices
- Use pipelining or MGET/HMGET for bulk reads.
- Keep values under ~1MB; split large payloads.
- Prefer O(1)/O(log N) commands — avoid KEYS, SMEMBERS on huge sets.
- Co-locate app and Redis in the same AZ to cut RTT.
- Use connection pooling (Lettuce) — do not open a new TCP per request.
- Disable transparent huge pages on Linux Redis hosts.
Common mistakes
- Sending commands one-by-one over WAN without pipelining.
- Using KEYS * or SMEMBERS on production keyspaces.
- Storing multi-MB JSON blobs — blocks the event loop during read/write.
- Assuming more CPU cores speed up one Redis instance (single-threaded command path).
Advanced interview questions
Q1BeginnerWhy is Redis faster than MySQL for reads?
Q2BeginnerIs Redis multi-threaded?
Q3IntermediateWhat is pipelining?
Q4IntermediateWhat slows Redis down in production?
Q5AdvancedHow would you diagnose latency spikes?
Summary
Speed = RAM + simple structures + single-threaded command path.