How to Set Up Conversation Memory with SQLite for Agents: OpenAI SDK and Google ADK Guide
You can set up conversation memory with SQLite for agents by using SQLiteSession in the OpenAI Agents SDK or DatabaseSessionService in Google ADK, both of which automatically persist conversation history to local SQLite files and reload it on subsequent runs.
Setting up conversation memory with SQLite for agents ensures your LLM applications retain context across user sessions and system restarts. The Shubhamsaboo/awesome-llm-apps repository provides production-ready implementations using the OpenAI Agents SDK and Google Agent Development Kit (ADK), demonstrating how to persist conversation state using lightweight, file-based SQLite databases without external infrastructure.
Why Use SQLite for Agent Conversation Memory?
SQLite provides a serverless, zero-configuration database engine that stores data in a single file on disk. For agent frameworks, this means you can maintain ACID-compliant conversation history without deploying PostgreSQL or Redis. Both the OpenAI Agents SDK and Google ADK leverage SQLite to store message threads, agent states, and event logs, enabling true persistence across process restarts.
OpenAI Agents SDK: Persistent Memory with SQLiteSession
The OpenAI Agents SDK implements conversation memory through the SQLiteSession class, which wraps a SQLite database to store message history. When you pass a SQLiteSession instance to Runner.run(), the SDK automatically appends each turn to the underlying database and retrieves the full history on subsequent calls.
Implementation Details
In ai_agent_framework_crash_course/openai_sdk_crash_course/7_sessions/7_1_basic_sessions/agent.py, the implementation demonstrates two modes:
- In-memory sessions: Omit the
db_pathparameter to store history temporarily during the process lifetime - Persistent sessions: Provide a file path like
"conversation_history.db"to survive process restarts
The SQLiteSession constructor signature is SQLiteSession(session_id, db_path=None), where session_id uniquely identifies the conversation thread.
Code Example
from agents import Agent, Runner, SQLiteSession
import asyncio
# Define the agent
root_agent = Agent(
name="Memory Assistant",
instructions="You are a helpful assistant that remembers prior conversation."
)
async def demo_persistent_memory():
# Persistent SQLite session that survives restarts
session = SQLiteSession("user_123", "chat_history.db")
# First turn - stores to SQLite
result1 = await Runner.run(
root_agent,
"My name is Alice and I love hiking.",
session=session
)
print(f"Assistant: {result1.final_output}")
# Second turn - automatically loads history from SQLite
result2 = await Runner.run(
root_agent,
"What is my name and what do I love?",
session=session
)
print(f"Assistant: {result2.final_output}")
# Run the demo
asyncio.run(demo_persistent_memory())
Google ADK: DatabaseSessionService for SQLite Persistence
Google's Agent Development Kit (ADK) provides the DatabaseSessionService class for persistent conversation storage. Unlike the OpenAI SDK's single-table approach, ADK creates three distinct tables (sessions, state, and events) to store session metadata, application state, and interaction events separately.
Implementation Details
In ai_agent_framework_crash_course/google_adk_crash_course/5_memory_agent/5_2_persistent_conversation_agent/agent.py, the implementation shows how to configure the service with a SQLite URL:
session_service = DatabaseSessionService(db_url="sqlite:///sessions.db")
The service automatically initializes the database schema on first run, creating:
- sessions: Stores session IDs and metadata
- state: Stores key-value application state as JSON
- events: Stores the full event history including user and agent messages
Code Example
import asyncio
from google.adk.agents import LlmAgent
from google.adk.sessions import DatabaseSessionService
from google.adk.runners import Runner
from google.genai import types
from dotenv import load_dotenv
load_dotenv() # Loads GOOGLE_API_KEY
# Initialize persistent SQLite storage
session_service = DatabaseSessionService(db_url="sqlite:///sessions.db")
# Create the agent
agent = LlmAgent(
name="memory_agent",
model="gemini-1.5-flash",
description="Agent with persistent memory",
instruction="You are a helpful assistant. Remember facts about the user."
)
# Runner connects agent to storage
runner = Runner(agent=agent, app_name="memory_demo", session_service=session_service)
async def chat(user_id: str, session_id: str, message: str) -> str:
# Ensure session exists
session = await session_service.get_session("memory_demo", user_id, session_id)
if not session:
session = await session_service.create_session(
"memory_demo", user_id, session_id, state={"history": []}
)
# Create user message
content = types.Content(role="user", parts=[types.Part(text=message)])
# Run and capture final response
async for event in runner.run_async(
user_id=user_id, session_id=session_id, new_message=content
):
if event.is_final_response():
return event.content.parts[0].text if event.content else ""
async def main():
await session_service.initialize() # Creates tables if needed
user = "alice"
session = "session_001"
# Conversation turns
for msg in ["I love programming in Python", "What language do I love?"]:
response = await chat(user, session, msg)
print(f"User: {msg}")
print(f"Agent: {response}\n")
if __name__ == "__main__":
asyncio.run(main())
Key Architectural Differences
While both frameworks use SQLite for persistence, they differ in schema design and control granularity:
OpenAI Agents SDK (SQLiteSession)
- Stores conversation history as a serialized message list in a simplified table structure
- Provides automatic prompt stitching without manual state management
- Supports both transient (in-memory) and persistent modes via the optional
db_pathparameter - Requires less boilerplate for basic conversational memory
Google ADK (DatabaseSessionService)
- Separates storage into three distinct tables:
sessions,state, andevents - Allows storage of arbitrary application state beyond message history via JSON columns
- Requires explicit session initialization and retrieval in application code
- Provides granular control over event streaming and state manipulation for complex workflows
Choose OpenAI SDK for rapid prototyping and simple conversational agents where you only need message history. Choose Google ADK when you need to persist complex application state or require fine-grained control over the session lifecycle.
Summary
- SQLite enables serverless persistence for agent conversation memory without requiring external database infrastructure.
- OpenAI Agents SDK uses
SQLiteSessionto automatically persist messages when passed toRunner.run(), supporting both in-memory and file-backed modes via thedb_pathparameter. - Google ADK implements
DatabaseSessionServicewith a three-table schema (sessions,state,events) for comprehensive conversation and state persistence. - Both approaches require a unique
session_idto isolate conversation threads and automatically handle prompt stitching, eliminating manual context management. - Reference implementations are available in
ai_agent_framework_crash_course/openai_sdk_crash_course/7_sessions/7_1_basic_sessions/agent.pyandai_agent_framework_crash_course/google_adk_crash_course/5_memory_agent/5_2_persistent_conversation_agent/agent.py.
Frequently Asked Questions
How does SQLite conversation memory survive application restarts?
SQLite stores data in a local file on disk (e.g., sessions.db or chat_history.db). When you configure SQLiteSession with a db_path parameter in OpenAI SDK or DatabaseSessionService with db_url="sqlite:///..." in Google ADK, the frameworks write conversation history to this file. On restart, the same file path reconnects to the existing database, and the frameworks automatically load prior messages when you instantiate a session with the same session_id.
Can I use the same SQLite database for multiple agents or users?
Yes. Both frameworks support multi-tenancy through the session_id parameter. In OpenAI SDK, create distinct SQLiteSession instances with unique session IDs (e.g., user_123, user_456) while pointing to the same database file. In Google ADK, the DatabaseSessionService uses composite keys (app_name, user_id, session_id) to isolate conversations, allowing a single SQLite file to serve thousands of distinct user sessions without data collision.
What is the difference between in-memory and persistent SQLite sessions in the OpenAI SDK?
The OpenAI Agents SDK's SQLiteSession class supports both modes through the optional db_path parameter. When you omit db_path (e.g., SQLiteSession("temp_id")), the session stores history in an in-memory SQLite database that persists only for the process lifetime—ideal for testing or stateless deployments. When you provide a file path (e.g., SQLiteSession("user_123", "chat.db")), the SDK writes to a persistent file on disk, enabling conversation continuity across application restarts and system reboots.
How can I query or debug the conversation history stored in SQLite?
Both frameworks use standard SQLite schemas that you can inspect using any SQLite client (e.g., sqlite3 CLI, DB Browser for SQLite, or Python's sqlite3 module). In OpenAI SDK implementations, the SQLiteSession stores messages in a table structure that you can query directly to inspect the conversation history. In Google ADK, the DatabaseSessionService creates three explicit tables—sessions (metadata), state (JSON application state), and events (message history)—allowing you to run SQL queries like SELECT * FROM events WHERE session_id = 'user_123' ORDER BY timestamp to debug conversation flow or audit agent interactions.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →