Chapter 61 · Amazon Elasticache
Subchapter 61.13
references/genai/session-store.mdMarkdown6 KBView on GitHub
Session state, message history, and resumable conversations with ElastiCache Valkey. Plain data structures, no vector search, no embedding model. Works on serverless.
Serverless caches use (not configurable), which only evicts keys that have a TTL set. Always set a TTL on every key. Keys without a TTL will never be evicted and can cause OOM errors. The policy recommended in some best-practice guides applies only to node-based clusters.
volatile-lruallkeys-lru{conv:session_id}:messages # JSON-encoded list of message dicts
{conv:session_id}:metadata # JSON-encoded conversation metadata
conv:user:{user_id}:sessions # sorted set of session_ids, score = timestampHash tag note: The {conv:session_id} hash tag ensures messages and metadata keys hash to the same slot on cluster-mode-enabled caches (including serverless). Without a hash tag, pipeline operations on these keys are non-atomic across slots and a mid-pipeline failure could leave partial state. The conv:user:{user_id}:sessions index key does not share a hash tag with the message/metadata keys, so it hashes to a different slot. This is acceptable because the index is advisory (listing sessions), not transactional.
Use this when you’re not on the Strands framework and need direct control over session storage.
# pip install valkey
# For serverless or cluster-mode-enabled node-based clusters:
# from valkey.cluster import ValkeyCluster
# For cluster-mode-disabled node-based clusters:
# import valkey (use valkey.Valkey)
import json
import time
import valkey
CONVERSATION_TTL = 30 * 24 * 60 * 60 # 30 days (adjust to your retention policy)
_client = None
def get_client():
"""Lazy client initialization. Never create connections at module level.
For serverless or cluster-mode-enabled node-based clusters, use
valkey.cluster.ValkeyCluster instead of valkey.Valkey.
The strands-valkey-session-manager package (community package, v0.1.0+ — MIT license, maintained by jeromevdl) provides a drop-in ValkeySessionManager. Five lines of setup:
import valkey
from strands import Agent
from strands_valkey_session_manager import ValkeySessionManager
_strands_client = None
def get_strands_client():
"""Lazy client initialization. Never create connections at module level.
Uses ValkeyCluster for serverless (cluster-mode-enabled).
For cluster-mode-disabled node-based clusters, use valkey.Valkey instead.
"""
global _strands_client
if _strands_client is None:
_strands_client = valkey.ValkeyCluster(
host="your-endpoint.serverless.use1.cache.amazonaws.com", port=6379, ssl=True,
ssl_cert_reqs="required", decode_responses=True, # in-VPC EKS with real cert verification
# tunnel/dev alternative: ssl_cert_reqs="none" (skips cert verification; not for production)
)
return _strands_client
def create_agent(session_id: str = "user-42") -> Agent:
client = get_strands_client()
session_mgr = ValkeySessionManager(session_id=session_id, client=client)
return Agent(system_prompt="You are a helpful assistant.", session_manager=session_mgr)
# Usage:
# agent = create_agent("user-42")
# response = agent("My name is Alex and I'm building a RAG pipeline.")The session manager stores three key types in Valkey: session:{id} (session record), session:{id}:agent:{agent_id} (agent state), and session:{id}:agent:{agent_id}:message:{msg_id} (individual messages).
| Scope | Recommended TTL |
|---|---|
| Active session | 24 hours |
| Resumable session | 720 hours (~30 days) |
| Session index per user | 90 days |
agent-memory.mdframework-guide.md