Memori

Engineering

Written by Bobur Umurzokov

AI Agent Memory on Your Existing Postgres: We are back to SQL

Explore why your existing Postgres can be used as a strong foundation for AI memory. Learn how SQL databases can power memory for AI agents without exotic tools.

LLMs are smart in the moment, but they forget everything as soon as the conversation moves on.

You can tell an AI assistant, "I don't like coffee", and three steps later, it will happily recommend an espresso. It is not broken logic, it is missing memory.

So the question is: how do we give AI agents memory?

Most builders today rush toward exotic tools: vector databases, graph stores, hybrid architectures. But here's the twist: after all the hype, the simplest answer might be the one we have trusted for more than 50 years. SQL databases like Postgres.

In this post, we'll explore why your existing Postgres can be used as a strong foundation for AI memory. We'll look at how memory works, what problems it solves, where vectors and graphs fall short, and how SQL fits perfectly.

Why Memory Matters for AI Agents

LLMs are powerful at generating language, reasoning over a prompt, and connecting patterns. But by design, they are stateless. Each request starts fresh, with no recollection of what came before unless you provide all that context again.

That leads to big problems:

  • Repetition: You keep telling the AI the same thing (preferences, facts, context).
  • Contradictions: It suggests things you've already rejected.
  • Shallow interactions: It cannot build on history.
  • Expensive prompts: To simulate memory, developers keep appending long histories, blowing up token counts and costs.

Human-like AI requires memory:

  • remembering what you said yesterday,
  • keeping track of your preferences,
  • holding facts, rules, and skills across sessions,
  • and even forgetting things that no longer matter.

Four Common Approaches to AI Memory

Over time, developers have tried different ways to give LLMs memory:

  1. Prompt stuffing / fine-tuning
    • Keep prepending conversation history. Works for short chats, but quickly becomes too expensive.
  2. Vector databases (RAG)
    • Store embeddings of past conversations in Pinecone, Weaviate, or pgvector.
    • Semantic recall works well, but retrieval can be noisy, and structure gets lost.
  3. Graph databases
    • Build entity-relationship graphs. Great for reasoning, but hard to scale and query.
  4. Hybrid systems
    • Mix vectors, graphs, and key-value stores. Flexible, but complex and hard to operate.

Each approach has strengths. But they all introduce complexity, new infrastructure, and costs.

The Overlooked Answer: Relational Databases

Relational databases Postgres, MySQL, SQLite, have powered applications for decades. They are everywhere: mobile apps, web platforms, finance, social media, logistics.

What if the best way to give AI memory is not to reinvent the wheel, but to reuse what already works?

With SQL, you can:

  • Store facts and preferences as structured records
  • Keep short-term vs long-term memory in separate tables
  • Promote important information into permanent memory
  • Use joins and indexes to retrieve relevant context quickly
  • Rely on proven durability, transactions, and scale

Instead of building memory into exotic new systems, we can let AI memory live inside Postgres. This is the approach we took for the Memori open-source project.

Why Postgres?

Postgres is a natural fit for memory because:

  1. It's already everywhere

    You don't need a new database. Most teams already use Postgres or a Postgres-compatible service (Supabase, Neon, AWS RDS).

  2. LLMs understand SQL

    Unlike graph traversal languages or custom APIs, LLMs can generate and reason about SQL easily. Many fine-tunes already know how to write SQL queries.

  3. Structured storage is powerful

    Not all memory is semantic. Preferences, rules, and states fit naturally into rows and columns.

  4. It can do vectors too

    With pgvector, Postgres also supports semantic similarity search. That means you can combine structured facts with embeddings—without leaving your database.

  5. It's cheap and reliable

    Postgres is battle-tested, runs anywhere, and doesn't add new moving parts to your stack.

The Coffee vs Espresso Example

Let's revisit the classic example:

  • You tell the AI: "I hate espresso."
  • Later, it suggests coffee.

Is that wrong? Maybe. Espresso is coffee, but not all coffee is espresso. What if you love black coffee but dislike espresso?

How do we store that? With Postgres, you can design a simple schema:

CREATE TABLE preferences (
  user_id TEXT,
  subject TEXT,
  relation TEXT, -- 'like' or 'dislike'
  strength FLOAT, -- optional, 0 to 1
  created_at TIMESTAMP DEFAULT now()
);

Now you can record both:

  • dislike: espresso
  • like: coffee

If there's a conflict, you can resolve it with rules (e.g., latest wins, or stronger preference wins).

You can also add a hierarchy table:

CREATE TABLE entities (
  child TEXT,
  parent TEXT,
  relation TEXT -- 'is_a'
);

That way, you can reason that espresso is coffee.

The retrieval layer can apply simple logic:

  • If user dislikes espresso, warn against recommending espresso.
  • If user likes coffee, allow coffee in general.
  • Conflicts? Show both and let the user clarify.

This avoids messy embedding searches while keeping reasoning clear and auditable.

Memory Categories

From real-world projects, it helps to think of memory as categories:

  • Facts – technical info, data points, definitions.
  • Preferences – likes/dislikes, personal choices.
  • Skills – user's competencies, learning progress.
  • Context – project details, current situation.
  • Rules – constraints, policies, guidelines.

Each category maps cleanly to a SQL table. For example:

CREATE TABLE memories (
  id SERIAL PRIMARY KEY,
  user_id TEXT,
  category TEXT, -- fact, preference, skill, context, rule
  content TEXT,
  importance INT,
  created_at TIMESTAMP DEFAULT now(),
  expires_at TIMESTAMP
);

With indexes on (user_id, category), retrieval is fast.

Forgetting and Conflict Resolution

Memory isn't just about storing—it's about forgetting and resolving contradictions.

In Postgres, you can implement policies:

  • Decay: auto-expire records after X days.
  • Promotion: if something is repeated often, mark as permanent.
  • Conflict resolution: keep the latest preference, or store both and flag contradiction.

Example query for decay:

DELETE FROM memories
WHERE expires_at < now();

Example for promotion:

UPDATE memories
SET importance = importance + 1
WHERE content = 'prefers black coffee';

Comparison to Vector Search

A common objection: "SQL LIKE searches are fragile. What about synonyms, languages, fuzzy matches?"

Here's the answer:

  • Use SQL first for structured facts.
  • Add full-text search (tsvector) or trigram indexes for fuzzy matching.
  • Fall back to pgvector if needed.

This gives you a cost-efficient pipeline:

  1. Keyword / filter search (cheap).
  2. Structured rules (accurate).
  3. Semantic embeddings (as a last resort).

How to Start: Simple Schema

You can start with just two tables:

CREATE TABLE memories (
  id SERIAL PRIMARY KEY,
  user_id TEXT,
  content TEXT,
  category TEXT,
  importance INT,
  created_at TIMESTAMP DEFAULT now(),
  expires_at TIMESTAMP
);

CREATE INDEX idx_memories_user ON memories(user_id);
CREATE INDEX idx_memories_category ON memories(category);

Then, a simple query to fetch relevant memories:

SELECT content
FROM memories
WHERE user_id = 'user123'
  AND category IN ('preference', 'rule')
  AND (expires_at IS NULL OR expires_at > now())
ORDER BY importance DESC, created_at DESC
LIMIT 5;

Inject those results into your LLM prompt.

That's it: you've given your agent memory—without a new database.

Observability and Costs

Postgres also gives you transparency. You can measure:

  • How many memories were retrieved.
  • Which queries hit vs missed.
  • Token costs saved by not appending entire history.

You can even log why a memory was injected:

INSERT INTO audit_log (memory_id, action, reason)
VALUES (123, 'injected', 'preference: dislikes espresso');

This helps debug agent behavior and build trust.

Limitations and When to Use Vectors

SQL is not perfect. Times when vector search makes sense:

  • Pure semantic similarity ("find text like this paragraph").
  • Multimedia embeddings (images, audio, video).
  • Very large memory (>100M records).

But for most real-world cases—chatbots, assistants, enterprise apps—SQL is enough.

Think of it this way:

  • Use Postgres for structured, durable, governed memory.
  • Add vectors when you need fuzzy, semantic recall.

Conclusion: SQL is Enough

The AI world is chasing shiny new databases. But the truth is: you already have the right tool.

Postgres can store facts, preferences, rules, and context. It can enforce policies, handle conflicts, and scale. With extensions like pgvector, it can even do semantic search.

Instead of adding complexity, let's use what works.

Memory on your existing Postgres is:

  • Simple
  • Cheap
  • Transparent
  • Reliable

Your AI agents don't need exotic systems to remember. They just need well-designed schemas, smart retrieval, and the wisdom of a technology that's been working for half a century.