---
title: "Buttondown no longer runs Redis"
date: 2026-05-15
tags: post
---

Buttondown no longer runs Redis!

I added it years ago for the same reason almost every Django app has Redis: that's just what you do. Workers wanted a queue, the queue wanted a broker, the broker was Redis. The cache wanted a backend, the backend was Redis. Sessions wanted a store, the store was Redis. And then it festers from there. [^1]

I wrote [[postgres-jobs|earlier this year]] about pulling django-rq and the worker queue off of Redis. What was left after that was mostly small: rate-limit counters, a few short-TTL caches, an idempotency-key fast-path, and session storage. Not enough to really cause any issues, *but* we're working on our Heroku migration [^2], and big infrastructural changes are made slightly easier by one fewer dependency, even if it's a fairly static one.

When I actually measured the replacements against production Postgres, they came in well under the Redis round-trip they were replacing, which has to cross AWS regions to reach our RedisCloud instance. The "fast in-memory store" was, in this configuration, slower than the database itself. (Thanks, [[planetscale|PlanetScale]]!)

The few caches that didn't have a good home in Postgres became per-process in-memory dicts. We deploy enough times a day that a process-local cache lives long enough to do its job and gets cleared often enough that staleness isn't meaningfully real.

When I wrote [[difficulty-scores|yesterday about maintenance costs]], this is exactly the kind of thing I had in mind. It is both wild and accurate to say that the Buttondown stack, as of right this second, is dramatically simpler — let alone more stable — than it was two years ago.

[^1]: Though "festers" is unkind: I have no qualms with Redis as a technology, I just have qualms with twice as many datastores as I ought to have.

[^2]: Stay tuned for more.
