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 name
const cache = await client.kev.db('user-cache');
// Set a value with TTL
await 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 counter
const count = await cache.increment('page:views');
console.log(count); // 1, 2, 3, ...

Database Configuration

Eviction Policies

PolicyDescription
noevictionReturn error when memory limit reached
allkeys-lruEvict least recently used keys (recommended)
allkeys-lfuEvict least frequently used keys
volatile-lruEvict LRU keys with TTL set
volatile-ttlEvict keys with shortest TTL

SDK Reference

Get Store

// Get existing key-value store by name
const 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 session
await cache.set(`session:${sessionId}`, {
userId: user.id,
email: user.email,
roles: user.roles,
createdAt: Date.now(),
}, 86400); // 24 hours
// Get session
const 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 request
if (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 first
const cached = await cache.get<T>(key);
if (cached) return cached;
// Fetch and cache
const data = await fetcher();
await cache.set(key, data, ttl);
return data;
}
// Usage
const user = await getCachedData(
`user:${userId}`,
() => db.query(`SELECT * FROM users WHERE id = $1`, [userId]),
3600
);

Leaderboards

const cache = await client.kev.db('leaderboards');
// Update score
await cache.hset('leaderboard:weekly', `user:${userId}`, score);
// Get all scores
const 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 increment for counters
  • Memory planning: Monitor usage and set appropriate limits

Limits

ResourceLimit
Max memory per database16 GB
Max key length512 bytes
Max value size512 MB
Max list length4 billion elements
Max hash fields4 billion