Est.

Agent Memory Backends and Storage Options

Vector databases excel at semantic retrieval but miss structured state and temporal accuracy.

Senior Writer · · 11 min read
Cover illustration for “Agent Memory Backends and Storage Options”
Open-Source Agent Tooling · September 7, 2026 · 11 min read · 2,391 words

Every LLM call starts from zero. No memory, no history, no idea who you are or what you asked five minutes ago, unless something explicitly stores that context and hands it back later. Statelessness is the default rather than the exception, and that single fact is why agent memory turned into its own engineering discipline instead of a paragraph buried in the system prompt.

Consequences show up fast once you scale past a demo. An agent that can't recall a user's preferences asks the same onboarding questions every session, forever, like a barista with amnesia. Long conversations degrade on their own too: attention spreads thin, context drifts, and hallucination rates climb as the token count grows. Multi-agent setups make it worse. Tool outputs passed from one agent to another chew through context budgets faster than a single chatty conversation ever would.

McKinsey's 2025 State of AI Global Survey put a number on the gap between talking about agents and actually running them: 23% of organizations were scaling an agentic system in at least one business function, while 39% were still stuck experimenting. That jump, from prototype to production, is exactly where memory design falls apart. Three failure modes keep showing up, and they're worth naming plainly. Memory drift is one, where the agent quietly loses track of facts as the context window fills. Context poisoning is another, where stale or manipulated input corrupts what the agent thinks it knows (this overlaps with established prompt injection risk categories). Silent retrieval failures round out the list, where the agent answers confidently from memory that's missing or out of date, with no signal that anything went wrong.

Pick your memory backend late and you'll pay for it in a rewrite. This is an infrastructure decision, and the choice made here decides whether continuity, accuracy, and scale are even on the table six months from now.

The four memory types agents actually use and what each one does

Diagram: Four Memory Types, Four Distinct Jobs. Visualizes: Visualize the four memory types agents use — working, episodic, semantic, and procedural — as a ranked or layered structure showing what each stores, how long it persists, and its access…

The field settled on a taxonomy borrowed straight from cognitive science: working, episodic, semantic, and procedural memory. Frameworks build these four in wildly different ways, but the categories keep showing up because each one maps to a distinct, real problem. Here's the mistake teams keep making: picking one storage backend and asking it to handle all four. Each type has a different access pattern, a different persistence need, and a different tolerance for delay, and one backend will be wrong for at least three of them.

Working memory is the live context window: system prompt, chat history, tool outputs, and retrieved facts, all fighting over the same token budget. It's instant to access and costs nothing in retrieval latency, but it's capped hard by token length and it vanishes the second the session ends. One common pattern is a FIFO queue: hit the token limit, and the oldest messages get flushed out to longer-term storage.

Episodic memory holds the record of what happened: what this user asked for last time, what decision got made on this task, what pattern keeps repeating. It's the layer that does personalization, and it has to survive across sessions, usually pulled back by a user ID or session ID.

Semantic memory is the external knowledge store, the facts and documentation that live outside the model's training data and get updated as new material comes in. This is the layer RAG pipelines exist to serve.

Procedural memory covers the rules and workflows an agent follows, whether that's baked into model weights or spelled out as explicit instructions. It gets pulled up the least often at runtime, but a mistake here poisons every single action downstream.

Some taxonomies tack on a fifth category, parametric memory: knowledge baked into the weights during training, not writable at runtime, but worth knowing about since it explains what an agent "knows" without retrieving anything at all.

In-context storage: what the context window can and cannot do

In-context storage is the simplest setup there is: everything the agent needs sits in the prompt, every turn, no retrieval step required. It works right up until the token ceiling gets in the way, and that ceiling always arrives eventually.

That ceiling is lower than it looks on paper. Claude Opus 4 handles up to 200,000 tokens; GPT-4o tops out at 128,000. Sounds like a lot, until the system prompt, tool schemas, conversation history, and retrieved chunks all start elbowing each other for the same space. Multi-agent workflows burn through it even faster, since passing tool outputs between agents adds bulk a single conversation never would.

Dumping everything into the prompt gets you the best accuracy available, on paper, but it falls apart in production. Token cost rises in a straight line with history length, and latency rises with prompt size. Older content loses its grip on the model's attention as the window fills, which shows up in practice as the agent "forgetting" something it technically still has access to, buried on page one of a conversation it stopped paying attention to on page five. A bigger context window doesn't fix this, even though teams keep treating it like it does. A retrieval strategy that pulls in only what's needed, when it's needed, from storage that lives outside the prompt entirely, is what actually helps.

In-context storage earns its keep on short, bounded tasks, something that fits in one sitting with nothing to remember once it's over. It breaks the moment a task needs memory that outlives a session, or a workflow racks up history over many steps, or the cost and latency budget gets tight.

Vector databases as the semantic retrieval layer

Vector databases are the storage layer semantic memory gets built on top of, rather than standalone memory systems on their own. The mechanism: embeddings turn meaning into high-dimensional vectors, and similarity search pulls back whatever sits closest in that vector space at query time.

That fits semantic memory well (documents, knowledge bases, anything RAG-shaped), and it handles episodic retrieval too when you're searching by content similarity. Yet it has a real blind spot, and it's worth being blunt about it: vector search finds what's similar, not necessarily what's current or what's specifically about one entity. Ask it "what's true about this customer right now" and it hands back whatever reads closest in meaning, with little sense of time or identity attached.

The backend options split along real tradeoffs, and picking one is less about which is "best" than which failure mode you can live with. Pinecone is a managed vector search service well suited to RAG workloads, though it addresses semantic retrieval rather than structured agent state. Weaviate is open-source and supports hybrid search that blends vector and keyword matching. Qdrant is designed for cases where you need vector similarity combined with detailed metadata filtering. Pgvector bolts vector search onto PostgreSQL as an extension, a practical pick for teams that don't want a separate database just for embeddings (more on that under the relational section below). Redis, paired with RediSearch, supports embedding lookups alongside session state, making it a candidate for caching session context and transient state.

None of this solves reasoning about relationships between entities, or asking what was true at a specific point in time. Vector search hands back relevant chunks with no graph structure and little concept of when a fact stopped being true.

Key-value stores for session state and low-latency transient memory

Key-value stores run on a different access pattern than vector search: look something up by its exact key, rather than by how similar it sounds. In agent systems, that covers a few jobs. Session state is one, holding the current thread, active task parameters, or preferences keyed by user or session ID. Caching is another, so a repeated tool call or embedding lookup doesn't run twice. Overflow for working memory rounds it out, since a FIFO queue can flush its oldest messages out when the token limit is reached, before they migrate to long-term storage.

Redis dominates this space for a simple reason: it's in-memory, so reads and writes are fast enough for the low-latency demands of an agent loop, exactly what an agent loop needs when it's checking state on every single turn. Add RediSearch and Redis picks up vector similarity too, letting a team run session state and embedding search off one system instead of two.

FalkorDB pushes this further by combining graph query capabilities with vector search in a single system, reducing the overhead of coordinating between separate databases, which matters when latency is the whole point of the exercise. For teams running distributed, high-throughput workloads where Redis's licensing terms are a sticking point, open-source forks of Redis offer an alternative path.

Here's the catch nobody puts on the marketing slide: key-value stores can't run complex queries across the data they hold, have no built-in concept of similarity, and if you're running one purely in memory, nothing survives a restart unless persistence gets configured separately, on purpose, ahead of time.

Graph databases for memory that tracks entities, relationships, and time

Graph memory has matured into a recognized production pattern, and is specifically a strong fit for agents that need to reason about relationships rather than just fetch similar-sounding text.

What it adds beyond vector search: entity-centric lookup, meaning you pull every fact connected to one specific person or organization by walking the graph, rather than by guessing at semantic similarity. Temporal awareness, tracking both when something was true in the real world and when the system found out about it. And contradiction handling: when a new fact conflicts with an old one, the old fact gets marked invalid instead of deleted outright, so the history stays intact instead of getting silently overwritten.

Graphiti, the open-source temporal knowledge graph library behind Zep, is the clearest example of this pattern running in production. It builds bi-temporal graphs out of conversations and business data, so an agent can ask what's true right now, what was true on a given date, and where a fact originally came from. It runs on Neo4j, FalkorDB, or Kuzu, depending on what the team already operates.

Managed cloud graph options have expanded, which matters mainly for teams already living on a single cloud provider who'd rather not stand up a separate graph database instance for one feature. Approaches that blend vector similarity with graph traversal have shown promise over pure vector or pure graph retrieval in recent research, though the margin depends heavily on the task.

Graph memory earns its cost for agents managing long-running relationships (support agents, CRM-style workflows), for domains where facts shift over time and the agent has to tell current from historical, and for multi-agent systems sharing one knowledge graph. It's not worth the operational overhead for short, task-bounded agents where nothing changes and there's barely any user history to track. A graph database should earn its place through the demands of the workload, not the appeal of the architecture diagram; too many teams reach for one because it looks sophisticated on a slide.

Relational and distributed SQL as the persistence and multi-tenancy layer

Relational databases rarely get billed as "agent memory," but they do quiet, load-bearing work underneath most production systems: persistence, auditability, and keeping one tenant's data walled off from another's.

The strengths are the same ones relational databases have always had. ACID guarantees matter once multiple agents write to shared state at the same time and consistency can't slip. Structured queries handle joins, aggregations, and exact-match lookups against task history or user records in ways vector search was never built for. Tenant isolation, keeping each user's or customer's memory store separate, is something relational systems have done since long before agents existed.

PostgreSQL with the pgvector extension is the most direct path for teams that don't want four different databases just to serve one agent. Structured state (procedural rules, task history, user records) lives in standard SQL tables, and pgvector handles semantic retrieval in the same database. A single-node setup covers early-stage or moderate-scale deployments fine; scaling out horizontally takes extra architecture work on top of that.

That's where distributed SQL comes in: systems designed for cross-region deployments and high write throughput. These matter once an agent workload spans regions, needs high write throughput, or serves a large number of concurrent users at once, offering stronger consistency and availability guarantees under load than a single PostgreSQL instance can promise.

There's a broader shift underway here, toward consolidating onto fewer platforms rather than running separate vector, graph, and relational databases side by side. PostgreSQL with pgvector is the clearest example, and mainly it's about cutting operational complexity, one fewer system to patch, back up, and page someone about at 2am. Worth being straight about the tradeoff, though: pgvector handles moderate data volumes fine, but purpose-built vector databases are generally better suited once embedding volume gets large. Consolidation has a limit, and it's worth stopping there instead of forcing one database to do five jobs badly.

How memory frameworks abstract the backend layer

Memory frameworks sit one layer above all of this. They decide what gets stored, when it gets retrieved, how conflicts get resolved, and which backend each piece writes to. Developers configure the storage; the framework runs the logic on top of it.

Mem0 is a clear example. It splits memory into distinct scopes, user, session, and agent, backed by a store that can draw on multiple retrieval mechanisms. When new information conflicts with something already stored, Mem0 is designed to handle conflicting facts rather than simply appending new ones, which keeps memory from bloating over time into a pile of contradictions nobody wants to sort through. It is designed to support multiple vector backends, so teams can plug into whatever they're already running. According to benchmark evaluations, Mem0 scored 26% higher on response quality than OpenAI's native memory feature while using 90% fewer tokens to do it; a later version, in April 2026, scored 92.5 on the LoCoMo benchmark.

The pattern here is the same one that shows up in every mature piece of infrastructure: the interesting decisions move up the stack. A memory backend earns its place when a specific workload, personalization, compliance, latency, scale, actually demands it, not because it showed up in someone else's stack. The framework on top is what makes switching backends later something you can do without rewriting the whole agent from scratch.

Sources

  1. mem0.ai
  2. atlan.com
  3. atlan.com
  4. redis.io
  5. aiagentmemory.org
  6. atlan.com
  7. atlan.com
  8. atlan.com

More in Open-Source Agent Tooling