Tangible Bytes

A Web Developer’s Blog

Laravel Redis vs Memcached

I want to use a distributed cache in my Laravel Application to make the app more responsive and reduce database load.

I’m not sure whether to use Memcache or Redis

My general understanding is that these days Redis is “better” - has more functions while still matching memcache for performance.

Working with a more general purpose data store is also appealing as it may have more uses ver time and in other projects.

It looks like Laravel’s cache Facade makes all caches appear much the same.

Cache Tags

Looking at various blog posts I see use of “cache tags” and this is documented in older versions of Laravel

Cache tags are not supported when using the file, dynamodb, or database cache drivers. Furthermore, when using multiple tags with caches that are stored “forever”, performance will be best with a driver such as memcached, which automatically purges stale records.

https://laravel.com/docs/9.x/cache#cache-tags

Seems to favour Memcache

But this has been removed from the docs

“undocument cache tags due to complexity of implementation”

https://github.com/laravel/docs/commit/63dde39470588ab1ad39cea9a592f0838ca5ad47

and

Don’t suggest cache tags for Redis

https://github.com/laravel/docs/commit/1b40cbdc9f2b4c7c4beabfab7f41a5b4088d4ee8

and the upgrade notes say

Usage of Cache::tags() is only recommended for applications using Memcached. If you are using Redis as your application’s cache driver, you should consider moving to Memcached or using an alternative solution.

https://laravel.com/docs/10.x/upgrade#redis-cache-tags

So if I want to use cache tags I should use memcache ?

But the whole documentation note has been removed - which makes me feel like the functionality is entirely deprecated.

This repository offers both an explanation of the problems with the Laravel Redis cache tags implementation and a possible solution - but it seems quite old.

https://github.com/swayok/alternative-laravel-cache

What else does Redis offer

By default, the throttle middleware is mapped to the Illuminate\Routing\Middleware\ThrottleRequests class. However, if you are using Redis as your application’s cache driver, you may wish to instruct Laravel to use Redis to manage rate limiting

https://laravel.com/docs/12.x/routing#throttling-with-redis

There isn’t any clue here as to why you might want to use redis here instead of the database, nor why this functionality might be accessed via something like Memcache.

I assume it is more performant than the database option - important when database access is one of the things you want to throttle.

I also assume it uses the richer API and/or data types Redis offers to do something Memcache can’t do.

Memory leaks

Looking through various issues and commits I see there is a concern about memory leaks in the way Redis is used as a cache

It seems like this may be fixable with the right Redis config

Starting with Redis 4.0, the Least Frequently Used eviction mode is available. This mode may work better (provide a better hits/misses ratio) in certain cases. In LFU mode, Redis will try to track the frequency of access of items, so the ones used rarely are evicted. This means the keys used often have a higher chance of remaining in memory.

https://redis.io/docs/latest/develop/reference/eviction/#lfu-eviction

Decision

I don’t like this sort of choice where it looks like both options have limitations.

On the other hand it also looks like the cost of switching back is low.

I’m quite swayed by the fact that Laravel Sail supports Redis by default but not Memcache - and that likely indicates more people using Redis.

I think I’m going to use Redis and I’ll use the now undocumented cache tags - in a simplified form where I will only use one tag on any item.

My application hosts data for multiple sites so it wil be very useful to be able to clear the cache for one site at a time, other than that I think I can clear individual items.