Redis for .NET Developers: Not Just Caching — Data Structures That Change System Design
Ask a .NET developer what Redis is, and the answer is usually:
“A distributed cache.”
That answer is technically correct, and architecturally incomplete.
Redis is not a faster dictionary you put in front of your database.
Redis is a server-side data structure engine, and once you start using it that way, your application designs change.
This article is the first in a Redis-focused stream for .NET developers. We’ll cover:
-
why Redis is fundamentally different from relational databases
-
how each structure changes how you model problems
-
TTL and eviction patterns that actually work in production
This is not a Redis command reference.
This is about thinking differently.
Why Redis Feels “Too Simple” at First
Redis:
-
runs entirely in memory
-
exposes primitive operations
-
avoids joins, queries, and schemas
To SQL-trained developers, this feels limiting.
In practice, it’s liberating.
Redis forces you to:
-
design explicit read models
-
move logic closer to data
-
accept eventual consistency where appropriate
And in return, it gives you:
-
predictable performance
-
structures tuned for specific problems
The Mental Shift: From Tables to Data Structures
In SQL, you ask:
“How do I query this data?”
In Redis, you ask:
“What operation do I need to be fast?”
That question determines the structure.
Strings: More Than Just Key–Value
Redis strings are binary-safe values up to 512 MB.
Use cases
-
cache entries
-
counters
-
serialized payloads
Example: atomic counters
No locks. No race conditions. Atomic by default.
JSON payloads (simple case)
Strings are the foundation — but rarely the best final form.
Hashes: Redis as a Document Store
Hashes store field–value pairs under one key.
Why hashes matter
-
partial updates
-
memory efficient
-
ideal for read models
Example: user profile
Read one field without deserializing everything:
Design insight
Hashes often replace:
-
small SQL tables
-
JSON blobs that change frequently
Sets: Unordered, Unique Collections
Sets enforce uniqueness automatically.
Use cases
-
memberships
-
permissions
-
feature flags per user
-
deduplication
Example: user roles
Check membership:
Why this changes design
No join tables. No indexes. No locking.
Sorted Sets: Where Redis Really Shines
Sorted sets (ZSETs) associate each member with a score.
Use cases
-
priority queues
-
scheduling
Example: leaderboard
Top 10 users:
Time-window pattern
Then trim old entries:
This replaces entire SQL queries.
Lists: Simple Queues (With Caveats)
Lists are ordered sequences.
Use cases
-
simple queues
-
task buffers
-
logs
Example
Lists work — but for serious eventing, Redis Streams are better.
Streams: Redis as an Event Log
Streams are append-only logs with IDs and consumer groups.
Why streams matter
-
persistent
-
replayable
-
support multiple consumers
-
built-in backpressure
Append event
Consumer groups enable:
-
retries
-
exactly-once-ish processing
Streams are critical for CDC and event-driven architectures.
TTL Patterns: Where Most Redis Bugs Live
TTL is simple — until it isn’t.
Basic TTL
Pattern 1: cache-aside
-
read from Redis
-
on miss, load from DB
-
write back with TTL
Pattern 2: sliding expiration
Pattern 3: negative caching
Cache “not found” to prevent DB hammering:
Eviction Is Not Expiration
This is a common misunderstanding.
-
TTL: key expires predictably
-
Eviction: Redis removes keys under memory pressure
Your app must tolerate:
-
missing keys
-
unexpected evictions
Redis is a performance layer, not a source of truth.
Key Naming: The Hidden Design Tool
Good Redis usage lives or dies on key design.
Recommended pattern
Example:
This:
-
supports multi-tenancy
-
enables bulk deletes
-
improves observability
Redis vs PostgreSQL: Not Either/Or
Redis excels at:
-
fast reads
-
counters
-
ephemeral state
-
coordination
-
eventing
Postgres excels at:
-
durability
-
complex queries
-
transactions
-
reporting
The best systems use both.
Summary: Redis Changes How You Think
Once you stop treating Redis as “just a cache”, you start:
-
modelling problems differently
-
removing unnecessary queries
-
simplifying application logic
-
embracing explicit read models
Redis doesn’t replace your database.
It replaces accidental complexity.

Comments
Post a Comment