State for Serverless AI Agents (Lambda, Cloud Run, Vercel)
Free · Open source (MIT) · Works with LangChain, CrewAI, AutoGen · No signup
Serverless functions reset on every invocation, wiping your AI agent's memory clean. Your Lambda function, Cloud Run container, or Vercel deployment can't remember previous conversations, decisions, or learned context. Here's how to give your serverless AI agents persistent memory that survives across invocations and deployments.
The State Problem with Serverless AI Agents
Every serverless platform — AWS Lambda, Google Cloud Run, Vercel Functions — treats functions as stateless by design. When your function finishes, the runtime might persist for a few minutes, but there's no guarantee. Your next invocation could start completely fresh on a different machine.
This breaks AI agents that need to remember things: chat history, user preferences, intermediate reasoning steps, or task progress. Your agent might be halfway through a multi-step workflow when the function times out. The next call starts from scratch, asking the same questions again.
Traditional solutions don't fit serverless constraints. Redis requires connection management and VPC setup. DynamoDB needs AWS SDK configuration and IAM roles. Most developers end up passing state through function parameters or external APIs, creating brittle architectures that leak implementation details.
The serverless agent state problem isn't just about chat history — it's about any persistent context your agent needs across ephemeral compute cycles.
The Fix: Persistent Key-Value Memory
BotWire Memory provides persistent key-value storage designed for serverless AI agents. No setup, no credentials, no infrastructure management.
pip install botwire
from botwire import Memory
import json
def lambda_handler(event, context):
# Create memory scoped to this user
memory = Memory(f"user-{event['user_id']}")
# Get conversation context
chat_history = memory.get("chat_history") or []
user_preferences = memory.get("preferences") or {}
# Process the message with context
response = process_message(
event['message'],
chat_history,
user_preferences
)
# Save updated state
chat_history.append({
"user": event['message'],
"assistant": response,
"timestamp": context.aws_request_id
})
memory.set("chat_history", chat_history)
memory.set("last_interaction", {"timestamp": "2024-01-15"})
return {"response": response}
This agent remembers conversations across Lambda invocations. Each user gets isolated memory through namespacing.
How Serverless Agent Memory Works
The Memory class acts like a persistent dictionary. The namespace isolates different users, sessions, or agent instances. Behind the scenes, it's an HTTP API call to a managed service, but the interface feels local.
from botwire import Memory
# Different namespaces for isolation
user_memory = Memory("user-alice")
session_memory = Memory("session-abc123")
agent_memory = Memory("crew-planning-agent")
# Store complex objects (automatically serialized)
agent_memory.set("workflow_state", {
"current_step": 3,
"completed_tasks": ["research", "outline"],
"pending_tasks": ["draft", "review"],
"context": {"topic": "serverless patterns"}
})
# Retrieve with defaults
workflow = agent_memory.get("workflow_state", {"current_step": 0})
# List all keys in namespace
all_keys = agent_memory.list()
print(f"Agent has {len(all_keys)} memories")
# Clean up old data
agent_memory.delete("temporary_calculation")
Memory persists across different machines, deployments, and cold starts. If your Lambda function crashes mid-execution, the next invocation picks up where it left off by reading the last saved state.
The free tier provides 1000 writes per day per namespace with unlimited reads — perfect for development and moderate production workloads. Data stays available indefinitely unless you explicitly delete it.
Cross-process coordination works naturally. Multiple Lambda invocations can read/write the same namespace for agent handoffs or collaborative workflows.
LangChain and CrewAI Integration
For LangChain agents, use the chat history adapter to maintain conversation memory:
from langchain.agents import create_openai_functions_agent
from langchain_openai import ChatOpenAI
from botwire import BotWireChatHistory
def vercel_function(request):
session_id = request.headers.get("x-session-id")
# Persistent chat history across Vercel deployments
history = BotWireChatHistory(session_id=f"chat-{session_id}")
llm = ChatOpenAI()
agent = create_openai_functions_agent(
llm=llm,
tools=tools,
chat_history=history
)
response = agent.invoke({"input": request.json["message"]})
return {"response": response["output"]}
CrewAI agents can use memory tools for shared knowledge:
from crewai import Agent
from botwire.memory import memory_tools
researcher = Agent(
role="Researcher",
tools=memory_tools("research-crew") + other_tools,
memory=True # CrewAI's built-in memory + BotWire persistence
)
When NOT to Use BotWire Memory
- Vector search or semantic similarity: This isn't a vector database. Use Pinecone, Weaviate, or similar for embedding-based retrieval.
- High-throughput applications: Free tier limits to 1000 writes/day. For intensive workloads, consider Redis or DynamoDB.
- Sub-millisecond latency requirements: HTTP API calls add 50-200ms latency. Use in-memory caching for ultra-low latency needs.
FAQ
Why not Redis or DynamoDB? They require infrastructure setup, connection management, and error handling. BotWire works immediately with zero configuration — critical for rapid prototyping and simple use cases.
Is this actually free? Yes, permanently. 1000 writes/day per namespace, unlimited reads, 50MB storage per namespace. No credit card required, no surprise bills.
What about data privacy? Data is stored on managed infrastructure. For sensitive applications, BotWire is open source (MIT license) and self-hostable as a single FastAPI service.
Give your serverless AI agents the persistent memory they need. pip install botwire and start building stateful agents that remember across invocations. Full docs and examples at https://botwire.dev.