Skip to content

Sachini066/cachecraft

Repository files navigation

cachecraft

NestJS Redis TypeScript License: MIT

Advanced Redis caching patterns for NestJS with decorator-based API, stampede prevention, distributed invalidation, and built-in metrics.

Why cachecraft?

Most caching implementations are basic get/set wrappers. cachecraft provides production-grade caching patterns as simple decorators:

  • Cache-Aside with XFetch stampede prevention
  • Write-Through for cache consistency
  • Cache Invalidation via Redis Pub/Sub across instances

Features

  • @CacheAside() - Check cache first, fetch on miss, auto-populate
  • @WriteThrough() - Write to source, then update cache atomically
  • @InvalidateCache() - Invalidate after mutations
  • XFetch Algorithm - Probabilistic early revalidation prevents cache stampedes
  • Redis Pub/Sub - Distributed invalidation across multiple app instances
  • Built-in Metrics - Hit rate, latency, error tracking per key and global
  • Docker Ready - docker-compose with Redis included

Quick Start

git clone https://github.com/Sachini066/cachecraft.git
cd cachecraft
cp .env.example .env
docker compose up -d

Metrics at http://localhost:3000/metrics/cache | Swagger at http://localhost:3000/docs

Usage

Cache-Aside Pattern

@Controller('products')
export class ProductsController {
  @Get(':id')
  @CacheAside({ key: 'product::arg0', ttl: 300, staleWindow: 60 })
  findOne(@Param('id') id: string) {
    return this.productsService.findOne(id);
  }
}

The staleWindow enables XFetch: as the TTL approaches, requests probabilistically refresh the cache in the background, preventing thundering herd on expiry.

Write-Through Pattern

@Post()
@WriteThrough({ key: 'product::arg0', ttl: 300 })
create(@Body() dto: CreateProductDto) {
  return this.productsService.create(dto);
}

Cache Invalidation

@Delete(':id')
@InvalidateCache({ key: 'product::arg0' })
remove(@Param('id') id: string) {
  return this.productsService.remove(id);
}

Invalidation is broadcast via Redis Pub/Sub - all instances evict the key.

Programmatic API

@Injectable()
export class MyService {
  constructor(private cache: CacheService) {}

  async getData(id: string) {
    return this.cache.cacheAside(
      `data:${id}`,
      () => this.fetchFromDb(id),
      300,  // TTL seconds
      60,   // Stale window seconds
    );
  }
}

XFetch: Stampede Prevention

Traditional caching creates a thundering herd when keys expire - all requests simultaneously hit the database. cachecraft uses the XFetch algorithm:

Cache TTL: |████████████████████████████|░░░░░|
                                         ↑ stale window
                                     Probabilistic revalidation
                                     (probability increases as
                                      expiry approaches)

During the stale window, requests that hit the cache have an increasing probability of triggering a background refresh. By the time the key expires, it's already been refreshed.

Metrics

GET /metrics/cache
{
  "global": {
    "hits": 1523,
    "misses": 47,
    "errors": 0,
    "hitRate": 0.97,
    "avgLatencyMs": 0.8,
    "totalRequests": 1570
  },
  "byKey": {
    "product:123": { "hits": 89, "misses": 1, "hitRate": 0.99, ... }
  }
}

Project Structure

src/
├── cache/
│   ├── decorators/         # @CacheAside, @WriteThrough, @InvalidateCache
│   ├── interceptors/       # NestJS interceptors for each pattern
│   ├── interfaces/         # Types and interfaces
│   ├── cache.module.ts     # Global cache module
│   ├── cache.service.ts    # Core service with Redis + metrics + XFetch
│   └── index.ts            # Public API barrel export
├── metrics/
│   ├── metrics.controller.ts   # GET /metrics/cache
│   └── metrics.module.ts
├── app.module.ts
└── main.ts

Testing

npm test              # Unit tests (mocked Redis)
npm run test:cov      # Coverage report

Environment Variables

Variable Default Description
REDIS_URL redis://localhost:6379 Redis connection URL
PORT 3000 Application port

License

MIT

About

Advanced Redis caching patterns for NestJS with decorators, stampede prevention, and metrics

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors