Most backend architectures look like this:
App Server (Node.js) ──[ 1–5 ms network hop ]──► Redis ──[ JSON.parse ]──► Response
While Redis is fast, doing network hops and JSON serialization on every single cache read costs tens of thousands in cloud bills and introduces tail latency under load.
What if your Node.js cache had:
- L1 RAM (Sub-microsecond V8 Heap): Zero network hop, 0 ns decode time with direct object reference caching.
- L1.5 NVMe Disk Spill: Fast local disk fallback instead of evicting to the void when RAM gets full.
- L2 Redis / Valkey Tier: Distributed multi-instance sync with AES-256 encryption and Brotli compression.
- WASM Bloom Filter & Count-Min Sketch: Gating cold misses and burst frequency tracking with WebAssembly.
That is why I built TriCache.
⚡ What Makes It Different?
┌─────────────────────────────────────────────────────────────────────────────┐
│ TriCache 3-Tier Caching Engine │
│ │
│ [ Next.js "use cache" | NestJS @Cacheable | Prisma withTriCache | Hono ] │
│ │ │
│ ┌────────────────▼───────────────┐ │
│ │ L1 Smart Memory (0 ns decode) │ ◄── 4.54M ops/sec │
│ └────────────────┬───────────────┘ │
│ │ (Eviction Spill) │
│ ┌────────────────▼───────────────┐ │
│ │ L1.5 NVMe Disk (Atomic Async) │ ◄── 500 MB Local Pool │
│ └────────────────┬───────────────┘ │
│ │ (Miss Promotion) │
│ ┌────────────────▼───────────────┐ │
│ │ L2 Redis / Valkey Backplane │ ◄── Cluster / Streams │
│ └────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
1. Zero-Allocation WebAssembly Bloom Filter
Cold cache misses are screened through an inlined WebAssembly double-hashing Bloom filter before touching disk or Redis. By pre-allocating the staging memory buffer, .add() executes in 220 ns (4.54 Million ops/sec) with 0 JavaScript garbage collection pauses.
2. O(1) Generational Tag Invalidation
Instead of $O(N)$ Redis KEYS or SMEMBERS deletions, TriCache uses atomic generational version counters. Tag invalidations take 605 ns (1.65 Million ops/sec) across single or batch tags.
3. Thundering Herd Coalescing
10,000 concurrent coroutines requesting the same cold key collapse into exactly 1 upstream fetch call.
🛠️ Plug-and-Play with Your Favorite Stack
Next.js 16 & React 19 RSC Streams
// next.config.mjs
export default {
cacheHandler: require.resolve('tricache/next'),
};
Prisma ORM
import { PrismaClient } from '@prisma/client';
import { withTriCache } from 'tricache/prisma';
import { CacheService } from 'tricache';
const cache = CacheService.create();
const prisma = new PrismaClient().$extends(withTriCache({ cache }));
// Automatically cached + auto-invalidates on mutations:
const users = await prisma.user.findMany({ where: { role: 'ADMIN' }, cache: { ttl: 300 } });
NestJS Decorators
@Injectable()
export class UserService {
@Cacheable({ ttl: 300, tags: ['users'] })
async getUser(id: string) {
return this.userRepo.findById(id);
}
@CacheEvict({ tags: ['users'] })
async updateUser(id: string, data: UpdateDto) {
return this.userRepo.update(id, data);
}
}
Universal HTTP Middleware & 304 ETags (Express / Fastify / Hono)
import { fastifyCache } from 'tricache/http';
app.get('/api/products', { preHandler: fastifyCache({ cache, ttl: 60 }) }, handler);
📊 Live Benchmark Highlights
| Operation | Throughput | Latency |
|---|---|---|
| L1 RAM Hot Read (0-copy) | 621,100 ops/sec | 1.61 µs |
| Generational Tag Invalidation | 1,650,000 ops/sec | 605 ns |
| WASM Bloom Filter Insert | 4,540,000 ops/sec | 220 ns |
| Distributed Mutex Lock | 341,300 ops/sec | 2.93 µs |
📦 Try It Out
TriCache is 100% open-source under MIT, with 485 automated chaos & resilience tests.
npm install tricache
# or try the CLI:
npx tricache inspect
I’d love to hear your thoughts, feedback, and edge cases in the comments! 🚀
Top comments (0)