Redis caching and data structures
An in-memory store used for the jobs a primary database handles badly — caching, sessions, queues and counters.
In-memory store
Chosen per project
Maintainable handover
Redis is rarely the main database and is not meant to be. It is what you put in front of one: caching expensive query results, holding sessions, backing job queues, and counting things at a rate that would otherwise hammer your primary store.
The discipline that matters is deciding what happens when it is empty. A cache is an optimisation, and an application that breaks when Redis restarts has made it a dependency by accident.
What we build with Redis
Caching expensive query results and rendered fragments
Session storage shared across several application servers
Rate limiting and abuse protection
Job queues for background work
Where it fits — and where it does not
Good fit when
Repeated reads of data that changes slowly
Sessions that must be shared across instances
Counters and leaderboards updated frequently
Queue-backed background processing
Consider something else when
As a primary store for data you cannot lose
Datasets far larger than available memory
Complex queries and reporting — that is a database's job
How a cached read should behave
The important property is the miss path. Handled this way, losing the cache entirely costs performance and nothing else.
Request
Application needs a value.
Check cache
Look in Redis first.
Miss
Not there — fall through to the database.
Populate
Write the result back with an explicit TTL.
Serve
Return it; subsequent reads hit the cache.
Invalidation returns to the start: when the underlying data changes, the key is cleared.
How we work with Redis
Cache-aside
The application reads through and populates on a miss, so an empty cache is slow rather than broken.
Deliberate invalidation
Explicit keys and TTLs agreed up front — stale cached data is worse than none.
Persistence chosen
AOF or RDB selected against how much loss is acceptable, rather than left at defaults.
Memory policy
An eviction policy and memory limit set explicitly, so the instance degrades predictably.
Our typical Redis setup
| Concern | What we use |
|---|---|
| Deployment | Managed Redis, or self-hosted with replication |
| Caching | Cache-aside with explicit keys and TTLs |
| Sessions | Shared session store across application instances |
| Queues | BullMQ, Sidekiq or Laravel queues depending on the stack |
| Persistence | AOF or RDB chosen against acceptable data loss |
| Memory | Explicit maxmemory and eviction policy |
Frequently asked questions
It removes repeated work — expensive queries, recomputed pages, session lookups. It does nothing for a slow query running for the first time, so index the database first and cache second.
With cache-aside, the application falls back to the database and runs slower. If it errors instead, the cache has become a dependency — which is a design problem worth fixing.
Only for data you can afford to lose or rebuild. It persists to disk, but it is memory-first by design, and datasets bigger than memory do not fit that model.
Services built with Redis
Cloud Solutions
Hosting designed around what your application actually needs, with the monitoring and backups that make it safe to rely on.
Web Application Development
Applications that run in the browser, handle real workloads and hold up when several departments depend on them at once.
SaaS Development
Building a software product means building a business system around it too — tenancy, billing, onboarding and support tooling.
Software Maintenance
Keeping working systems working — including ones built by somebody else.
Tell us what you are trying to build
Describe the problem in plain language and we will tell you what it would take to solve it — the approach, the moving parts and the sensible order to build them in. No obligation either way.