Skip to content

Data

Redis

An in-memory store for cache, sessions, queues and rate limits on builds that run on conventional servers.

Redis keeps data structures in memory and answers in well under a millisecond. Strings, hashes, sorted sets, streams, plus scripting so a read and a write can be one atomic operation. It is not where you keep the truth. It is where you put things you can afford to lose, plus a few things you cannot lose that you have decided to be careful about.

How we use it

Consonas points Laravel's cache, session and queue drivers at Redis through Predis, which is the standard arrangement in that framework and means a signed-in session, a queued job and a cached report all sit in the same service. That is convenient and it is also the arrangement that needs the most care, for reasons below.

Starterflare uses Redis 7 through ioredis for caching and rate limiting alongside its Postgres 16 database, and the continuous integration workflow brings up both as service containers so tests run against the real thing rather than a fake.

What it costs you

It is another stateful service that bills whether or not anybody is using your product. In Starterflare it was one of four, next to Postgres, OpenSearch and NATS, all of them needing to be up before the first user arrives. We worked through what four stateful services cost at rest, and for a product with no users yet that number is the whole argument.

Memory is the resource, and the eviction policy is the setting people get wrong. Put sessions and cache on one instance under allkeys-lru and a burst of cache writes will evict session keys, which signs your users out for no reason anybody can reproduce. Separate instances, or at minimum separate logical databases with a noeviction policy on the one holding sessions.

Durability is a choice with no free option. Snapshots lose everything since the last save, append-only logging costs write throughput and still has a fsync window. A job queue on Redis inherits whichever you picked, so "we lost an hour of queued emails" is a configuration decision made months earlier.

Redis executes commands on a single thread. One KEYS scan over a large keyspace, or a Lua script that turned out to be slower than expected, blocks every other client for the duration. And if you later move to cluster mode, multi-key operations only work within a hash slot, so the neat rate limiter script written for a single node needs rewriting.

When we would choose something else

On a Cloudflare build we would not add Redis at all. Cached values and sessions go in key-value storage, which is already global and needs no instance. Background work goes through Queues and scheduled jobs with a dead letter queue and retries handled for us. Counters and rate limits, the thing Redis is genuinely good at and KV is genuinely bad at, go to a Durable Object: DMARC Engine runs its rate limiter that way, because one object is a correct counter and an eventually consistent cache is not. Where a conventional server stack is already in place, Redis stays, since replacing it usually means replacing the framework's idea of how caching works.

Where we have used it

Every build below lists this in its stack, so the claim is checkable.