Recipe: Agent memory + persistence
Give your Nimbus agent long-term memory with Upstash KV and session-scoped context windows.
Overview
This recipe wires a persistent memory layer into the agent runtime. Each conversation stores its full message history in Upstash KV under a session key. On reconnect, the agent hydrates its context window from the stored transcript, preserving continuity across restarts and deploys.
Prerequisites
- Nimbus agent runtime v2.4+
- Upstash KV REST URL + token
- Session ID generator (UUID v7 recommended)
Step 1 — Session key schema
Use the pattern memory:{userId}:{sessionId}. Each value is a JSON array of message objects with role, content, and timestamp fields. Set TTL to 72 hours for ephemeral sessions or omit for permanent recall.
Step 2 — Hydrate on connect
On agent startup, issue a GET to the session key. If the response is non-empty, parse the JSON array and push every message into the agent's context window before the first user prompt. This makes the agent immediately aware of prior turns.
Step 3 — Append on each turn
After every user message and agent response, append both to the in-memory array and persist the full array back to KV with a SET. Use conditional writes if multiple workers share a session to avoid lost updates.
Step 4 — Context window pruning
When the message array exceeds your model's token limit, trim the oldest messages while preserving the system prompt and the last N user-assistant pairs. Write the pruned array back to KV so the stored state stays within bounds.
Full example
// memory.ts — Nimbus agent memory layer
import { Redis } from "@upstash/redis";
const kv = Redis.fromEnv();
export async function hydrate(
userId: string,
sessionId: string
): Promise<Message[]> {
const key = `memory:${userId}:${sessionId}`;
const raw = await kv.get<string>(key);
return raw ? JSON.parse(raw) : [];
}
export async function persist(
userId: string,
sessionId: string,
messages: Message[]
): Promise<void> {
const key = `memory:${userId}:${sessionId}`;
await kv.set(key, JSON.stringify(messages), { ex: 259200 });
}Next steps
Combine with the vector search recipe to add semantic recall over long-lived knowledge. For multi-tenant deployments, namespace keys by organization ID.