There's a genre of blog post emerging in the database industry, and it goes like this: agents fail because of what lands in the context window, this discipline is called context engineering, and therefore you should consolidate your AI stack on our database. Redis published a good example of the genre recently — a genuinely thoughtful one. Its diagnosis is largely correct. Its prescription maps a hard application problem onto a storage purchase. Here's their post
We have an unusual vantage point on this. Miriel is a context and memory platform: a streaming ingestion pipeline that turns documents, SaaS connectors, chat scrollback, and agents' own interactions into permissioned, queryable long-term memory shared by every assistant on an account. And Redis sits at the center of our production stack — our entire ingestion pipeline rides Redis Streams across roughly a hundred consumer groups. We are heavy Redis users. We also keep nothing durable in it, and we'd never put agent memory there. The distinction between those two facts is what this post is about.
The diagnosis is right#
The Redis post opens with an agent that confidently invents a 60-day return policy because the real 30-day policy never made it into the context window. Correct, and well put: the failure happened upstream of the model. Its taxonomy of failure modes — fragmented context, opaque data, slow retrieval, and memory that never accumulates — matches what we see. So does its rule that your maturity is your weakest pillar, not your average.
But notice what kind of failure the opening example is. The policy document existed. It was presumably sitting in a store somewhere, retrievable in single-digit milliseconds. The agent still didn't see it. That's not a storage failure — it's a failure of selection and assembly: what to retrieve, how to rank it, what to cut when the window fills up. It's a retrieval failure. Selection and assembly are application logic, unless, like with Miriel, you put them into the retrieval pipeline.
Where the leverage actually is#
Almost all of the difficulty in context engineering — and nearly all of our engineering investment in it — lives in code no database vendor ships:
Ranking. Vector similarity is a candidate generator, not an answer. Our retrieval pipeline scores candidates on eleven dimensions — semantic, lexical (BM25), temporal, graph proximity, geographic, structural, provenance, freshness, session affinity, cost/latency, and uncertainty — with weight profiles per query intent (a lookup weighs freshness differently than troubleshooting does) and per-account overrides. Then MMR diversity re-ranking, so the window doesn't fill with five paraphrases of the same chunk.
Compression. Summarization is dangerous — a bad summary contaminates every step that follows — so it's the last resort, not the first. We run three escalating levels of context distillation: collapse near-duplicates, drop low-relevance chunks, and only then LLM-summarize groups of similar chunks.
Budgeting. When the assembled context exceeds the model's window, something must go, and the order matters. Our budgeter trims in an explicit priority order — knowledge-graph edges first, then retrieved images, then chunks — binary-searching against per-model token limits, with a separate cost model for image tokens.
Expansion. Sometimes the query itself is the problem. HyDE — generating hypothetical answer documents and retrieving against those — is a per-query option, merged and deduplicated keeping each document's best score.
Structure. Text chunks can't express that two records are related. We extract entities at ingest (fast NER, LLM fallback) and maintain a knowledge graph; queries traverse it and the edges enter the prompt as their own context section, ranked by their own dimension.
Every one of those decisions changes what the model sees. None of them care which database the vectors came from.
Memory is ingestion, not a feature#
The deepest divergence is on memory. The vendor framing treats agent memory as a component — a memory API bolted on beside your knowledge base. We think that's an architectural mistake, and it's the one our product exists to avoid.
In Miriel, memory is the knowledge base. When an agent learns something, that fact enters the same pipeline as every uploaded document and every connector sync: fetched, parsed, chunked, embedded, entity-extracted, indexed. Our chat bots write their own past interactions back as ordinary tagged documents and retrieve them blended with everything else. Our MCP server exposes exactly two tools — learn and query — against one shared store, so anything learned in one conversation is available to every assistant on the account in all future ones.
The payoff is that memories inherit everything the pipeline gives documents for free: provenance, content-addressed dedup, graph edges, deletion tombstones, per-account access control. A standalone memory store is a second, parallel knowledge base with none of those properties — and now you have two sources of truth to reconcile. "Compounding memory" isn't a product SKU; it's what happens when memory rides the ingest path.
Freshness is an ordering problem#
Vendor posts frame freshness as streaming-versus-batch: nightly refreshes bad, real-time good. True, but shallow. The hard freshness bug is a race: a document is deleted at time T while a stale add for that same document is still sitting in the pipeline from T-minus-five-minutes. Process them in the wrong order and the deleted document resurrects.
Our fix is a generational tombstone: every deletion records an invalidation timestamp taken from Redis's own clock — the same clock domain that stamps stream message IDs — so the indexer can compare them directly and drop exactly the in-flight writes enqueued before the delete, and nothing else. Freshness at the infrastructure level isn't "ingest fast"; it's "keep adds and deletes correctly ordered across a distributed pipeline." No storage tier gives you that. You have to engineer it.
Where the latency actually goes#
"Latency is a correctness property" is the load-bearing claim in the case for an in-memory context stack. But in an agent loop, the floor is the LLM call — seconds — and embedding inference — tens of milliseconds. Whether a vector lookup takes half a millisecond or thirty is invisible. We serve retrieval from pgvector, among other backends, without drama.
Where we actually bought latency, we bought it with concurrency and scheduling: entity extraction runs in parallel with vector search inside a single query; embedding runs on a shared GPU tier; and our indexer has two priority lanes with an anti-starvation ratio, so a million-document bulk backfill can't delay an interactive write. That last one really is latency-as-correctness — and it's a queueing design, not a memory tier.
Semantic caching deserves one caution here. Serving a cached answer to a paraphrase-similar query is a correctness hazard in exactly the systems these posts describe: personalized, permissioned, fresh. Two similar queries from different users must not share an answer; the same query from the same user fifteen minutes apart should differ as new context lands — our ranker has a session-affinity dimension precisely to make that happen. Exact-prefix prompt caching at the model provider gives you the savings without the hazard.
What we actually use Redis for#
None of this is anti-Redis. Here's our production rule, stated as strongly as we mean it: everything in Redis is either in-flight work or a rebuildable cache. Streams carry the pipeline (payloads offloaded to object storage, messages carry pointers); job counters, leases, and dead-letter streams coordinate it; watcher cursors and dedup sets track connector progress; presence hashes and pub/sub channels run the live surfaces; short-TTL caches absorb read bursts. If our Redis vanished, we'd lose in-flight work and warm caches — not one byte of memory, knowledge, or history.
flowchart LR
subgraph Sources
A[Uploads / API learns]
B[SaaS connectors]
C[Agent interactions]
end
subgraph Redis["Redis — transport & coordination (ephemeral)"]
F[fetch stream] --> P[parse stream] --> I[index streams]
end
subgraph Durable["Durable stores"]
V[(Vector backends)]
G[(Knowledge graph)]
R[(Postgres: resources, transcripts)]
S[(Object storage: originals)]
end
A --> F
B --> F
C --> F
I --> V
I --> G
I --> R
P --> S
V --> Q[Query: rank 11 dims, distill, budget]
G --> Q
R --> Q
Q --> LLM[Model context window]That's the honest version of "Redis for AI": a great coordination and ephemera layer used all over the industry — the fast, disposable tissue between durable stores. It's a market leader in that lane. It doesn't need to also be the memory, the vector index, and the semantic cache to matter.
Grade your application layer#
The maturity model in these posts asks whether your storage is navigable, fast, fresh, and compounding. Fair questions. But if you want to know why your agent hallucinated a return policy, audit the layer above: How are candidates ranked beyond cosine similarity? What gets cut when the window fills, and in what order? Do deletes race adds? Does what your agent learned on Tuesday change what it retrieves on Wednesday — for every assistant your team runs, not just the one that learned it?
Those are the questions context engineering actually names. Notice that none of them are storage engine uestions. They live in the layer above the database — the layer that decides what gets retrieved, how it's ranked, what gets cut, and what gets remembered.
The database vendors are right about one thing: you shouldn't have to be great at that layer to ship a reliable agent. They're just selling the wrong layer as the substitute. The stack that works has three tiers, not two — storage below, your agents and applications above, and in between a context platform whose whole job is ranking, assembly, freshness, and memory, exposed to your application as two verbs: learn and query.
That middle tier is Miriel. Your agents, your workflows, your product stay yours — they just sit on a platform where the eleven ranking dimensions, the token budgeter, the tombstone ordering, and the compounding memory are already built. Context engineering is an application problem. It just doesn't have to be your application's problem.


