> every time I need to do something slightly weird, there's a sensible and well thought out way to achieve it.

In my world cache systems like memcached and redis are just that, a cache to put and get from. Possibly use some invalidation system like tagging.

What can you do with a cache system that is 'wierd'? What are people doing with caches other than just caching data?

Genuinely interested.

Non-caching things I regularly see people do with Redis:

- Rate limits for API endpoints via the leaky bucket algorithm

- Feature flags and stats tracking

- Websocket pub/sub

- Background job queue

In general, lots of things that need to survive deploys (so they can't be in-memory in the app) and/or they need to be coordinated across multiple horizontally scaled servers and/or things that prefer to be in a data structure which is slightly awkward to stick in a database table.

No, you're right. Nothing crazy. But things like counting API usage across threads with INCRBY, or debounced HTML cache clears, or even an actual light db with persistence (AOF), and everything just working.

Can do fantastically weird stuff with Lua scripts in Redis/Valkey

We had Rails writing to memcached, and nginx pulling from memcached for full page caching.

At some point someone decided to gzip all writes into memcached, and our site looked really fun for a while.

I’ve done moving window rate limiting using redis to do atomic rate calculations etc.

That requires some weirdness

> moving window rate limiting

So does that mean you are tracking how many times data is being entered into redis, and rejecting it if the entry rate is too high?

Why would you not track this before, at the point of calculating the data to enter into redis, rather than querying redis to see how much data is entered in a given timeframe?

Again, genuinely curious as to the reason for architectural decisions.

Not GP, but I think they mean usecases like limiting how many times any given IP address can access an API to a certain amount of calls per minute. For example, you might want to restrict login attempts to at most 10 per minute per IP to prevent people trying out lists of common passwords.

This is fairly easy to do if your apps runs on a single server, but many companies run multiple servers and load balance requests among them. Those servers need some sort of coordination mechanism to keep track of the rate limits and their current state. Redis has dedicated instructions these days to do this, and in the old days there were plethora of libraries that use embedded Lua scripts to do the same thing.

Spot on! It was for a decently sized SaaS app; 10k+ request per minute & and a LOT of spam traffic from china a.o. we needed to limit. The app ran across 10+ servers, this is also why we put it in the app using redis and not with something like nginx rate limiting.

I don't exactly remember how i implemented it, but it basically did a single call to redis to count the request for the IP and check the limits.

Another usecase where the more advanced data types & operations of redis are usefull, is for job queues, since you can atomically move a job from the 'queue' to the 'processing' list, thus preventing loosing jobs if the processor crashes after pulling it orso. But we do run all those on persisted redis stores, for safety :)

And if i would do it all again, i'd probably just use postgres for anything i want to keep when things crash. Redis just kinda lives between a 'real' database and a pure volatile kv-cache