Overview
Stands up the actual Upstash Redis instance and credentials the rest of the Redis-backed history cache work talks to. Deliberately no application code changes — just makes Redis reachable from both local dev and the deployed app.
Today lib/historyCache.ts only has InMemoryHistoryCache, a process-local Map. Its own comment already flags the problem: "a cache miss is expected in multi-instance/serverless deploys" — but in a real Vercel/serverless deployment that's not an edge case, it's the common case, since each request can land on a cold or different instance with an empty Map. The HistoryCache interface was deliberately designed so swapping the backing store needs zero changes in app/api/sessions/route.ts or app/api/sessions/[id]/message/route.ts — both already depend only on the interface, never the concrete class.
Provider decision: Upstash Redis — REST-based (@upstash/redis), so it needs no persistent TCP connection/pool, which fits Next.js route handlers running on serverless (runtime = "nodejs", dynamic = "force-dynamic") far more cleanly than a TCP client like ioredis.
Acceptance criteria
- Upstash Redis database created, sized for a ~30 MB free-tier budget (sized by concurrent active sessions, ~75 KB each).
@upstash/redis added to package.json dependencies.
UPSTASH_REDIS_REST_URL / UPSTASH_REDIS_REST_TOKEN added locally to .env.local (gitignored, never committed) — if the repo has no .env.example, add one listing the required var names (no values) alongside the existing NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY, ANTHROPIC_API_KEY.
- Same two vars added to the production deploy target's environment config (e.g. Vercel project settings) — this is a manual dashboard step, call it out as such rather than assuming it's scriptable.
- A manual
GET/SET round trip against the instance confirms connectivity before the RedisHistoryCache implementation builds on it.
Overview
Stands up the actual Upstash Redis instance and credentials the rest of the Redis-backed history cache work talks to. Deliberately no application code changes — just makes Redis reachable from both local dev and the deployed app.
Today
lib/historyCache.tsonly hasInMemoryHistoryCache, a process-localMap. Its own comment already flags the problem: "a cache miss is expected in multi-instance/serverless deploys" — but in a real Vercel/serverless deployment that's not an edge case, it's the common case, since each request can land on a cold or different instance with an emptyMap. TheHistoryCacheinterface was deliberately designed so swapping the backing store needs zero changes inapp/api/sessions/route.tsorapp/api/sessions/[id]/message/route.ts— both already depend only on the interface, never the concrete class.Provider decision: Upstash Redis — REST-based (
@upstash/redis), so it needs no persistent TCP connection/pool, which fits Next.js route handlers running on serverless (runtime = "nodejs",dynamic = "force-dynamic") far more cleanly than a TCP client likeioredis.Acceptance criteria
@upstash/redisadded topackage.jsondependencies.UPSTASH_REDIS_REST_URL/UPSTASH_REDIS_REST_TOKENadded locally to.env.local(gitignored, never committed) — if the repo has no.env.example, add one listing the required var names (no values) alongside the existingNEXT_PUBLIC_SUPABASE_URL,NEXT_PUBLIC_SUPABASE_ANON_KEY,ANTHROPIC_API_KEY.GET/SETround trip against the instance confirms connectivity before theRedisHistoryCacheimplementation builds on it.