Build1 distinct publisher3 min readPublished
The estimate was 30,000 to 40,000 credits per simulation, the gateway needed only three read patterns, and the store already holding tenant rows could serve all three, so tenancy became an argument every query passes.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
Credits are a unit on someone else's meter. The post gives consumption, 30,000 to 40,000 per simulation, and no rate [2][25], so the figure that transfers is the multiplier rather than the money: one run a day for a year is 10.95 to 14.6 million credits [23]. Against a weekly scenario that estimate is noise. Against a daily batch with reads served on top of it, the provider's availability, billing model and isolation semantics are now inside your read path [4].
What made the swap cheap was the read profile, not the database. The framing invites a bad design: reproduce the provider's graph product inside the gateway, then keep a second graph engine running beside MiroFish [11]. Two graph engines in one service is one more than a launch scope can staff. What actually shipped was three tables, graph_nodes for entities mirrored from the upstream graph, graph_edges for typed relationships, agent_episodes for round actions and their content vectors [15], sitting in the same transactional store as the existing records [9]. pgvector answered the semantic query without adding a network hop [10].
The isolation work is where owning the store pays. Both graph tables carry tenant_id and simulation_id, and unique constraints stop the same upstream entity or episode being written twice for one simulation [13]. Two tenants can hold a node with the same upstream identifier without either seeing the other's row [14]. Behind a service boundary that behaviour is whatever the provider implements, and you find out which it is during an incident, not during design [4].
The embedding path is built to make one coupling loud. Width is 384 because the in-process Xenova/all-MiniLM-L6-v2 emits exactly that shape, with mean pooling and normalized output [16]. The table definition, the embedding constant and the tests all name 384 [18], which is the author's argument that a silent dimensional mismatch is worse than a migration you planned [18]. The extractor initializes lazily behind one shared promise, so requests that never touch semantic search do not load the ONNX model and two concurrent callers do not start two loads [19]. The cost is cold-start latency on the first embedding request, accepted because this gateway runs long simulations, with pre-warming at startup held in reserve if search ever becomes an interactive first screen [20].
Two conditions carry the whole build case: the required traversals were bounded, and the semantic search was local [21]. Check both against your own workload before the credit estimate means anything, because the estimate describes the shape of this author's simulation, not yours. If your reads walk unbounded paths, or your embedding model is chosen by a vendor who updates it, the arithmetic above stops being the relevant arithmetic.
Ranked by verification strength, evidence, and original report placement.
A completed MiroFish simulation left the gateway able to display the final answer but unable to reliably ask its own questions of the evidence that produced it, because the useful memory lived behind another service boundary.
The project estimate put Zep consumption at 30,000 to 40,000 credits per simulation.
Daily runs would turn memory retrieval into a recurring external dependency before the gateway had served its first reader.
A provider-controlled memory layer made every later query depend on that provider's availability, billing model, and isolation semantics.
The author moved gateway-owned memory into PostgreSQL 16 with pgvector.
Zep was not removed from MiroFish: the upstream checkout still uses its configured graph provider while it constructs a graph.
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 29, 2026
Follow any of these and your For You feed starts watching them — no settings page required.
build
RLS Is a Planner Problem: One VOLATILE Function Turns a 3ms Index Scan Into 1.8 Seconds1 distinct publisher
build
Four control planes, one Postgres: a team's case against polyglot persistence1 distinct publisher
build
A RAG stack lived seven hours before a hosted embedding endpoint returned 4041 distinct publisher
build
Agent memory products differ on one thing: whether anything decides a fact is dead1 distinct publisher
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
One engineer's own account, redeemed by quoted code
The checkable part is the SQL. Because the searchEpisodes function is printed rather than paraphrased, a reader can confirm for themselves that tenant and simulation are predicates and that topK is clamped before it reaches the database — that is stronger evidence than most posts of this kind offer. Everything numeric is weaker: 30,000 to 40,000 credits is a project estimate, not an invoice, and there is not a single latency, recall or row-count figure to show the new store performs the three reads well.
One gateway, and only half of it moved
Adoption here is a single project that had not yet served a reader when the decision was made — and it is a partial move by the author's own admission, since MiroFish still builds its graph through the configured provider. What changed hands is the persisted copy and the reads against it. There are no other users, no downstream projects, and nothing that would tell you whether this pattern survives contact with a second team.
The headline he declined to write
Slightly understated, which is unusual. The obvious claim — Zep replaced — is refused outright, the scope limit is volunteered rather than extracted, and the review trigger is named: arbitrary path analysis across millions of edges would put the choice back on the table. The pull in the other direction is the credit figure, which carries rhetorical weight it has not earned, since no rate turns it into money and no bill confirms it.
The departing party writes the vendor's part
Zep's availability, billing model and per-simulation consumption are all described by the side that walked away, and the vendor has no voice anywhere in this reporting. The venue matters too: a dev.to decision post rewards a tidy arc, and tidy arcs rarely include the week the migration went sideways. No commercial or competitive interest is visible — the incentive on show is reputational, an engineer demonstrating judgement in public.
Firm on the design, thin on the numbers
We would stand behind the architecture as described: named versions, printed schema shapes, a quoted query, an explicitly pinned vector width. We would not stand behind any quantity. The credit band is unverified, the annualised figure is our arithmetic on it, and the money question stays open because the rate simply is not in the reporting. A second account — a bill, a benchmark, or an operator running the same stack — would move this materially.