# How to Set Up Conversation Memory with SQLite for Agents: OpenAI SDK and Google ADK Guide

> Learn how to set up conversation memory with SQLite for agents using OpenAI SDK or Google ADK. Persist and reload conversation history automatically to local SQLite files.

- Repository: [Shubham Saboo/awesome-llm-apps](https://github.com/shubhamsaboo/awesome-llm-apps)
- Tags: how-to-guide
- Published: 2026-02-16

---

**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`](https://github.com/Shubhamsaboo/awesome-llm-apps/blob/main/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_path` parameter 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

```python
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`](https://github.com/Shubhamsaboo/awesome-llm-apps/blob/main/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:

```python
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

```python
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_path` parameter
- Requires less boilerplate for basic conversational memory

**Google ADK (`DatabaseSessionService`)**
- Separates storage into three distinct tables: `sessions`, `state`, and `events`
- 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 `SQLiteSession` to automatically persist messages when passed to `Runner.run()`, supporting both in-memory and file-backed modes via the `db_path` parameter.
- **Google ADK** implements `DatabaseSessionService` with a three-table schema (`sessions`, `state`, `events`) for comprehensive conversation and state persistence.
- **Both approaches** require a unique `session_id` to 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.py`](https://github.com/Shubhamsaboo/awesome-llm-apps/blob/main/ai_agent_framework_crash_course/openai_sdk_crash_course/7_sessions/7_1_basic_sessions/agent.py) and [`ai_agent_framework_crash_course/google_adk_crash_course/5_memory_agent/5_2_persistent_conversation_agent/agent.py`](https://github.com/Shubhamsaboo/awesome-llm-apps/blob/main/ai_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.