Personally I'd use memcached or some equivalent for strictly cacheing, and then bring on Redis with persistence if you need its data structures for e.g scoreboards.
At $WORK we never imported either, our cache layer for slow operations keeps its data in both the filesystem and a db table (used as a k/v store). The database helps coordinate thundering herd problems - this operation is being calculated by another thread, so just wait for it. Reads from the same server just hit the filesystem, and reads from another server hit the db once and then keep it in the filesystem. We could change the fs layer to memcached but so far it's working great.
* Outages where Valkey had no memory policy, ate all the memory, and then caused write errors to its append-only file. Bonus points for another one where the disk itself was full, and AOF writes failed.
* 500s where Redis was fully expected to be live, running, and populated with data for every user, and no fallback to a slower path.
* Creative uses of sorted sets and other data structures which depended on the sets never being evicted.
Despite the observations from the field, I think it's still hard to recommend memcache ahead of Redis. It can be difficult to architect an app to have a memcache-friendly cache layout.
I'd almost guarantee a large enough team using memcache will find a way to need Redis. And then we're maintaining 2 cache technologies.
More features mean more users. Some stick to the old stuff, some embrace the new, and eventually certain values become the de facto default, not really optional anymore.
Take Redis. Turn off AOF and it works as a volatile in memory cache. But most of us don't even think about it that way. So there is this argument that fewer features and simpler is better.(Memcached is such an example in this context) The so called 'straitjacket' approach. That makes total sense for big teams. But on the other hand, open source projects need regular updates to keep getting funding or contributions, so there is a built in tension.
And sometimes that leads to specialized forks or spin offs that excel in one niche area. My personal take? There is no right answer. It all depends on the context. Communication itself isn't free, after all
The comparison is especially weird as memcached is also not persistent.
Perhaps that's because I'm not giving admin access to random people who think that Redis is a persistent storage, but honestly it's one of those technologies I'd describe as absolutely rock solid and well designed. The API is dead basic and every time I need to do something slightly weird, there's a sensible and well thought out way to achieve it.
Just trying to get a sense of where people draw the line.
Never felt the need to go back to memcached except when a legacy dependency needed it.
1) Wrap your client library so that it's impossible to store anything without an expiry date. You don't want 6-months-old data suddenly coming up in your app!
2) Either turn off persistence, or use a separate database for the cache. In other words, don't mix volatile data with stuff you actually care about.
3) Set up a reasonable maxmemory value with an appropriate maxmemory-policy, so that Redis doesn't eat up all your RAM.
4) Resist the urge to use complex data structures. If you try to update a single field on an expired hash, you will end up with an incomplete object.
If you don't want all that hassle, then yes, Memcached probably works better out of the box.
> Dealing with memcached downtime is incredibly easy, because client libraries generally ignore connection exceptions. For instance, a simple get will just return the default value (or none) if the server is down.
This is a terrible idea in the context of things that might use Redis. If you use Redis with some kind of complex state (say, a document if you're working on a Notion clone, for instance), wtf even is a "default value"? In fact, I actually also want to know when the thing is down.
> Clustering memcached is wonderful, because memcached actually has no clustering built-in.
Yeah bro, this is yet another one of the reasons people use Redis: it handles consensus and clustering for you. What even is this article? It's a master class in straw-manning architectural decisions: most people use hammers as hammers, but screwdrivers make great hammers too, especially if you also need to screw stuff in! I mean.. technically true?
This so much. (Ab)Using a db table as a k/v store + the FS can do so much before even considering paying the price of setting up a dedicated caching store. I’ve fought countless foes in the engineering world when proposing solutions like yours just because (incompetent) people feel like caching should live in its dedicated store.
Redis was definitely more featureful, and antirez is both an engaging character and admirably humble, so I can see why redis overtook it in popularity - but, for me, memcached has always been the pinnacle of "choose boring technology".
As a platform engineer, I'm happy to support either - but when developers start using some of the more advanced redis features (persistence, replication, clustering), I try to make sure that they've fully understood the downsides of that decision.
Honestly designing your app to have a "memcache-friedly cache layout" is the same thing as designing it to have a redis-friendly cache layout. The pattern for this kind of application cache is identical: "get, and if not there, calculate and set".
I think that’s because people replaced Memcached with Redis, and expect the same from it.
Off topic, but that's my problem with microservices, devs seem to be totally unaware of this.
What do you think of the argument made in the article?
No need for this client-side complexity, as you should be using `allkeys-lru`. FWIW, should likely be doing this anyway, as (generally speaking) all data stored in Redis is usually regarded as volatile because of what Redis actually is.
Considering how complex and error prone this is, I don’t want it in my stack.
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.
Ultimately though, regardless of whether you’re experience is true for the wider industry or not, if you’re letting a junior dev who refuses to read product documentation the responsibility of architecting production systems, then your problem isn’t Redis.
It's not bad enough where I had to pull it from the old project that used it, but going forward the new ones used a vibecoded queueing system that was genuinely more reliable than Celery but consumed a lot of memory (RSS inflation). Have then shifted to rq and at least for now it seems to "just work". You're better off doing anything custom/complex (like dependencies, or progress updates across multiple tasks) directly yourself in Redis anyway; since half the time Celery's less-well-trodden inbuilt features don't work the way they should anyway.
At some point someone decided to gzip all writes into memcached, and our site looked really fun for a while.
The most common first thing to cache is getting the current user, because this ends up being a very hot path for most stateless systems. Because you need to get the current user for almost every request, it's quite easy for getting the current user to be 50% of database load: first you get the user, then you do the thing. tada, user lookup is now half your app by volume
Clustering redis is not that hard even if you do it manually and I have only had to do it once.
I never use redis persistence and have a max size set with LRU or whatever the application requires.
With memcached I remember having to mess around the LD_LIBRARY path to link whatever python module I was using at the time
The article mentions the default value is a null, which would be the cue to run whatever computationally expensive op or query the db or hit the disk etc... that you would normally run if you had no cache to begin with.
> but screwdrivers make great hammers too
I don't know what your screwdrivers look like but that sounds like a rough time.
“Anyways, Redis homepage aside, you deploy it, and off you go - your trusty cache. You hand the connection string to the people who asked for it, and off you go.”
That requires some weirdness
Have you ever used Redis before? I've literally never had to manage clustering or had any issues with it, and I've been using Redis for like 15 years (including for games where state had to live in multiple regions and could change on a 30- or 60-tick basis).
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.
If you know this already, then you didn't need to read OP or any of this thread. :)
The problem is that Redis tries very hard to position itself as a persistent data store, with defaults that lean toward persistence (no default eviction policy). Beginners need to fight these defaults every step of the way if all they want is a cache.
at notion we use redis for a lot of things, but actual caching we leave to memcached
It works pretty well when you need to hit something with a solid object a couple times.
“None of these things are impossible with Redis, it’s just that memcached’s architecture in general more leans towards these directions, which makes it much, much more straightforward from an operations point of view.”
What are you talking about? On their website, the top 3 use cases (under the Platform menu) are: caching, streaming, and session management. Literally all of these three are volatile.
Mature ops would be tracking cache hit ratios right?
It sounds like memcached would be really good in a use case where you really just need an optional stateless pure cache with absolutely zero rope to hang yourself on. A use case where "cache hit ratio" is the goal, not "fiddly in-memory data store".
Sure, and sentry integrates well with redis in python which is what I use primarily with redis.
I don't think memcached is bad, I just think its old and industry has moved to redis because it offers more while covering the previous use case.
Calling redis fiddly is a mischaracterization. For many use cases I have not had to think more than 30s to setup redis.
(also when I say redis I mean Valkey at this point, even if they are starting to diverge)
Does your argument assume you already have a database, so you might as well use it for your cache mechanism?
APCu count=1000 min=0.000290 avg=0.000318 p50=0.000320 p95=0.000331 max=0.000992 ms
Memcached count=1000 min=0.032422 avg=0.039714 p50=0.037211 p95=0.053261 max=0.091343 ms
MariaDB count=1000 min=0.015680 avg=0.019541 p50=0.018485 p95=0.023855 max=0.103867 ms
Don't even start a socket if possible.Now then do a traceroute. Even to my router it costs 0.547 ms but that's only 1 direction. And a cloud space is hosting many servers, many routers, many switches, with lots of moving pieces so you're realistically adding 1.1 ms per subnet hop and in pretty much every data center that's probably 3-5 hops inside the LAN.
It is more sophisticated than grab memory per item.
This helped be to understand it better - https://vectree.io/c/memcached-internals-slab-allocation-lru...
If you happen to find yourself in a sysadmin position, or a position where you just so happen to maintain someone’s infrastructure, chances are that at some point in time the topic “we need a cache” comes up.
You think for a moment and reach out for Redis, because you’re used to it, it’s fully featured, and it works! You remember it being a good, solid cache, and you wonder which new features recent releases have brought, and head to its homepage:
Your agents aren’t failing. Their context is.
Inquiring agents want to know:
How can I use Redis Iris as a real-time context engine for AI apps?1
Right, so probably something with AI2. This is sort of understandable, because Redis is a company that wants to make money.
Anyways, Redis homepage aside, you deploy it, and off you go - your trusty cache. You hand the connection string to the people who asked for it, and off you go.
After a while, it turns out that cache.set("key", "value") is a really simple abstraction, and definitely easier than INSERT INTO table VALUES ('key', 'value'). People start treating the REmote DIctionary Server as something that’s always there, something that persists data, something that is a database.
You don’t know this. Your ops colleagues don’t know this. Therefore, your alerting doesn’t know this either, because you assume that people treat the cache as something volatile.
You find out that this has been going on when you happen to do something to Redis. Maybe you upgrade it, maybe you move it to another node, maybe your cat hits the eject button on your RAID0 server’s HDD tray.
The issue isn’t that Redis doesn’t have persistence, the issue is that usually, Redis is brought into a stack as a cache, and it is run with the assumption that people treat it that way.
Usually, by the time you realize this, it is already too late, and Redis is too intertwined in the app to really leave its place. Instead, you have the eternal pleasure of maintaining it and monitoring it like a pet.
First off - what’s a memcached? Easy, ask its website:
What is Memcached?
Free & open source, high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.3
Wow, first sentence on the page, even with code examples. And look at those cute little mascots at the top!
Memcached is also a cache, similar to Redis. Chances are that you’re using a framework like Django, which supports pluggable caching and allows you to switch between different caching backends.
But why should you use memcached when it has much less features than Redis? Here are my reasons for why these days, I will always prefer memcached over Redis:
Dealing with memcached downtime is incredibly easy, because client libraries generally ignore connection exceptions. For instance, a simple get will just return the default value (or none) if the server is down.
Clustering memcached is wonderful, because memcached actually has no clustering built-in. To “cluster” it, you configure the client library with multiple URLs4, and the client will select the target instance based on hashing the key. If a client-side call detects an instance as done, it removes the node from the hasher. After a certain time, the client will automatically attempt to reconnect and use the dead node.
memcached “solves” the whole persistence issue, because it does not persist to disk. It is therefore a perfect fit to just being scheduled as a stateless workload wherever you desire it.
None of these things are impossible with Redis, it’s just that memcached’s architecture in general more leans towards these directions, which makes it much, much more straightforward from an operations point of view.
But because of memcached being such a relatively simple application (plus the fact that you can run dozens instances of it with ~64 MB cache size and close to no overhead), if I need a cache these days, I usually reach out to memcached.
That said, a lot of “database too slow” problems actually begin their life as “query too slow” or “missing indices”, so be a kind person and help your developers with optimizing their queries.
Also, if you’re curious about some of the decisions behind memcached, the blog contains interesting posts, with one published just in May: “How Long Does That Response Take… For Real?”.
https://redis.io/, accessed 2026-06-02 ↩︎
That said, https://redis.io is probably not the best entrypoint for engineers, that website seems geared to people making purchasing decisions. ↩︎
https://memcached.org, accessed 2026-06-02 ↩︎
Bonus points for using a service discovery mechanism to automatically generate this setting. ↩︎