Caching reinvented.
Imagine your Node.js app as a bustling airport — Redis is that shared runway everyone fights over. At low traffic, it’s fine. Double the planes? Chaos. Enter layercache, a slick TypeScript library that stacks in-memory speed on Redis muscle (and even disk if you want persistence), all behind one dead-simple API. No more hand-rolling fragile hybrids that break under stampede.
Here’s the magic: on a hot read, it zips from L1 memory at 0.005ms. Miss? Fetcher fires once — exactly once — no matter 75 goroutines hammering it. Redis coordinates cross-instance, backfills layers automatically. It’s like having a personal jet strip per process, with air traffic control for the shared one.
Why Redis Latency Kills Your P95
Every backend dev knows the drill. Traffic spikes, that 0.2ms Redis ping balloons your tail latencies. You slap on an in-process cache — great, until invalidation logic turns into a nightmare. Three months in, you’re debugging consistency bugs at 3am.
Layercache? It handles stampede prevention, cross-instance invalidation, graceful degradation. Out of the box. Here’s the stack:
your app ──▶ L1 Memory ~0.006 ms (per-process, sub-millisecond) │ L2 Redis ~0.2 ms (shared across instances) │ L3 Disk ~2 ms (optional, persistent) │ Fetcher runs once (even under high concurrency)
And the code? Butter.
npm install layercache
Memory only:
import { CacheStack, MemoryLayer } from 'layercache'
const cache = new CacheStack([
new MemoryLayer({ ttl: 60, maxSize: 1_000 })
])
const user = await cache.get('user:123', () => db.findUser(123))
Add Redis? Same API. Swap layers like Lego bricks. Your app code stays pristine.
But numbers, right? That’s where hype dies or lives.
I dug into the benchmarks — real Redis 7 on Docker, not mocks. Hot path? Memory-only: 0.009ms avg, p95 0.014ms. Add Redis layer: 0.005ms avg, 0.006ms p95. Sub-ms paradise. Both scream ‘production ready.’
Can Layercache Survive a Stampede?
This is the gut-check. 75 concurrent misses, repeated 5x.
| Mode | Avg ms | Origin Executions |
|---|---|---|
| No cache | 409.5 | 375 |
| Memory only | 6.9 | 5 |
| Memory + Redis | 36.7 | 5 |
No cache: 375 DB thrashes. Layercache? Fetcher runs 5 times total. Redis layer pays coordination tax (36ms vs 7ms), but zero stampede. That’s the single-flight guarantee most DIY caches botch.
Sustained autocannon blast — 40 connections, 8 seconds:
| Route | Avg Latency | P97.5 | Req/s |
|---|---|---|---|
| No cache | 249 ms | 271 ms | 161 |
| Memory only | 1.82 ms | 4 ms | 16,705 |
| Memory + Redis | 1.74 ms | 4 ms | 17,184 |
161 req/s to 17k+. Latency craters to <2ms. After warmup, L1 owns hot paths — Redis fades into the background.
Caching moved the service from 161 req/s to over 17,000 req/s — roughly a 100× improvement in throughput.
What Happens When Redis Tanks?
Production isn’t fairytales. Inject 500ms TCP delay:
| Redis Delay | L1 hot hit | L2 hit | Cold miss |
|---|---|---|---|
| 0ms | 0.407ms | 2.655ms | 12.259ms |
| 100ms | 0.119ms | 101.172ms | 504.167ms |
| 500ms | 0.196ms | 501.404ms | 2506.013ms |
L1 hot hits? Untouched. Slow Redis only bites L2 or colds. Graceful degradation keeps warm traffic humming — but colds still timeout at 2s if Redis pauses fully. No magic fallback for never-seen keys. Smart devs preheat critical paths.
My unique take? This echoes memcached’s 2003 debut — in-process speed shattered shared-cache myths. Layercache does it for hybrids. Bold prediction: in two years, it’ll be the default for Node.js at 10k+ req/s, like Express owns HTTP. No PR spin; the benchmarks don’t lie.
But wait — is it truly effortless? Setup’s a breeze, but tune TTLs right or L1 bloats. Cross-instance needs Redis cluster awareness (it does). Disk layer? Niche for cold starts, but hey, options rock.
Why Does Layercache Matter for Node.js Devs?
Node’s single-threaded charm shines at scale — until I/O stalls it. Layercache turns caching into a fire-and-forget layer. Scale horizontally? Instances sync via Redis. Vertical? Memory scales with cores. It’s the platform shift for backends: caching as infrastructure, not glue code.
Picture this: your e-comm site Black Fridays without cache avalanches. APIs humming at 17k req/s. That’s not hype; that’s measured reality.
Enthusiasm aside, test it yourself. Docker up Redis, npm install, benchmark. You’ll wonder why you tolerated half-baked caches so long.
And yeah, it’s TypeScript-first — types catch key bugs early. No JS footguns.
🧬 Related Insights
- Read more: Ditching the Cloud: How Nordic SMBs Are Migrating Back On-Prem — And Saving a Fortune
- Read more: LeetCode 207: The Cycle That Sinks 55% of Coders — Visual Kahn’s Algorithm Breakdown
Frequently Asked Questions
What is layercache and how does it work?
Layercache is a Node.js/TypeScript caching library that layers in-memory (L1), Redis (L2), and optional disk (L3) storage. It provides a unified get(key, fetcher) API with automatic backfilling, stampede protection, and cross-instance consistency.
Does layercache prevent cache stampede?
Yes — the fetcher for a key runs exactly once, even under high concurrency. Benchmarks show 75 concurrent requests trigger just one origin call per round.
Is layercache ready for production Redis setups?
Absolutely. It handles Redis failures with graceful degradation for hot keys, delivers sub-ms hits, and boosts throughput 100x in tests. Tune for your workload.