{"_id":"@appelboomhd/nextjs-redis-sentinel-cache-handler","_rev":"5-e5fa60a32a0ebc33b8dbc07cd1a842d3","name":"@appelboomhd/nextjs-redis-sentinel-cache-handler","dist-tags":{"latest":"0.3.0","beta":"0.1.3"},"versions":{"0.2.0":{"name":"@appelboomhd/nextjs-redis-sentinel-cache-handler","version":"0.2.0","keywords":["nextjs","cache-handler","redis","ioredis","sentinel","isr","rijksoverheid"],"license":"EUPL-1.2","_id":"@appelboomhd/nextjs-redis-sentinel-cache-handler@0.2.0","maintainers":[{"name":"appelboomhd","email":"julianriemersma@gmail.com"}],"homepage":"https://github.com/appelboomhd/nextjs-redis-sentinel-cache-handler#readme","bugs":{"url":"https://github.com/appelboomhd/nextjs-redis-sentinel-cache-handler/issues"},"dist":{"shasum":"e21f9c3d8ed618df26f2c691147e0696538cbbe1","tarball":"https://registry.npmjs.org/@appelboomhd/nextjs-redis-sentinel-cache-handler/-/nextjs-redis-sentinel-cache-handler-0.2.0.tgz","fileCount":8,"integrity":"sha512-Dh4LqF5xbgRDc/CbPKk2jGcn9QhCGg6cInZwHpHKxXuwq643vdNM9RgMDNXQKBsMrWuaW73L7U2EqfOfkL9vYw==","signatures":[{"sig":"MEQCIFH8HduRj9zm0TKsZTxbkncn4gtvjV4WLs4106NFJ5sZAiB1dqrLPPtJ+nD2NdukVaR9bJIV83uaxxUaUHWhoZnTMA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":190551},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"2a60ec4d9064a159edb210a4f3d18dd851ca4469","scripts":{"dev":"tsup --watch","build":"tsup","format":"prettier --write .","typecheck":"tsc --noEmit","format:check":"prettier --check .","prepublishOnly":"tsup"},"_npmUser":{"name":"appelboomhd","email":"julianriemersma@gmail.com"},"repository":{"url":"git+https://github.com/appelboomhd/nextjs-redis-sentinel-cache-handler.git","type":"git"},"_npmVersion":"11.9.0","description":"Next.js cache handler backed by ioredis with Redis Sentinel support.","directories":{},"_nodeVersion":"24.14.0","dependencies":{"lru-cache":"^11.0.0"},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","ioredis":"^5.10.0","prettier":"^3.4.2","typescript":"^5.9.3","@types/node":"^25.6.0"},"peerDependencies":{"next":">=14.0.0","ioredis":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/nextjs-redis-sentinel-cache-handler_0.2.0_1784110900596_0.6563119802832824","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@appelboomhd/nextjs-redis-sentinel-cache-handler","version":"0.2.1","keywords":["nextjs","cache-handler","redis","ioredis","sentinel","isr","rijksoverheid"],"license":"EUPL-1.2","_id":"@appelboomhd/nextjs-redis-sentinel-cache-handler@0.2.1","maintainers":[{"name":"appelboomhd","email":"julianriemersma@gmail.com"}],"homepage":"https://github.com/appelboomhd/nextjs-redis-sentinel-cache-handler#readme","bugs":{"url":"https://github.com/appelboomhd/nextjs-redis-sentinel-cache-handler/issues"},"dist":{"shasum":"d23950d2f2620ed6f2c738715966cc3f9b03da8c","tarball":"https://registry.npmjs.org/@appelboomhd/nextjs-redis-sentinel-cache-handler/-/nextjs-redis-sentinel-cache-handler-0.2.1.tgz","fileCount":8,"integrity":"sha512-pv1S/4j8j4ovIiPOw1NBPKV5Z4a/R5RN1xuIVxNmC+aL/bFZQ3AmFR1BvZlPtnRpuwPTFEgLIkHzEufEQUt+rQ==","signatures":[{"sig":"MEYCIQDo1pwvEJuHxyFGCNqzaWn6T2QL0H5n3H6y8wXNOrFB4gIhAP7l9H+R7/YJxJUDkEoTJVWpH2yGZ9kRA+OJJ9bXht9f","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":195383},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"ee7f667cb03141ce4d491c2db58a094bf5715393","scripts":{"dev":"tsup --watch","build":"tsup","format":"prettier --write .","typecheck":"tsc --noEmit","format:check":"prettier --check .","prepublishOnly":"tsup"},"_npmUser":{"name":"appelboomhd","email":"julianriemersma@gmail.com"},"repository":{"url":"git+https://github.com/appelboomhd/nextjs-redis-sentinel-cache-handler.git","type":"git"},"_npmVersion":"11.9.0","description":"Next.js cache handler backed by ioredis with Redis Sentinel support.","directories":{},"_nodeVersion":"24.14.0","dependencies":{"lru-cache":"^11.0.0"},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","ioredis":"^5.10.0","prettier":"^3.4.2","typescript":"^5.9.3","@types/node":"^25.6.0"},"peerDependencies":{"next":">=14.0.0","ioredis":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/nextjs-redis-sentinel-cache-handler_0.2.1_1785230271065_0.1950406857684821","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@appelboomhd/nextjs-redis-sentinel-cache-handler","version":"0.1.2","keywords":["nextjs","cache-handler","redis","ioredis","sentinel","isr","rijksoverheid"],"license":"EUPL-1.2","_id":"@appelboomhd/nextjs-redis-sentinel-cache-handler@0.1.2","maintainers":[{"name":"appelboomhd","email":"julianriemersma@gmail.com"}],"homepage":"https://github.com/appelboomhd/nextjs-redis-sentinel-cache-handler#readme","bugs":{"url":"https://github.com/appelboomhd/nextjs-redis-sentinel-cache-handler/issues"},"dist":{"shasum":"9da572f4763e842029d39f2977324047d44f86f5","tarball":"https://registry.npmjs.org/@appelboomhd/nextjs-redis-sentinel-cache-handler/-/nextjs-redis-sentinel-cache-handler-0.1.2.tgz","fileCount":8,"integrity":"sha512-ju9FLzhz+ecAu9OezF68fVvouvnT85lVwIy0SdrCkY9uhKyzT6o8pB2hhalcYXbOj0mtbfC1K/reWcslRWss3g==","signatures":[{"sig":"MEUCIQCvDQF+hVXVFuOZvUn+6mZQ45/xeCRXuUaLk5WmNRCBOgIgbSW3HjxCUEMB5J7kgsFe6VayAsDebOpAfVBfLEFouvs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":164937},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"18fbfe20ad9d4e107870a8e961e105975a4d2732","scripts":{"dev":"tsup --watch","build":"tsup","format":"prettier --write .","typecheck":"tsc --noEmit","format:check":"prettier --check .","prepublishOnly":"tsup"},"_npmUser":{"name":"appelboomhd","email":"julianriemersma@gmail.com"},"repository":{"url":"git+https://github.com/appelboomhd/nextjs-redis-sentinel-cache-handler.git","type":"git"},"_npmVersion":"11.9.0","description":"Next.js cache handler backed by ioredis with Redis Sentinel support.","directories":{},"_nodeVersion":"24.14.0","publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tsup":"^8.5.1","ioredis":"^5.10.0","prettier":"^3.4.2","typescript":"^5.9.3","@types/node":"^25.6.0"},"peerDependencies":{"next":">=14.0.0","ioredis":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/nextjs-redis-sentinel-cache-handler_0.1.2_1785230862871_0.26796074821012716","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@appelboomhd/nextjs-redis-sentinel-cache-handler","version":"0.1.3","keywords":["nextjs","cache-handler","redis","ioredis","sentinel","isr","rijksoverheid"],"license":"EUPL-1.2","_id":"@appelboomhd/nextjs-redis-sentinel-cache-handler@0.1.3","maintainers":[{"name":"appelboomhd","email":"julianriemersma@gmail.com"}],"homepage":"https://github.com/appelboomhd/nextjs-redis-sentinel-cache-handler#readme","bugs":{"url":"https://github.com/appelboomhd/nextjs-redis-sentinel-cache-handler/issues"},"dist":{"shasum":"d42578622395814b860951af7c1128c985253a3b","tarball":"https://registry.npmjs.org/@appelboomhd/nextjs-redis-sentinel-cache-handler/-/nextjs-redis-sentinel-cache-handler-0.1.3.tgz","fileCount":8,"integrity":"sha512-wOufyyZsW9M61bLmSCXKF6d/Z5/FAa6G6QBS364vQknrdcv6XDTdzCia2gZ2SUzBJxU+//Xs9xlSOuNklkpW6w==","signatures":[{"sig":"MEQCIAhS6h2OthXPna/54ysbnA+iPI8hptPtir8UTRJIu7LRAiBUXBiJpMcwDGvrEjy+aFxHyrc46RlI8jtgnrkDHg5q9g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":200380},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"329d6f2736ef634642224d9a1589c802521dc6c0","scripts":{"dev":"tsup --watch","build":"tsup","format":"prettier --write .","typecheck":"tsc --noEmit","format:check":"prettier --check .","prepublishOnly":"tsup"},"_npmUser":{"name":"appelboomhd","email":"julianriemersma@gmail.com"},"repository":{"url":"git+https://github.com/appelboomhd/nextjs-redis-sentinel-cache-handler.git","type":"git"},"_npmVersion":"11.9.0","description":"Next.js cache handler backed by ioredis with Redis Sentinel support.","directories":{},"_nodeVersion":"24.14.0","publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tsup":"^8.5.1","ioredis":"^5.10.0","prettier":"^3.4.2","typescript":"^5.9.3","@types/node":"^25.6.0"},"peerDependencies":{"next":">=14.0.0","ioredis":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/nextjs-redis-sentinel-cache-handler_0.1.3_1786434116494_0.5802427531942549","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@appelboomhd/nextjs-redis-sentinel-cache-handler","version":"0.3.0","description":"Next.js cache handler backed by ioredis with Redis Sentinel support.","repository":{"type":"git","url":"git+https://github.com/appelboomhd/nextjs-redis-sentinel-cache-handler.git"},"homepage":"https://github.com/appelboomhd/nextjs-redis-sentinel-cache-handler#readme","bugs":{"url":"https://github.com/appelboomhd/nextjs-redis-sentinel-cache-handler/issues"},"type":"module","exports":{".":{"types":"./dist/index.d.ts","require":"./dist/index.cjs","import":"./dist/index.js"}},"main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","publishConfig":{"access":"public","provenance":true},"scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","format":"prettier --write .","format:check":"prettier --check .","prepublishOnly":"tsup"},"engines":{"node":">=18"},"dependencies":{"lru-cache":"^11.0.0"},"peerDependencies":{"ioredis":">=5.0.0","next":">=14.0.0"},"devDependencies":{"@types/node":"^25.6.0","ioredis":"^5.10.0","prettier":"^3.4.2","tsup":"^8.5.1","typescript":"^5.9.3"},"license":"EUPL-1.2","keywords":["nextjs","cache-handler","redis","ioredis","sentinel","isr","rijksoverheid"],"gitHead":"4857f4bef50c0e15dc280b452bd587db146fd581","_id":"@appelboomhd/nextjs-redis-sentinel-cache-handler@0.3.0","_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-4D+57fyUWj2Asz3o77A7SymksfVtr57kA4+pxX8wq4YzPv85wt+Kl1AYnSgWXatqAMPFpy2fJdIjH84dFU7cgA==","shasum":"3ce56b91485a613a2d669926f45fa5e5f813c8b1","tarball":"https://registry.npmjs.org/@appelboomhd/nextjs-redis-sentinel-cache-handler/-/nextjs-redis-sentinel-cache-handler-0.3.0.tgz","fileCount":8,"unpackedSize":243212,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIFRGtCl6E2s97Ae/uhlPtw9tM8HdtH6wVdp68bCvu3ugAiEAtQ8n5baT9OzfA4bO3dWdDNWdn0FlHsQfPjZB3P6YM3A="}]},"_npmUser":{"name":"appelboomhd","email":"julianriemersma@gmail.com"},"directories":{},"maintainers":[{"name":"appelboomhd","email":"julianriemersma@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/nextjs-redis-sentinel-cache-handler_0.3.0_1787567218032_0.4372561676516633"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-15T10:21:40.460Z","modified":"2026-08-24T10:26:58.476Z","0.2.0":"2026-07-15T10:21:40.725Z","0.2.1":"2026-07-28T09:17:51.220Z","0.1.2":"2026-07-28T09:27:43.015Z","0.1.3":"2026-08-11T07:41:56.625Z","0.3.0":"2026-08-24T10:26:58.171Z"},"bugs":{"url":"https://github.com/appelboomhd/nextjs-redis-sentinel-cache-handler/issues"},"license":"EUPL-1.2","homepage":"https://github.com/appelboomhd/nextjs-redis-sentinel-cache-handler#readme","keywords":["nextjs","cache-handler","redis","ioredis","sentinel","isr","rijksoverheid"],"repository":{"type":"git","url":"git+https://github.com/appelboomhd/nextjs-redis-sentinel-cache-handler.git"},"description":"Next.js cache handler backed by ioredis with Redis Sentinel support.","maintainers":[{"name":"appelboomhd","email":"julianriemersma@gmail.com"}],"readme":"# `@appelboomhd/nextjs-redis-sentinel-cache-handler`\n\nNext.js cache handler backed by `ioredis`, with support for Redis Sentinel, direct Redis connections, tag revalidation, replica reads, an in-memory LRU tier for hot entries, and a filesystem fallback when Redis is unavailable.\n\n## Features\n\n- Redis Sentinel support for master/replica setups\n- Direct Redis mode for simpler deployments\n- Filesystem fallback when Redis is unavailable\n- Tag-based invalidation via `revalidateTag()`\n- Circuit breaker to avoid repeated failures during Redis outages\n- In-memory LRU tier that serves hot entries without a Redis round-trip\n\n## Install\n\n```bash\nnpm install @appelboomhd/nextjs-redis-sentinel-cache-handler ioredis\n```\n\n`next` is a peer dependency and is expected to already be present in your Next.js app.\n\n## Usage\n\nConfigure your Next.js app to use the package as its cache handler:\n\n```js\n// next.config.js\nmodule.exports = {\n  cacheHandler: require.resolve('@appelboomhd/nextjs-redis-sentinel-cache-handler'),\n  cacheMaxMemorySize: 0,\n}\n```\n\n## Configuration\n\n### Sentinel mode\n\n```bash\nREDIS_SENTINEL_URL=redis://sentinel-1:26379,redis://sentinel-2:26379,redis://sentinel-3:26379\nREDIS_SENTINEL_MASTER_NAME=myprimary\nREDIS_PASSWORD=your-password\nREDIS_DB=0\nREDIS_CACHE_PREFIX=cache:\nREDIS_CACHE_DEBUG_LEVEL=0\nREDIS_ENABLE_AUTOPIPELINING=0\n```\n\n### Direct Redis mode\n\n```bash\nREDIS_URL=redis://redis-host:6379\nREDIS_PASSWORD=your-password\nREDIS_DB=0\nREDIS_CACHE_PREFIX=cache:\nREDIS_CACHE_DEBUG_LEVEL=0\n```\n\n## Environment variables\n\n| Variable                      | Required      | Description                                              |\n| ----------------------------- | ------------- | -------------------------------------------------------- |\n| `REDIS_SENTINEL_URL`          | Sentinel mode | Comma-separated Redis Sentinel URLs.                     |\n| `REDIS_SENTINEL_MASTER_NAME`  | No            | Sentinel master name. Defaults to `myprimary`.           |\n| `REDIS_URL`                   | Direct mode   | Direct Redis connection URL.                             |\n| `REDIS_PASSWORD`              | No            | Password used for Redis and Sentinel.                    |\n| `REDIS_DB`                    | No            | Database index. Defaults to `0`.                         |\n| `REDIS_CACHE_PREFIX`          | No            | Key prefix. Defaults to `cache:`.                        |\n| `REDIS_CACHE_DEBUG_LEVEL`     | No            | `0` = silent, `1` = errors, `2` = warnings, `3` = debug. |\n| `REDIS_ENABLE_AUTOPIPELINING` | No            | `1` = enabled. Defaults to disabled.                     |\n| `REDIS_CACHE_LRU_ENABLED`     | No            | `0` = disabled. Defaults to enabled.                     |\n| `REDIS_CACHE_LRU_MAX`         | No            | Max entries in the in-memory tier. Defaults to `1000`.   |\n| `REDIS_CACHE_LRU_MAX_SIZE`    | No            | Approx. memory budget in bytes. Defaults to 50 MB.       |\n| `REDIS_CACHE_LRU_TTL_MS`      | No            | In-memory entry TTL in ms. Defaults to `5000`.           |\n| `REDIS_CACHE_BUILD_ID`        | No            | Override the detected build ID. Defaults to `.next/BUILD_ID`. |\n| `REDIS_CACHE_FS_FALLBACK_ON_MISS` | No        | `0` = disabled. Defaults to enabled.                     |\n| `REDIS_CACHE_TTL_SECONDS`     | No            | Baseline entry TTL in seconds. Defaults to 14 days.      |\n\n`REDIS_DB` selects the Redis logical database for both modes. In direct mode a database in the `REDIS_URL` path (`redis://redis-host:6379/2`) wins over it, so use one or the other.\n\nUse either Sentinel mode or direct mode. If neither `REDIS_SENTINEL_URL` nor `REDIS_URL` is configured, the handler will fall back to the Next.js filesystem cache only.\n\n## Build-scoped keys\n\nEvery `next build` generates a new `BUILD_ID`, and prerendered HTML hardcodes `/_next/static/<BUILD_ID>/...` script tags. Because cache keys are scoped by route path, a shared Redis would otherwise hand a new deployment the HTML written by the previous one — script tags pointing at a static directory that no longer exists on disk, so `_buildManifest.js` and `_ssgManifest.js` 404 until the cache is flushed.\n\nEntries are therefore namespaced per build:\n\n```\n<REDIS_CACHE_PREFIX>b:<buildId>:<cacheKey>      entry\n<REDIS_CACHE_PREFIX>b:<buildId>:tags:<tag>      tag -> keys index\n<REDIS_CACHE_PREFIX>tagtime:<tag>               revalidation marker (shared)\n```\n\nThe build ID is read from `<serverDistDir>/../BUILD_ID` at startup, which ships inside `output: 'standalone'` and so can never drift from the HTML being served. Override with `REDIS_CACHE_BUILD_ID`. When no build ID can be resolved (for example `next dev`), keys stay unscoped and a warning is logged.\n\nTag revalidation markers are deliberately **not** build-scoped. During a rolling deployment both builds serve traffic, and a `revalidateTag()` issued by a pod on the old build must invalidate entries held by pods on the new one.\n\nSuperseded namespaces are not actively deleted; they expire via `REDIS_CACHE_TTL_SECONDS`. Since each build writes a complete fresh copy rather than overwriting the previous one, lower that value if Redis memory becomes a concern.\n\n### Filesystem fallback on miss\n\nA build-scoped namespace starts empty on every deployment, and Next.js has no filesystem fallback of its own once a custom `cacheHandler` is configured. On a Redis miss the handler therefore reads the running build's prerendered output from disk, serves it, and back-fills Redis — preserving the original `lastModified` so the ISR clock is not reset. Entries whose tags have since been revalidated are skipped, so a revalidation cannot be undone by build-time output. Disable with `REDIS_CACHE_FS_FALLBACK_ON_MISS=0`.\n\n## In-memory LRU tier\n\nSetting a custom `cacheHandler` disables Next.js's built-in in-memory ISR cache, so without this tier every request pays a Redis round-trip plus a full JSON deserialization — even for hot pages. The LRU tier restores a process-local fast path: entries are stored already deserialized, so a memory hit skips both the Redis read and the `JSON.parse`.\n\n- Bounded by entry count (`REDIS_CACHE_LRU_MAX`) and an approximate byte budget (`REDIS_CACHE_LRU_MAX_SIZE`).\n- Entries expire after a short TTL (`REDIS_CACHE_LRU_TTL_MS`) so a `revalidateTag()` on another instance cannot keep a stale copy alive for long.\n- Memory hits still honor tag revalidation: stale entries are evicted locally and re-fetched through the Redis path.\n- Disable it entirely with `REDIS_CACHE_LRU_ENABLED=0`.\n\n## Development\n\n```bash\nnpm install\nnpm run typecheck\nnpm run build\n```\n\n## License\n\nEUPL-1.2\n","readmeFilename":"README.md"}