Built-in Storage
MemoryStorage
Best for development, single-process, or stateless deployments.
import { MemoryStorage } from '@carloscortezcloud/sayay-guard';
const storage = new MemoryStorage();
// Data is lost on restart
KVStorage (Cloudflare KV)
Works across Workers in production. Eventually consistent.
import { KVStorage } from '@carloscortezcloud/sayay-guard';
const storage = new KVStorage(env.BUDGET_KV);
// Keys: budget:{userId}:{date}
Custom Storage
Implement the SayayStorage interface for any backend:
interface SayayStorage {
getSpend(userId: string): Promise<{ daily: number; monthly: number; session: number }>;
addSpend(userId: string, costUsd: number): Promise<void>;
}
Redis Example
import { createClient } from 'redis';
class RedisStorage implements SayayStorage {
private client;
constructor() {
this.client = createClient({ url: process.env.REDIS_URL });
}
async getSpend(userId: string) {
const today = new Date().toISOString().slice(0, 10);
const daily = await this.client.get(`budget:${userId}:daily:${today}`) || '0';
const monthly = await this.client.get(`budget:${userId}:monthly`) || '0';
return {
daily: Number(daily),
monthly: Number(monthly),
session: 0,
};
}
async addSpend(userId: string, costUsd: number) {
const today = new Date().toISOString().slice(0, 10);
await this.client.incrByFloat(`budget:${userId}:daily:${today}`, costUsd);
await this.client.incrByFloat(`budget:${userId}:monthly`, costUsd);
}
}
D1 (Cloudflare)
class D1Storage implements SayayStorage {
constructor(private db: D1Database) {}
async getSpend(userId: string) {
const today = new Date().toISOString().slice(0, 10);
const row = await this.db.prepare(
`SELECT daily, monthly FROM budgets WHERE user_id = ? AND date = ?`
).bind(userId, today).first();
return {
daily: row?.daily || 0,
monthly: row?.monthly || 0,
session: 0,
};
}
async addSpend(userId: string, costUsd: number) { /* similar */ }
}
Python Storage
The Python SDK ships three built-in storages. All use the same key scheme (sayay:{user}:daily:{date}).
from sayay import SayayGuard, MemoryStorage, FileStorage
# In-memory — best for dev / single-process
guard = SayayGuard(storage=MemoryStorage(), budget={"dailyUsd": 5.0})
# File — JSON on disk, survives restarts
guard = SayayGuard(storage=FileStorage("budgets.json"), budget={"dailyUsd": 5.0})
RedisStorage
Requires the optional extra — pip install "sayay[redis]":
from sayay import SayayGuard, RedisStorage
guard = SayayGuard(
storage=RedisStorage(host="localhost", port=6379),
budget={"dailyUsd": 5.0},
)
The redis client is lazily imported, so you get a helpful error message if the extra isn’t installed.