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';
const tenzro = new Tenzro({ apiKey: 'your-api-key' });
// Create a key-value database
const db = await tenzro.kev.create({
projectId: 'project-id',
db_name: 'my-cache',
maxMemory: 256, // MB
evictionPolicy: 'allkeys-lru',
});
// Set a value with TTL
await tenzro.kev.set(db.kev_db_id, 'session:user123', {
userId: 'user123',
name: 'John Doe',
roles: ['admin'],
}, 3600); // 1 hour TTL
// Get a value
const { value } = await tenzro.kev.getValue(db.kev_db_id, 'session:user123');
console.log(value); // { userId: 'user123', name: 'John Doe', ... }
// Increment a counter
const { value: count } = await tenzro.kev.increment(db.kev_db_id, 'page:views', 1);
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

Key Operations

Set Value

await tenzro.kev.set(
kevDbId: string, // Database ID
key: string, // Key name
value: any, // Value (JSON serializable)
ttl?: number // Optional TTL in seconds
);

Get Value

const { key, value } = await tenzro.kev.getValue(kevDbId, key);

Delete Key

const { deleted } = await tenzro.kev.deleteKey(kevDbId, key);

Increment Counter

const { key, value } = await tenzro.kev.increment(kevDbId, key, by);
// by: number - amount to increment (default: 1)

Hash Operations

Hashes store multiple field-value pairs under a single key:

Set Hash Field

await tenzro.kev.hset(kevDbId, 'user:123', 'name', 'John Doe');
await tenzro.kev.hset(kevDbId, 'user:123', 'email', 'john@example.com');

Get Hash Field

const { value } = await tenzro.kev.hget(kevDbId, 'user:123', 'name');
// value: 'John Doe'

Get All Hash Fields

const { hash } = await tenzro.kev.hgetall(kevDbId, 'user:123');
// hash: { name: 'John Doe', email: 'john@example.com' }

List Operations

Lists are ordered collections of values:

Push to List

const { length } = await tenzro.kev.lpush(kevDbId, 'queue:tasks', [
{ task: 'process', data: {...} },
{ task: 'notify', data: {...} },
]);

Get List Range

const { values, count } = await tenzro.kev.lrange(
kevDbId,
'queue:tasks',
0, // start index
-1 // end index (-1 = all)
);

Pub/Sub

Publish messages to channels:

const { receivers } = await tenzro.kev.publish(
kevDbId,
'events:orders',
{ orderId: 'ord-123', status: 'completed' }
);

Use Cases

Session Storage

// Store session
await tenzro.kev.set(kevDbId, `session:${sessionId}`, {
userId: user.id,
email: user.email,
roles: user.roles,
createdAt: Date.now(),
}, 86400); // 24 hours
// Get session
const { value: session } = await tenzro.kev.getValue(kevDbId, `session:${sessionId}`);
if (!session) {
throw new Error('Session expired');
}
// Delete session (logout)
await tenzro.kev.deleteKey(kevDbId, `session:${sessionId}`);

Rate Limiting

async function checkRateLimit(userId: string, limit = 100): Promise<boolean> {
const key = `ratelimit:${userId}:${Math.floor(Date.now() / 60000)}`;
const { value: count } = await tenzro.kev.increment(kevDbId, key, 1);
// Set TTL on first request
if (count === 1) {
await tenzro.kev.set(kevDbId, key, count, 60); // 1 minute window
}
return count <= limit;
}

Caching

async function getCachedData<T>(
key: string,
fetcher: () => Promise<T>,
ttl = 300
): Promise<T> {
// Try cache first
try {
const { value } = await tenzro.kev.getValue(kevDbId, key);
if (value) return value as T;
} catch {
// Cache miss
}
// Fetch and cache
const data = await fetcher();
await tenzro.kev.set(kevDbId, key, data, ttl);
return data;
}
// Usage
const user = await getCachedData(
`user:${userId}`,
() => db.query(`SELECT * FROM users WHERE id = $1`, [userId]),
3600
);

Leaderboards

// Update score
await tenzro.kev.hset(kevDbId, 'leaderboard:weekly', `user:${userId}`, score);
// Get all scores
const { hash } = await tenzro.kev.hgetall(kevDbId, 'leaderboard:weekly');
const sorted = Object.entries(hash)
.map(([user, score]) => ({ user, score }))
.sort((a, b) => (b.score as number) - (a.score as number));

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