
September 07, 2026
12 min read
By Kokil Thapa | Last reviewed: September 2026
Laravel cache tags with Redis vs Memcached is not an academic choice—it determines whether you can invalidate a whole slice of application cache without flushing everything or hard-coding key lists. On production Laravel applications I maintain, tagged caching keeps category pages, permission snapshots, and API response fragments consistent after a single model update. The catch: not every cache driver supports tags, and Redis and Memcached behave differently once traffic, clustering, and persistence enter the picture. This guide walks through how Laravel implements tags on each backend, what breaks in real deployments, and which option I reach for on Laravel 13 with PHP 8.3 or higher.
If you are new to application-level caching in Laravel, start with the fundamentals in Redis caching for Laravel PHP applications before layering tags on top. Tags solve a specific problem—group invalidation—not raw speed alone.
What are Laravel cache tags and why do you need them?
Cache tags let you label cached entries and flush every entry sharing a label in one call. Without tags, you either maintain a manual registry of keys or call Cache::flush(), which evicts unrelated data and spikes database load on the next request wave.
A typical pattern on an eCommerce or directory site:
- Tag product listing fragments with
productsand per-category tags likecategory:12. - Tag user permission caches with
user:45androles. - Tag CMS block output with
page:aboutso a content edit clears only affected pages.
Laravel exposes tags through the same facade regardless of driver:
use Illuminate\Support\Facades\Cache;
Cache::tags(['products', 'category:12'])->put(
'products.category.12.page.1',
$html,
now()->addHours(6)
);
Cache::tags(['products', 'category:12'])->flush();
Under the hood, Laravel stores tag metadata separately from the cached value. When you flush a tag, the framework resolves all keys associated with that tag and deletes them. That indirection costs a little memory and CPU compared to plain key-value caching, but it saves hours of brittle key-tracking code. For architectural context on where caching sits in a modern stack, see modern Laravel architecture best practices.
Does Memcached support Laravel cache tags like Redis?
Yes—both Redis and Memcached are among the drivers Laravel documents as supporting tags, along with array (tests) and DynamoDB. File and database drivers do not support tags; attempting Cache::tags() with them throws a runtime exception.
The API surface is identical. The differences show up in operations, limits, and infrastructure:
| Criteria | Redis (8.10) | Memcached (1.6.x) |
|---|---|---|
| Tag support in Laravel 13 | Yes — first-class production choice | Yes — works on single node; cluster caveats |
| Persistence | RDB snapshots, AOF optional | Purely volatile (data lost on restart) |
| Tag flush cost at scale | Moderate; SCAN-friendly workflows | Moderate; large tag sets can lag |
| Multi-node / cluster | Redis Cluster with known hash-slot rules | Client-side hashing; tag metadata must stay coherent |
| Beyond caching | Queues, locks, broadcasting, sessions | Caching only |
| Typical hosting cost | Slightly higher RAM footprint | Lean for simple object cache |
| Verdict for tagged Laravel apps | Recommended default | Legacy or specialised Memcached-only stacks |
On a legal-tech portal where document lists and permission caches must invalidate together after an upload, I default to Redis so one infrastructure component also handles Laravel real-time features with Redis and session storage when needed. Memcached remains valid if your platform team already operates Memcached 1.6.x pools and your Laravel app only needs object caching—nothing more.
For deeper persistence and failover trade-offs, read Redis persistence and clustering before committing to a production topology.
How do you configure Laravel cache tags with Redis?
Laravel 13 expects PHP 8.3 or higher. Install the PHP Redis extension or use Predis via Composer—extension-based phpredis is faster under load.
Install and verify the Redis extension
sudo apt install php8.5-redis
php -m | grep redis
composer require predis/predis
Set the cache driver in .env
CACHE_STORE=redis
REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
Confirm config/cache.php
'default' => env('CACHE_STORE', 'database'),
'stores' => [
'redis' => [
'driver' => 'redis',
'connection' => env('REDIS_CACHE_CONNECTION', 'cache'),
'lock_connection' => env('REDIS_CACHE_LOCK_CONNECTION', 'default'),
],
],
Keep cache connections separate from queue connections in config/database.php so a runaway queue worker cannot evict hot cache keys:
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'port' => env('REDIS_PORT', '6379'),
'database' => 0,
],
'cache' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'port' => env('REDIS_PORT', '6379'),
'database' => 1,
],
],
Smoke-test tagged writes
php artisan tinker
Cache::tags(['demo'])->put('tagged-key', 'hello', 60);
Cache::tags(['demo'])->get('tagged-key');
Cache::tags(['demo'])->flush();
Official reference: the Laravel 13 cache tags documentation lists supported drivers and method signatures. Redis server docs at redis.io cover memory policies that interact with eviction when RAM fills.
Server hardening—firewall rules, memory caps, persistence files—belongs in your deployment checklist alongside application config. For Ubuntu production setups I handle regularly, see Linux system administration for production Laravel hosting.
How do you configure Laravel cache tags with Memcached?
Switching drivers is mostly an environment change—your tagged call sites stay the same. That portability is the main reason teams prototype with array in tests and deploy with Redis or Memcached.
Install Memcached and the PHP extension
sudo apt install memcached php8.5-memcached
sudo systemctl enable --now memcached
Point Laravel at Memcached
CACHE_STORE=memcached
MEMCACHED_HOST=127.0.0.1
MEMCACHED_PORT=11211
In config/cache.php, the Memcached store accepts SASL credentials and custom server weights:
'memcached' => [
'driver' => 'memcached',
'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
'sasl' => [
env('MEMCACHED_USERNAME'),
env('MEMCACHED_PASSWORD'),
],
'options' => [
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
],
'servers' => [
[
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
'port' => env('MEMCACHED_PORT', 11211),
'weight' => 100,
],
],
],
Reference the Memcached protocol behaviour in the official Memcached documentation when tuning connection pools.
Operational caveats specific to Memcached
- Restarts evict everything. Unlike Redis with optional persistence, Memcached loses tagged metadata and values on process restart—plan warm-up jobs after deploys.
- Multi-node consistency. Laravel’s tag implementation stores reference keys. If clients hit different Memcached nodes with inconsistent key routing, tag flushes may miss entries. Use a single pool with consistent hashing or keep tag-heavy workloads on one logical cluster.
- Item size limit. The default 1 MB item cap applies to tagged payloads; large HTML fragments may need compression or fragment splitting.
- No secondary use. You still need Redis or the database for queues, locks, and sessions—Memcached rarely consolidates infrastructure the way Redis can.
When auditing an existing Memcached deployment, I log tag flush duration during staging load tests before signing off—a slow flush under write-heavy catalog updates is a signal to migrate hot tags to Redis. Performance tuning as a service line is covered under testing and optimization for Laravel applications.
How do you flush cache by tag safely in production Laravel apps?
Tag design matters as much as driver choice. Treat tags as part of your domain model, not ad-hoc strings scattered through controllers.
Centralise tag names
namespace App\Support;
final class CacheTags
{
public static function products(): array
{
return ['products'];
}
public static function category(int $id): array
{
return ['products', 'category:'.$id];
}
public static function user(int $id): array
{
return ['user:'.$id, 'permissions'];
}
}
Flush from model events
protected static function booted(): void
{
static::saved(function (Product $product) {
Cache::tags(CacheTags::category($product->category_id))->flush();
});
static::deleted(function (Product $product) {
Cache::tags(CacheTags::products())->flush();
});
}
Guard against stampedes with locks
$key = 'products.category.'.$id;
$tags = CacheTags::category($id);
$value = Cache::tags($tags)->get($key);
if ($value === null) {
$value = Cache::lock('build-'.$key, 10)->block(5, function () use ($key, $tags) {
return Cache::tags($tags)->rememberForever($key, fn () => $this->renderCategory());
});
}
On API-heavy projects, pair tagged HTTP caching with the guidance in Laravel API best practices so ETags and application cache layers do not fight each other. For database-heavy rebuild paths, index tuning often matters as much as cache—see PostgreSQL for Laravel developers when PostgreSQL 18 backs your app.
Projects like Nepal Gift Card and Adventure Third Pole Trek rely on predictable cache invalidation because stale inventory or booking availability is a revenue problem, not a cosmetic glitch. Tagged flushes are how you keep that correctness without nightly full clears.
When should you choose Redis over Memcached for Laravel cache tags?
Use this decision frame before provisioning infrastructure on a greenfield Laravel 13 project:
- Choose Redis when you need tags plus queues, rate limiting, locks, Horizon metrics, or broadcasting; when you want optional persistence; when one managed service should cover multiple Laravel subsystems.
- Choose Memcached when your organisation already runs a mature Memcached 1.6.x fleet, workloads are strictly read-heavy HTML fragments, and losing cache on restart is acceptable.
- Avoid tags on file/database drivers—refactor to Redis or Memcached instead of bolting on manual key lists.
- Re-evaluate during cluster upgrades—Redis Cluster and Memcached pools both need validation that tag flushes reach every referenced key.
Cost-wise, a small dedicated Redis instance on a Rs 3,000–5,000/month VPS slice (~USD 22–37) often replaces separate Memcached plus auxiliary Redis installs, simplifying GitLab CI/CD deploy pipelines I run on shared EC2 infrastructure. Page-speed work still needs front-end and query optimisation—caching alone will not fix N+1 queries; combine tagged caches with speed optimization and technical SEO when public pages must pass Core Web Vitals.
Enterprise applications with complex domain rules benefit from upfront cache design during planning—enterprise application development engagements should document tag vocabulary alongside database schema. If you inherit a site with mystery flush scripts, support and maintenance is often the fastest path to map existing keys before migrating drivers.
Debugging tag metadata during incidents is easier when you can inspect JSON payloads—keep a JSON formatter handy in staging while comparing cached API responses to live database rows. For public-facing Laravel sites, align cache TTLs with SEO crawl patterns described in SEO setup for Laravel sites.
Key Takeaways
- Laravel cache tags work on Redis and Memcached, not on file or database drivers—plan your infrastructure accordingly.
- Redis 8.10 is the default choice for Laravel 13 tagged caching because it also covers queues, locks, and optional persistence.
- Memcached 1.6.x supports the same tag API but is volatile and sensitive to multi-node routing during tag flushes.
- Centralise tag strings, flush from model events, and use cache locks to prevent thundering herds after invalidation.
- Separate Redis logical databases or connections for cache versus queues to avoid cross-traffic eviction.
- Load-test tag flush duration before peak traffic—slow flushes are a migration signal from Memcached to Redis.
People Also Ask
Can Laravel cache tags work with the file driver?
No. Laravel throws an exception if you call Cache::tags() while the default store is file or database. Switch CACHE_STORE to redis or memcached, or refactor to untagged keys with explicit TTLs if you cannot add a network cache yet.
Do cache tags slow down Laravel?
Tagged writes carry a small metadata overhead compared to plain Cache::put(). Reads are comparable. The performance cost shows up during large tag flushes under write-heavy load—measure in staging, not assumptions. Correctness from targeted invalidation usually saves more database time than metadata costs.
Are Laravel cache tags safe with Redis Cluster?
They can be, but all tag-related keys must land on nodes your client can reach consistently. Test flush operations after enabling cluster mode. Many teams run a non-clustered Redis instance dedicated to cache while clustering queue workloads separately.
Should tests use tagged caching?
Yes—use the array driver in phpunit.xml. It supports tags, resets between tests, and avoids needing Redis running on CI runners. Mirror production tag names in tests to catch typos early.
Ship tagged caching with the right backend from day one
Laravel cache tags with Redis vs Memcached boils down to operational fit: both honour the same application code, but Redis gives Laravel teams one durable, multi-purpose backend while Memcached suits narrow, existing cache farms. On new Laravel 13 builds I specify Redis, document tag vocabulary in the repo, and wire model events before launch so stale fragments never become a production surprise. If you are auditing cache architecture on a live app—or planning a Memcached-to-Redis migration—contact us to review your drivers, flush paths, and deploy pipeline. You can also browse the portfolio for Laravel systems where caching and invalidation were built in from the start, or read more on the blog and home page for related engineering guides.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

