vercel/next.js / examples / cache-handler-redis-turbo / README.md
The React Framework
README.md
Next.js Redis Cache Integration Example (Turbo Redis Cache)
This example shows a production Redis cache for self-hosted Next.js using
@trieb.work/nextjs-turbo-redis-cache.
The cache-handler-redis example is the canonical
no-dependency starting point: both Next.js cache APIs against the redis
client directly. Use this example when you want a maintained package with GET
timeouts, request coalescing, an in-memory tag map, key-space notifications,
and TLS / multi-instance ops knobs.
It covers both Next.js cache handler interfaces:
| Interface | Used by | Handler file |
|---|---|---|
cacheHandler (singular) | ISR (/isr), on-demand revalidation | cache-handler.js |
cacheHandlers.remote (plural) | 'use cache: remote' (/cet, /gmt, /use-cache), cacheComponents: true (Next.js 16+) | cache-components-handler.js |
The plain 'use cache' directive uses the default in-memory handler. This
example opts into the shared Redis-backed remote handler explicitly on both
Cache Components demos. The separate /isr route exercises the singular
handler. Both handlers use the build ID as a Redis key prefix by default, so
rebuilding does not reuse cached pages from an older build. The default ISR
in-memory cache is disabled so both instances use Redis. Set KEY_PREFIX to
share a namespace across deployments deliberately.
How to use
Execute create-next-app with npm, Yarn, or pnpm to bootstrap the example:
npx create-next-app --example cache-handler-redis-turbo cache-handler-redis-turbo-app
yarn create next-app --example cache-handler-redis-turbo cache-handler-redis-turbo-app
pnpm create next-app --example cache-handler-redis-turbo cache-handler-redis-turbo-app
1. Start Redis
docker compose up -d
This starts a redis/redis-stack container on port 6379 with RedisInsight on
port 8001.
2. Enable Redis key-space notifications
The handler uses Redis key-space notifications to keep its in-memory tag map in sync across instances. Enable them with:
redis-cli -h localhost config set notify-keyspace-events Exe
If your Redis provider forbids
CONFIGcommands (e.g. some managed Redis services), setSKIP_KEYSPACE_CONFIG_CHECK=trueto skip the check.
3. Build and start the Next.js app
npm run build
npm start
next builddoes not require a running Redis instance — both handlers no-op duringPHASE_PRODUCTION_BUILD. Redis is only needed at runtime.
4. View the cache
Open http://localhost:3000 and navigate to:
/cetor/gmt— Time demo using'use cache: remote'withcacheLife("minutes")andcacheTag("time-data"). Shows the current time, a cache-state watcher, and a "Revalidate" button that callsupdateTag("time-data")./use-cache— Cache Components demo (pluralcacheHandlers). Uses the'use cache: remote'directive withcacheLife("minutes")andcacheTag(...). The "Revalidate" button callsupdateTag("use-cache-fact"), which invalidates the cached entry across all server instances sharing the Redis cache./isr— Pages Router ISR demo (singularcacheHandler). Displays the time generated bygetStaticPropsand regenerates after 10 seconds.
To see cache debug logs:
DEBUG_CACHE_HANDLER=true npm start
Documentation
Key Features
- L1 + L2 caching: in-memory L1 cache per instance + Redis L2 as the shared source of truth across all instances.
- Request deduplication: concurrent
getcalls for the same key are deduplicated to avoid redundant Redis round-trips. - Batch tag invalidation:
revalidateTagoperations are grouped and optimized for minimal Redis stress. - Key-space notifications: the in-memory tag map is automatically updated when Redis keys expire or are evicted.
- Cache Components support: full support for the
'use cache'directive,cacheTag, andcacheLife(Next.js 16+). - Pages Router support: ISR pages,
notFound/redirectresults, and on-demandres.revalidate(path)— including across multiple instances.
Environment Variables
| Variable | Required | Description |
|---|---|---|
REDIS_URL | Recommended | Redis connection URL, e.g. redis://localhost:6379 |
REDISHOST | If no REDIS_URL | Redis host (with REDISPORT) |
REDISPORT | If no REDIS_URL | Redis port |
VERCEL_URL | Optional | Used as a key prefix for multi-tenant / deploy isolation |
VERCEL_ENV | Optional | production → Redis DB 0; anything else → DB 1 |
KEY_PREFIX | Optional | Explicit cache key prefix |
DEBUG_CACHE_HANDLER | Optional | Set to true for debug logging |
SKIP_KEYSPACE_CONFIG_CHECK | Optional | Set to true to skip the notify-keyspace-events check |
KILL_CONTAINER_ON_ERROR_THRESHOLD | Optional | Exit after N Redis errors (for container restarts) |
REDIS_COMMAND_TIMEOUT_MS | Optional | Timeout for Redis GET (default: 500ms) |
Development and Production Considerations
-
The provided
compose.yamlis intended for local development. For production deployment, refer to the official Redis installation and management guidelines. -
Clearing Redis Cache:
docker exec -it cache-handler-redis-turbo redis-cli 127.0.0.1:6379> flushall OK
Rendered from the public repository vercel/next.js on GitHub; content belongs to its authors. Cached for up to an hour.