@kyrasource/redis
v1.0.2
Published
Advanced Redis client and module for NestJS applications with caching, connection management, TTL handling, and statistics tracking
Maintainers
Readme
@kyrasource/redis
Advanced Redis client and module for NestJS applications with caching, connection management, TTL handling, and statistics tracking.
Features
- ✅ Connection Management: Auto-reconnection with configurable retry strategy
- ✅ Cache Statistics: Built-in hit/miss tracking and performance monitoring
- ✅ Flexible TTL: Set indefinite persistence or custom TTL per key
- ✅ Pattern Deletion: Delete multiple keys matching a pattern
- ✅ TypeScript Support: Full type safety with generics
- ✅ NestJS Integration: Global module with ConfigService support
- ✅ Error Handling: Graceful fallbacks and comprehensive logging
- ✅ Production Ready: Used in Redis Cloud with enterprise-grade reliability
Installation
npm install @kyrasource/redisQuick Start
1. Setup in Your Module
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { RedisModule } from '@kyrasource/redis';
import redisConfig from './config/redis.config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
load: [redisConfig],
}),
RedisModule,
],
})
export class AppModule {}2. Configure Redis in .env
REDIS_USERNAME=default
REDIS_PASSWORD=your-password
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_DATABASE=kushi-redis
REDIS_MAX_RETRIES=3
REDIS_RETRY_DELAY=10003. Use RedisService
import { Injectable } from '@nestjs/common';
import { RedisService } from '@kyrasource/redis';
@Injectable()
export class MyService {
constructor(private readonly redis: RedisService) {}
async example() {
// Set with TTL (seconds)
await this.redis.set('user:123', { name: 'John' }, 3600);
// Set indefinitely
await this.redis.set('config:app', { theme: 'dark' });
// Get value
const user = await this.redis.get<User>('user:123');
// Check existence
const exists = await this.redis.exists('user:123');
// Delete key
await this.redis.delete('user:123');
// Delete by pattern
await this.redis.deletePattern('user:*');
// Get statistics
const stats = this.redis.getStats();
console.log(`Hit rate: ${stats.hitRate}%`);
// Health check
const ok = await this.redis.ping();
}
}Configuration
Create src/config/redis.config.ts:
import { registerAs } from '@nestjs/config';
import { RedisConfig } from '@kyrasource/redis';
export default registerAs('redis', (): RedisConfig => ({
username: process.env.REDIS_USERNAME || 'default',
password: process.env.REDIS_PASSWORD,
host: process.env.REDIS_HOST || 'localhost',
port: parseInt(process.env.REDIS_PORT || '6379', 10),
database: process.env.REDIS_DATABASE || 'default',
maxRetries: parseInt(process.env.REDIS_MAX_RETRIES || '3', 10),
retryDelay: parseInt(process.env.REDIS_RETRY_DELAY || '1000', 10),
ttl: process.env.REDIS_TTL ? parseInt(process.env.REDIS_TTL, 10) : undefined,
enabled: process.env.CACHE_ENABLED !== 'false',
maxItems: parseInt(process.env.CACHE_MAX_ITEMS || '1000', 10),
ragTimeoutMs: parseInt(process.env.RAG_TIMEOUT_MS || '30000', 10),
}));API Reference
RedisService Methods
set(key: string, value: any, ttlSeconds?: number): Promise<boolean>
Set a value with optional TTL. If ttlSeconds is omitted, the key persists indefinitely.
await redis.set('user:1', { id: 1, name: 'John' }, 3600); // 1 hour
await redis.set('settings', { theme: 'dark' }); // Indefiniteget<T>(key: string): Promise<T | null>
Retrieve and deserialize a cached value.
const user = await redis.get<User>('user:1');
if (user) {
console.log(user.name);
}delete(key: string): Promise<boolean>
Delete a single key.
await redis.delete('user:1');deletePattern(pattern: string): Promise<number>
Delete all keys matching a glob pattern.
const deleted = await redis.deletePattern('user:*');
console.log(`Deleted ${deleted} keys`);exists(key: string): Promise<boolean>
Check if a key exists.
if (await redis.exists('user:1')) {
console.log('User cached');
}ping(): Promise<boolean>
Health check - returns true if Redis is reachable.
const healthy = await redis.ping();getStats(): RedisStats
Get cache hit/miss statistics.
const { hits, misses, hitRate, isConnected } = redis.getStats();Advanced Usage
Using with Other Services
import { Injectable } from '@nestjs/common';
import { RedisService } from '@kyrasource/redis';
@Injectable()
export class UserCacheService {
constructor(private readonly redis: RedisService) {}
async getCachedUser(id: number): Promise<User | null> {
const cached = await this.redis.get<User>(`user:${id}`);
if (cached) return cached;
// Not in cache - fetch from database
const user = await this.database.user.findById(id);
if (user) {
// Cache for 1 hour
await this.redis.set(`user:${id}`, user, 3600);
}
return user;
}
}Type Safety
interface User {
id: number;
name: string;
email: string;
}
// Fully typed
const user = await redis.get<User>('user:123');
if (user) {
console.log(user.email); // Type-safe!
}Exports
From @kyrasource/redis you can import:
export { RedisService } from './redis.service';
export { RedisModule } from './redis.module';
export { RedisConfig, RedisStats } from './types';Connection Details
The service automatically handles:
- Connection pooling
- Reconnection with exponential backoff
- Error recovery
- Graceful shutdown
Connection events are logged at INFO/DEBUG level. Check your logger output for details.
Troubleshooting
"Redis connection failed"
- Verify Redis is running and accessible
- Check credentials in
.env - Ensure network connectivity to Redis host
"Max retries exceeded"
- Redis is unreachable or crashed
- The service will log detailed error messages
- Requests will fail gracefully
Memory Issues
- Monitor cache hit rate via
getStats() - Implement cache eviction policies
- Use appropriate TTL values
License
MIT - See LICENSE file
Support
For issues, feature requests, or documentation, visit:
GitHub: kyrasource/redis
npm: @kyrasource/redis await this.redisService.set('persistent-key', { data: 'value' });
// Get value const data = await this.redisService.get('key');
// Delete key await this.redisService.delete('key');
// Delete pattern await this.redisService.deletePattern('pattern:*');
// Check stats const stats = this.redisService.getStats(); console.log(stats); } }
## Configuration
Set the following environment variables:
```env
# Required
REDIS_HOST=your-redis-host.com
REDIS_PORT=6379
REDIS_PASSWORD=your-password
# Optional
REDIS_USERNAME=default
REDIS_DATABASE=kushi-redis
REDIS_MAX_RETRIES=3
REDIS_RETRY_DELAY=1000
# Cache TTL settings (omit for indefinite persistence)
REDIS_TTL=3600
AGENT_CACHE_TTL=7200
PROMPT_CACHE_TTL=3600
ANSWER_CACHE_TTL=1800
CHROMADB_CACHE_TTL=3600
# Other settings
CACHE_ENABLED=true
CACHE_MAX_ITEMS=1000
RAG_TIMEOUT_MS=30000API Reference
RedisService Methods
set(key: string, value: any, ttlSeconds?: number): Promise<boolean>- Set a value with optional TTLget<T>(key: string): Promise<T | null>- Get a valuedelete(key: string): Promise<boolean>- Delete a keydeletePattern(pattern: string): Promise<number>- Delete keys matching a patternexists(key: string): Promise<boolean>- Check if a key existsgetStats()- Get cache statisticsping(): Promise<boolean>- Check Redis connectionflushAll(): Promise<boolean>- Flush all data (use with caution)
RedisConfig
The library exports a redisConfig function that loads configuration from environment variables.
License
MIT
