# Session store on Upstash Redis with TTL discipline
## Key layout
One key per session: session:SESSION_ID holding a JSON document.
Never one giant key for all sessions, and never key-per-message
unless you need per-message expiry.
## TTL discipline
Set the TTL to your session policy, and refresh it on activity:
SET session:abc123 PAYLOAD EX 3600
Every request from that session re-sets the key with a fresh TTL.
When the user goes quiet, Redis expires the session for you. No
cleanup cron, no orphaned sessions.
The Upstash agent-memory tutorial uses exactly this shape for chat
history: one key per session, one-hour TTL, capped message list.
## Cap what you store
Sessions bloat. Cap the stored payload:
- Chat history: keep the last N messages (the tutorial uses 20).
- Cart or state: store IDs and deltas, not full rendered pages.
- Sliding window: trim the list on every write so it cannot grow
unbounded between reads.
## Atomic updates
Read-modify-write races on session data are real under concurrent
requests. Use /multi-exec for read-modify-write cycles that must
not interleave, or Lua for check-and-set logic.
## Logout and invalidation
DEL session:SESSION_ID on logout. Do not rely on TTL alone for
security-sensitive invalidation: TTL is eventual, DEL is immediate.
## Verify
Create a session, confirm TTL counts down, hit it again and confirm
the TTL refreshed, then wait out the TTL (or set a 5-second TTL in
test) and confirm the key is gone.