Kev - Key-Value Store
High-performance Redis-powered key-value store for caching, sessions, rate limiting, and real-time data.
Overview
Kev provides a managed Redis-compatible key-value database with support for:
- String key-value pairs with TTL
- Hashes (field-value maps)
- Lists (ordered collections)
- Counters and atomic increments
- Pub/Sub messaging
Quick Start
import { Tenzro } from '@tenzro/cloud';const client = new Tenzro({apiKey: process.env.TENZRO_API_KEY,projectId: 'your-project-id',});// Get key-value store by nameconst cache = await client.kev.db('user-cache');// Set a value with TTLawait cache.set('session:user123', {userId: 'user123',name: 'John Doe',roles: ['admin'],}, 3600); // 1 hour TTL// Get a value (auto-parses JSON)const session = await cache.get('session:user123');console.log(session); // { userId: 'user123', name: 'John Doe', ... }// Increment a counterconst count = await cache.increment('page:views');console.log(count); // 1, 2, 3, ...
Database Configuration
Eviction Policies
| Policy | Description |
|---|---|
noeviction | Return error when memory limit reached |
allkeys-lru | Evict least recently used keys (recommended) |
allkeys-lfu | Evict least frequently used keys |
volatile-lru | Evict LRU keys with TTL set |
volatile-ttl | Evict keys with shortest TTL |
SDK Reference
Get Store
// Get existing key-value store by nameconst cache = await client.kev.db('user-cache');
Key Operations
Set Value
await cache.set('session:user123', // Key{ userId: '123', name: 'Alice' }, // Value (auto-serialized)3600 // Optional TTL in seconds);
Get Value
const session = await cache.get('session:user123');// Returns parsed JSON or null if not found
Delete Key
await cache.delete('session:user123');
Increment Counter
const count = await cache.increment('page:views', 1);// by: number - amount to increment (default: 1)
Hash Operations
Hashes store multiple field-value pairs under a single key:
Set Hash Field
await cache.hset('user:123', 'name', 'John Doe');await cache.hset('user:123', 'email', 'john@example.com');
Get Hash Field
const name = await cache.hget('user:123', 'name');// Returns: 'John Doe'
Get All Hash Fields
const user = await cache.hgetall('user:123');// Returns: { name: 'John Doe', email: 'john@example.com' }
List Operations
Lists are ordered collections of values:
Push to List
await cache.lpush('queue:tasks',{ task: 'process', data: {...} },{ task: 'notify', data: {...} });
Get List Range
const tasks = await cache.lrange('queue:tasks',0, // start index-1 // end index (-1 = all));
Pub/Sub
Publish messages to channels:
await cache.publish('events:orders',{ orderId: 'ord-123', status: 'completed' });
Use Cases
Session Storage
const cache = await client.kev.db('sessions');// Store sessionawait cache.set(`session:${sessionId}`, {userId: user.id,email: user.email,roles: user.roles,createdAt: Date.now(),}, 86400); // 24 hours// Get sessionconst session = await cache.get(`session:${sessionId}`);if (!session) {throw new Error('Session expired');}// Delete session (logout)await cache.delete(`session:${sessionId}`);
Rate Limiting
const cache = await client.kev.db('rate-limits');async function checkRateLimit(userId: string, limit = 100): Promise<boolean> {const key = `ratelimit:${userId}:${Math.floor(Date.now() / 60000)}`;const count = await cache.increment(key);// Set TTL on first requestif (count === 1) {await cache.set(key, count, 60); // 1 minute window}return count <= limit;}
Caching
const cache = await client.kev.db('app-cache');async function getCachedData<T>(key: string,fetcher: () => Promise<T>,ttl = 300): Promise<T> {// Try cache firstconst cached = await cache.get<T>(key);if (cached) return cached;// Fetch and cacheconst data = await fetcher();await cache.set(key, data, ttl);return data;}// Usageconst user = await getCachedData(`user:${userId}`,() => db.query(`SELECT * FROM users WHERE id = $1`, [userId]),3600);
Leaderboards
const cache = await client.kev.db('leaderboards');// Update scoreawait cache.hset('leaderboard:weekly', `user:${userId}`, score);// Get all scoresconst scores = await cache.hgetall('leaderboard:weekly');const sorted = Object.entries(scores).map(([user, score]) => ({ user, score: score as number })).sort((a, b) => b.score - a.score);
Best Practices
- Use TTL: Always set TTL for cached data to prevent stale data
- Key naming: Use consistent naming like
type:id:field - JSON values: Store complex objects as JSON for flexibility
- Atomic operations: Use
incrementfor counters - Memory planning: Monitor usage and set appropriate limits
Limits
| Resource | Limit |
|---|---|
| Max memory per database | 16 GB |
| Max key length | 512 bytes |
| Max value size | 512 MB |
| Max list length | 4 billion elements |
| Max hash fields | 4 billion |