High-performance, intelligent caching library for TypeScript/NestJS microservices
TurboCache-JS is a production-ready caching abstraction layer that brings Spring Cache-like decorators to the TypeScript/NestJS ecosystem. Built on top of battle-tested libraries like Keyv and Cacheable, it provides intelligent caching strategies, multi-tier support, and seamless microservices integration.
- π― Decorator-Based API - Clean, declarative caching with
@TurboCache,@TurboCacheEvict,@TurboCachePut - ποΈ NestJS First - Deep integration with dependency injection and module system
- π Multiple Adapters - Redis, Memory, MongoDB, PostgreSQL, or custom backends
- π Microservices Ready - Distributed cache coordination and cross-service invalidation
- π Multi-Tier Caching - L1 (memory) + L2 (distributed) for optimal performance
- π₯ Cache Warming - Pre-load hot data on startup, scheduled refresh, predictive warming
- π Type-Safe - Full TypeScript support with strict typing
- π Observable - Built-in metrics, logging, and health checks
- β‘ High Performance - <5ms read latency, 100k+ ops/sec
- π‘οΈ Production Ready - Stampede prevention, compression, encryption
- π¨ Flexible - Works standalone or with NestJS
npm i @brewedbytes/turbocache-jsimport { TurboCache } from 'turbocache-js';
class UserService {
@TurboCache({ key: 'user:#{id}', ttl: 3600 })
async getUser(id: string) {
return await db.users.findOne({ id });
}
}// app.module.ts
import { TurboCacheModule } from 'turbocache-js';
@Module({
imports: [
TurboCacheModule.register({
stores: [
{
name: 'default',
type: 'redis',
primary: {
type: 'redis',
uri: 'redis://localhost:6379'
},
ttl: 3600
}
],
namespace: 'myapp'
})
]
})
export class AppModule {}
// user.service.ts
@Injectable()
export class UserService {
constructor(
@InjectCache() private cache: CacheManager,
private userRepo: UserRepository
) {}
@TurboCache({ key: 'user:#{id}' })
async findById(id: string): Promise<User> {
return this.userRepo.findById(id);
}
@TurboCacheEvict({ key: 'user:#{id}' })
async update(id: string, data: UpdateUserDto) {
return this.userRepo.update(id, data);
}
}Automatically cache method results:
@TurboCache({
key: 'product:#{id}',
ttl: 3600,
condition: (result) => result !== null
})
async getProduct(id: string): Promise<Product> {
return await this.productRepo.findById(id);
}Invalidate cache on mutations:
@TurboCacheEvict({
key: 'user:#{id}',
allEntries: false
})
async deleteUser(id: string): Promise<void> {
await this.userRepo.delete(id);
}Update cache without preventing execution:
@TurboCachePut({ key: 'user:#{result.id}' })
async createUser(data: CreateUserDto): Promise<User> {
return await this.userRepo.create(data);
}Combine local memory with distributed cache:
TurboCacheModule.register({
stores: [
{
name: 'multi-tier',
type: 'multi-tier',
primary: {
type: 'memory',
options: { max: 1000 },
ttl: 300
},
secondary: {
type: 'redis',
uri: 'redis://localhost:6379',
ttl: 3600
}
}
]
})Dynamic key generation with expressions:
// Simple parameter
@TurboCache({ key: 'user:#{id}' })
// Object property
@TurboCache({ key: 'order:#{order.id}:#{order.status}' })
// Multiple parameters
@TurboCache({ key: 'search:#{category}:#{page}' })@Controller('products')
export class ProductController {
@Get(':id')
@TurboCache({ key: 'product:#{params.id}', ttl: 3600 })
async getProduct(@Param('id') id: string) {
return this.productService.findById(id);
}
}@TurboCache({ key: 'users:active', ttl: 600 })
async getActiveUsers(): Promise<User[]> {
return this.db.users.find({ status: 'active' });
}@TurboCache({
key: 'report:#{month}',
ttl: 86400, // 24 hours
stampedeLock: true
})
async generateMonthlyReport(month: string) {
return this.heavyComputation(month);
}// Service A
@TurboCacheEvict({ key: 'inventory:#{productId}' })
async updateInventory(productId: string, quantity: number) {
await this.repo.update(productId, quantity);
await this.eventBus.emit('inventory.updated', { productId });
}
// Service B listens and invalidates its cache
this.eventBus.on('inventory.updated', async ({ productId }) => {
await this.cache.delete(`inventory:${productId}`);
});- Architecture Guide - System design and patterns
- Implementation Guide - Step-by-step development
- API Reference - Complete API documentation
- Examples - Real-world usage examples
- Roadmap - Development timeline
βββββββββββββββββββββββββββββββββββββββββββ
β Application Layer β
β (Controllers, Services, Resolvers) β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββββββββββββββ
β Decorator Layer β
β @Cacheable @CacheEvict @CachePut β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββββββββββββββ
β Cache Manager (Core) β
β Strategy | Keys | TTL | Serialization β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββββββββββββββ
β Adapter Layer β
β Keyv | Cacheable | Multi-Tier β
ββββββββββββββββ¬βββββββββββββββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββββββββββββββ
β Storage Backends β
β Redis | Memory | MongoDB | PostgreSQL β
βββββββββββββββββββββββββββββββββββββββββββ
- Read Latency: <5ms (memory), <10ms (Redis)
- Throughput: 100,000+ operations/sec
- Memory Overhead: <100MB for typical workloads
- Cache Hit Rate: 85-95% in production
TurboCacheModule.registerAsync({
imports: [ConfigModule],
useFactory: (config: ConfigService) => ({
stores: [{
name: 'default',
type: 'redis',
primary: {
type: 'redis',
uri: config.get('REDIS_URL')
},
ttl: config.get('CACHE_TTL', 3600)
}],
namespace: config.get('APP_NAME'),
enableMetrics: config.get('ENABLE_METRICS', true),
compression: {
enabled: config.get('CACHE_COMPRESSION', false),
threshold: 1024
}
}),
inject: [ConfigService]
})describe('UserService', () => {
let service: UserService;
let cache: CacheManager;
beforeEach(async () => {
const module = await Test.createTestingModule({
imports: [
TurboCacheModule.register({
stores: [{
name: 'default',
type: 'memory',
primary: { type: 'memory' }
}]
})
],
providers: [UserService]
}).compile();
service = module.get(UserService);
cache = module.get('CACHE_MANAGER');
});
it('should cache user data', async () => {
const user = await service.findById('123');
const cached = await cache.get('user:123');
expect(cached).toEqual(user);
});
});- π§ Email: ajay.dutta94@gmail.com
- π Docs: Full Documentation
Made with β€οΈ by the platform engineering team