← Back to DevBytes

AI Agent Database Choices: Postgres, SQLite, or Vector DBs

Introduction to AI Agent Database Choices

Building AI agents—autonomous systems that perceive, reason, and act—requires robust data management. Agents must store conversation history, long-term memory, tool outputs, embeddings, and structured state. The choice of database directly impacts performance, scalability, and ease of development. Three primary options dominate: PostgreSQL (relational, feature-rich), SQLite (lightweight, embedded), and purpose-built vector databases (like Pinecone, Weaviate, Chroma). This tutorial explores when and how to use each, with practical code examples and best practices.

What Are AI Agent Databases and Why They Matter

An AI agent database serves as the agent's "memory" and operational store. It can hold:

Choosing the right database affects latency, cost, developer ergonomics, and the agent's ability to recall information accurately. A mismatch can lead to slow retrievals, high infrastructure complexity, or limited scalability.

PostgreSQL for AI Agents

PostgreSQL is a powerful open-source relational database with extensions like pgvector that enable vector similarity search. It's ideal when you need ACID compliance, complex queries, joins, and a single database for both structured data and embeddings.

Why Use PostgreSQL

How to Use PostgreSQL with AI Agents

You can store conversation messages in a table, agent state in another, and embeddings in a table with a vector column. pgvector supports exact and approximate nearest neighbor search.

-- Enable pgvector extension
CREATE EXTENSION IF NOT EXISTS vector;

-- Create a table for conversation messages
CREATE TABLE agent_messages (
    id SERIAL PRIMARY KEY,
    session_id UUID NOT NULL,
    role TEXT CHECK (role IN ('user', 'assistant', 'tool', 'system')),
    content TEXT,
    created_at TIMESTAMP DEFAULT NOW()
);

-- Create a table for embedding memory
CREATE TABLE agent_memory (
    id SERIAL PRIMARY KEY,
    session_id UUID,
    text TEXT,
    embedding vector(1536),  -- OpenAI Ada embedding size
    created_at TIMESTAMP DEFAULT NOW()
);

-- Index for fast similarity search
CREATE INDEX ON agent_memory USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);

Insert embeddings and query similar memories:

-- Insert embedding (example using psycopg2 or Python)
-- Python code would generate embedding and insert
INSERT INTO agent_memory (session_id, text, embedding)
VALUES ('550e8400-e29b-41d4-a716-446655440000', 'User prefers dark mode', '[0.12, -0.34, ...]');

-- Find top 3 similar memories
SELECT text, 1 - (embedding <=> '[0.10, -0.35, ...]') AS similarity
FROM agent_memory
WHERE session_id = '550e8400-e29b-41d4-a716-446655440000'
ORDER BY embedding <=> '[0.10, -0.35, ...]'
LIMIT 3;

Best Practices for PostgreSQL

SQLite for AI Agents

SQLite is a serverless, zero-configuration, embedded database. It's perfect for local, single-user agents, prototyping, edge devices, or when you need minimal operational overhead.

Why Use SQLite

How to Use SQLite with AI Agents

Integrate SQLite with the agent code using built-in libraries (Python's sqlite3, Node.js better-sqlite3). Use the sqlite-vec extension for embeddings. The database file can be stored alongside the agent script.

-- Load sqlite-vec extension (once per connection)
.load './vec0.dll' -- or .so for Linux/Mac

CREATE VIRTUAL TABLE vec_memories USING vec0(
    embedding float[1536],
    text TEXT,
    session_id TEXT
);

-- Insert with embedding (using Python to bind)
-- In Python:
import sqlite3
import sqlite_vec
conn = sqlite3.connect("agent.db")
conn.enable_load_extension(True)
conn.load_extension("vec0")
# Then insert using parameterized query
cursor.execute("INSERT INTO vec_memories (embedding, text, session_id) VALUES (?, ?, ?)",
               (embedding_list, "User likes pizza", "session123"))
conn.commit()

-- Query nearest neighbors
SELECT text, distance
FROM vec_memories
WHERE session_id = 'session123'
ORDER BY vec_distance_cosine(embedding, ?)
LIMIT 5;

Example Python code for embedding and querying:

import sqlite3
import numpy as np
# Assuming sqlite-vec extension loaded
conn = sqlite3.connect("agent_memory.db")
conn.enable_load_extension(True)
conn.load_extension("vec0")

# Create virtual table
conn.execute("""
CREATE VIRTUAL TABLE IF NOT EXISTS memories USING vec0(
    embedding float[768],  -- for embedding model dim
    content TEXT,
    user_id TEXT
);
""")

# Insert memory
embedding = [0.1, -0.2, ...]  # from model
conn.execute(
    "INSERT INTO memories (embedding, content, user_id) VALUES (?, ?, ?)",
    (embedding, "Reminder: buy milk", "user1")
)
conn.commit()

# Query similar memories
query_vector = [0.12, -0.18, ...]
results = conn.execute("""
    SELECT content, vec_distance_cosine(embedding, ?) as dist
    FROM memories
    WHERE user_id = 'user1'
    ORDER BY dist ASC
    LIMIT 3
""", (query_vector,)).fetchall()
print(results)

Best Practices for SQLite

Vector Databases (Purpose-Built) for AI Agents

Specialized vector databases like Pinecone, Weaviate, Chroma, Milvus, Qdrant are designed exclusively for similarity search on embeddings. They offer high scalability, advanced indexing, and cloud-native features.

Why Use a Vector Database

How to Use a Vector Database with AI Agents

Typically, you set up a cloud instance or run a local container. Store embeddings with associated metadata (e.g., session ID, timestamp). The agent queries the database for relevant context before generating responses.

Example with Chroma (open-source, local or server):

pip install chromadb
import chromadb
from chromadb.utils import embedding_functions

# Setup client (local persistent storage)
client = chromadb.PersistentClient(path="./agent_memory_chroma")

# Use default embedding function or bring your own
openai_ef = embedding_functions.OpenAIEmbeddingFunction(
    api_key="YOUR_KEY",
    model_name="text-embedding-ada-002"
)

# Create collection
collection = client.create_collection(
    name="agent_memories",
    embedding_function=openai_ef,
    metadata={"hnsw:space": "cosine"}
)

# Add documents (auto-embedding)
collection.add(
    documents=["User prefers dark mode", "Remember to call mom"],
    metadatas=[{"user_id": "user1", "type": "preference"}, {"user_id": "user1", "type": "todo"}],
    ids=["mem1", "mem2"]
)

# Query relevant memories
results = collection.query(
    query_texts=["What does the user like regarding UI?"],
    n_results=2,
    where={"user_id": "user1"}
)
print(results)

Example with Pinecone (managed):

import pinecone
import openai

# Initialize Pinecone
pinecone.init(api_key="YOUR_KEY", environment="us-west1-gcp")
index = pinecone.Index("agent-memory-index")

# Embed and upsert
embedding = openai.Embedding.create(input=["User wants weekly reports"], model="text-embedding-ada-002")['data'][0]['embedding']
index.upsert([
    ("mem_id_3", embedding, {"user_id": "user2", "text": "User wants weekly reports"})
])

# Query
query_vec = openai.Embedding.create(input=["report preferences"], model="text-embedding-ada-002")['data'][0]['embedding']
results = index.query(
    vector=query_vec,
    filter={"user_id": {"$eq": "user2"}},
    top_k=3,
    include_metadata=True
)
print(results)

Best Practices for Vector Databases

How to Choose the Right Database for Your AI Agent

Consider these factors:

Hybrid Approaches and Practical Integration

Many AI agents combine databases. For example, PostgreSQL for session state, user data, and tool logs, plus a vector database for semantic memory. Or SQLite for local cache and embeddings, syncing to a remote Postgres for multi-device access. The agent can abstract the storage layer behind a repository pattern.

Example of a hybrid agent using SQLite for fast local embedding search and PostgreSQL for shared state:

class AgentMemory:
    def __init__(self):
        self.local_db = sqlite3.connect("local_cache.db")
        self.remote_conn = psycopg2.connect("postgresql://...")
    
    def store_embedding_local(self, text, embedding, user_id):
        # Fast local write
        self.local_db.execute("INSERT INTO vec_memories ...")
    
    def sync_to_remote(self):
        # Batch sync to PostgreSQL for persistence
        pass
    
    def search(self, query_embedding, user_id):
        # First try local cache, fallback to remote
        # ...

Conclusion

Your database choice shapes your AI agent's memory architecture, performance, and maintenance burden. PostgreSQL brings transactional power and vector capabilities via pgvector—ideal for most server-based agents. SQLite shines for local, embedded, or offline-first agents with minimal dependencies. Purpose-built vector databases excel when scaling similarity search to millions of embeddings. Evaluate your agent's requirements: scale, data complexity, latency, and ops. Often a hybrid approach delivers the best balance. Experiment with the code examples above, and remember to follow best practices for indexing, connection management, and metadata filtering.

— Ad —

Google AdSense will appear here after approval

← Back to all articles