<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mark Gyles</title>
    <description>The latest articles on DEV Community by Mark Gyles (@mgyles).</description>
    <link>https://dev.to/mgyles</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1602559%2Ff82af600-3936-4f4a-a067-dfee7a3228d4.jpg</url>
      <title>DEV Community: Mark Gyles</title>
      <link>https://dev.to/mgyles</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mgyles"/>
    <language>en</language>
    <item>
      <title>Agent memory benchmarks are baked</title>
      <dc:creator>Mark Gyles</dc:creator>
      <pubDate>Thu, 15 Oct 2026 09:19:13 +0000</pubDate>
      <link>https://dev.to/surrealdb/agent-memory-benchmarks-are-baked-ca8</link>
      <guid>https://dev.to/surrealdb/agent-memory-benchmarks-are-baked-ca8</guid>
      <description>&lt;p&gt;Author: &lt;a href="https://x.com/tobiemh" rel="noopener noreferrer"&gt;Tobie Morgan Hitchcock&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every agent memory vendor publishes a benchmark score. While most of these scores are true, very few of them measure the same thing.&lt;/p&gt;

&lt;p&gt;We read the test harnesses (the code that runs a benchmark), prompts, judge settings and per-question output files behind the published scores on &lt;a href="https://arxiv.org/abs/2510.27246" rel="noopener noreferrer"&gt;BEAM&lt;/a&gt; and &lt;a href="https://snap-research.github.io/locomo/" rel="noopener noreferrer"&gt;LoCoMo&lt;/a&gt;, two benchmarks for agent memory, and we did the same for our own. A memory benchmark score is the result of several choices: which model writes the answers, which model judges them, which prompts they get and which scoring rule turns the judgements into a number. Change any one of these and the score changes. Without them, a headline score is hard to interpret.&lt;/p&gt;

&lt;p&gt;This post describes what we found when we ran SurrealDB Agent Memory on these benchmarks, what we changed in our own run, and every number behind our headline score, including the ones that lower it.&lt;/p&gt;

&lt;h2&gt;
  
  
  A score is a recipe
&lt;/h2&gt;

&lt;p&gt;BEAM gives a memory system long conversations, up to ten million tokens, and then asks questions about them. An answering model writes each answer from what the memory system retrieves. For each question, the benchmark lists the points a correct answer must contain, called rubric items. A judge model scores each rubric item 0, 0.5 or 1, the question's score is the average of its items, and the headline is the mean across all questions.&lt;/p&gt;

&lt;p&gt;Each step has settings that a vendor chooses. Who answers? Who judges? Does the judge see the question? Does the answering prompt know what kind of question it is? Does half credit count? How is event ordering scored?&lt;/p&gt;

&lt;p&gt;While none of these settings is dishonest on its own, a headline score rarely says how they were set.&lt;/p&gt;

&lt;h2&gt;
  
  
  Five ways a score gets easier
&lt;/h2&gt;

&lt;p&gt;All of these practices appear in published runs. The code and output files for each are linked from our &lt;a href="https://surrealdb.com/agent-memory/benchmarks" rel="noopener noreferrer"&gt;benchmarks page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The answering prompt includes parts of the answer.&lt;/strong&gt; BEAM stores metadata with each question, such as the topics a correct answer has to put in order. &lt;a href="https://hindsight.vectorize.io/" rel="noopener noreferrer"&gt;Hindsight&lt;/a&gt;'s April 2026 harness and &lt;a href="https://exabase.io/" rel="noopener noreferrer"&gt;Exabase&lt;/a&gt;'s published prompt add fields from this metadata to the answering prompt. In Hindsight's own outputs, 66 of 70 event-ordering answers name every expected topic, and none of those topics appears in the question. &lt;a href="https://hydradb.com/" rel="noopener noreferrer"&gt;HydraDB&lt;/a&gt; says it reused Hindsight's original prompts unchanged, and it has published no outputs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The question category chooses the prompt.&lt;/strong&gt; BEAM sorts its questions into categories, such as event ordering and instruction following. Hindsight, Exabase and &lt;a href="https://www.cognee.ai/" rel="noopener noreferrer"&gt;Cognee&lt;/a&gt; choose an answering prompt based on the question's category, and &lt;a href="https://honcho.dev/" rel="noopener noreferrer"&gt;Honcho&lt;/a&gt; sends instruction-following questions through a separate pipeline. In production, a memory system does not know in advance what kind of question it is about to answer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The scoring rule gets more lenient.&lt;/strong&gt; The BEAM paper scores event ordering with Kendall tau, a measure of how closely the answer's order matches the correct order. A rubric average only checks whether each event is mentioned, in any order. &lt;a href="https://mem0.ai/" rel="noopener noreferrer"&gt;Mem0&lt;/a&gt; and Cognee use the rubric average. We use Kendall tau, as the paper does. Event ordering is our lowest-scoring category, so this choice lowers our mean, but it is the only rule of the two that checks whether the order is correct, which is what the category exists to test. Scored by rubric average, the same answers would read 79.3% instead of 77.2%.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. The retrieval budget grows.&lt;/strong&gt; Mem0's headline on BEAM 1M (the version with conversations of one million tokens) gives the answering model up to 200 memories. Mem0’s own files show a score of 64.1% with 200 memories and 60.4% with 50. Our published run gives the answering model the top 50 memories.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. On LoCoMo, the hardest questions are removed and the judge accepts near misses.&lt;/strong&gt; LoCoMo groups its questions into five categories. Category 5 holds the adversarial questions, which cannot be answered from the conversation, so a correct response says that the information is not there. Following the Mem0 paper, most published LoCoMo scores leave this category out. Mem0's judge also counts an answer as correct when it gives one correct item out of a list, or a date up to 14 days away from the right one. In April 2026, an &lt;a href="https://dev.to/penfieldlabs/we-audited-locomo-64-of-the-answer-key-is-wrong-and-the-judge-accepts-up-to-63-of-intentionally-33lg"&gt;audit by Penfield Labs&lt;/a&gt; found that LoCoMo's judge accepted 62.81% of answers that were deliberately wrong but on the right topic.&lt;/p&gt;

&lt;p&gt;The choice of models also affects the score. Most vendors use models from the same family to answer and to judge, and many use a stronger answering model than the original papers did. Some headline scores have no per-question files behind them at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Counting only full marks
&lt;/h2&gt;

&lt;p&gt;A BEAM mean hides partial credit. A question where every rubric item gets half marks scores 0.5, and it raises the mean just as a correct answer does.&lt;/p&gt;

&lt;p&gt;So we also counted something simpler: the share of questions where every rubric item got full marks. We call this the strict score. None of the vendors we compared publishes one, so we calculated it from their own per-question files wherever those files exist.&lt;/p&gt;

&lt;p&gt;On BEAM 1M:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;System&lt;/th&gt;
&lt;th&gt;Headline mean&lt;/th&gt;
&lt;th&gt;Strict&lt;/th&gt;
&lt;th&gt;Answering model&lt;/th&gt;
&lt;th&gt;Judge&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SurrealDB Agent Memory&lt;/td&gt;
&lt;td&gt;77.2%&lt;/td&gt;
&lt;td&gt;57.1%&lt;/td&gt;
&lt;td&gt;Gemini 3.8 Flash&lt;/td&gt;
&lt;td&gt;Gemini 3.5 Flash Lite&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exabase&lt;/td&gt;
&lt;td&gt;75.0%&lt;/td&gt;
&lt;td&gt;48.0%&lt;/td&gt;
&lt;td&gt;Gemini 3 Flash Preview&lt;/td&gt;
&lt;td&gt;Gemini 2.5 Flash-Lite&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hindsight&lt;/td&gt;
&lt;td&gt;73.9%&lt;/td&gt;
&lt;td&gt;48.4%&lt;/td&gt;
&lt;td&gt;Gemini 3.1 Pro Preview&lt;/td&gt;
&lt;td&gt;Gemini 2.5 Flash-Lite&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mem0 (top-200)&lt;/td&gt;
&lt;td&gt;64.1%&lt;/td&gt;
&lt;td&gt;40.1%&lt;/td&gt;
&lt;td&gt;GPT-5&lt;/td&gt;
&lt;td&gt;GPT-5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Honcho&lt;/td&gt;
&lt;td&gt;63.1%&lt;/td&gt;
&lt;td&gt;41.4%&lt;/td&gt;
&lt;td&gt;Claude Haiku 4.5&lt;/td&gt;
&lt;td&gt;Claude Sonnet 4.5 (harness default)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HydraDB&lt;/td&gt;
&lt;td&gt;82.0%&lt;/td&gt;
&lt;td&gt;Not countable&lt;/td&gt;
&lt;td&gt;Not stated&lt;/td&gt;
&lt;td&gt;GPT-5.4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every strict score we could count is between about 20 and 27 points below its headline mean. A gap of this size is expected, because the mean gives credit for answers that are partly correct. Publishing both numbers shows how much of each score comes from that partial credit.&lt;/p&gt;

&lt;p&gt;Read the table as a record of how each score was produced. The rows use different answering models, different judges and different retrieval budgets, so they cannot be ranked against each other.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we did in our own run
&lt;/h2&gt;

&lt;p&gt;We followed the BEAM paper wherever we could, and we list every place where we did not.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Same judge prompt.&lt;/strong&gt; The judge prompt is the official BEAM prompt. The judge model is Gemini 3.5 Flash Lite instead of the GPT-4.1 Mini that the authors' code uses, so the judge model is one of the ways our run differs from the paper.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nothing extra in the prompts.&lt;/strong&gt; The question category is never given to the answering model, and the judge sees the answer and the rubric but not the question.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Half marks counted, and shown separately.&lt;/strong&gt; The mean counts 0.5 scores, as the paper specifies. The strict score of 57.1% counts only full marks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Our own prompt and retrieval.&lt;/strong&gt; The run answers with the product's own prompt and retrieval, instead of the paper's baseline prompt with the top 5 results.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ten non-default settings.&lt;/strong&gt; We switched on ten retrieval and chat settings that the product does not enable by default. Eight change retrieval: &lt;code&gt;SPECTRON_RETRIEVAL_TURN_ORDER&lt;/code&gt;, &lt;code&gt;SPECTRON_RETRIEVAL_CLAIM_CONFLICTS&lt;/code&gt;, &lt;code&gt;SPECTRON_RETRIEVAL_GROUNDING_CHECK&lt;/code&gt;, &lt;code&gt;SPECTRON_RETRIEVAL_EPISODIC_TREE&lt;/code&gt;, &lt;code&gt;SPECTRON_RETRIEVAL_EVENT_DIGESTS&lt;/code&gt;, &lt;code&gt;SPECTRON_RETRIEVAL_TREE_BREADTH&lt;/code&gt;, &lt;code&gt;SPECTRON_RETRIEVAL_GROUNDING_PROVENANCE&lt;/code&gt; and &lt;code&gt;SPECTRON_RETRIEVAL_TREE_ADAPTIVE_BUDGET&lt;/code&gt;. Two change how the chat answer is written: &lt;code&gt;SPECTRON_CHAT_ANSWER_CONTRACTS&lt;/code&gt; and &lt;code&gt;SPECTRON_CHAT_STANDING_INSTRUCTIONS&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event ordering scored by Kendall tau.&lt;/strong&gt; As in the paper, the score checks whether the order is correct. We score 49.7% in this category, and 1 of its 70 questions gets full marks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failures score zero.&lt;/strong&gt; When a judge call fails twice, the rubric item scores 0, and a score outside the range 0 to 1 is clamped to that range. The BEAM reference code stops scoring the whole conversation instead.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On LoCoMo, our strict score is 75.8% across all five categories, including the adversarial one, over 1,986 questions. Under Mem0's own protocol, which leaves out the adversarial category and uses the more lenient judge, the same system scores 92.6% with GPT-5 answering and judging, and 90.1% with GPT-OSS 120B answering and GPT-4o judging. We publish all three numbers together so that readers can compare them directly.&lt;/p&gt;

&lt;p&gt;Our 700 BEAM 1M answers are published on the &lt;a href="https://surrealdb.com/agent-memory/benchmarks" rel="noopener noreferrer"&gt;benchmarks page&lt;/a&gt;, each with its question and rubric, so you can grade them with any judge you like. The harness commands are not public yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Be your own judge
&lt;/h2&gt;

&lt;p&gt;Before you trust any memory benchmark score, including ours, ask five questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Which model answered, and which model judged?&lt;/li&gt;
&lt;li&gt;Did the prompt know the question's category, or any part of the answer?&lt;/li&gt;
&lt;li&gt;Does the headline include partial credit, and what is the strict score?&lt;/li&gt;
&lt;li&gt;How much context did the answering model get?&lt;/li&gt;
&lt;li&gt;Are the per-question files published, so that you can check the count yourself?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A score that comes with answers to all five can be checked. A score without them has to be taken on trust.&lt;/p&gt;

&lt;p&gt;Every run, judge, protocol and vendor comparison is on our &lt;a href="https://surrealdb.com/agent-memory/benchmarks" rel="noopener noreferrer"&gt;benchmarks page&lt;/a&gt;, with sources linked for every claim.&lt;/p&gt;

</description>
      <category>agentmemory</category>
      <category>ai</category>
      <category>agents</category>
      <category>news</category>
    </item>
    <item>
      <title>Introducing SurrealDB Agent Memory</title>
      <dc:creator>Mark Gyles</dc:creator>
      <pubDate>Thu, 15 Oct 2026 08:51:50 +0000</pubDate>
      <link>https://dev.to/surrealdb/introducing-surrealdb-agent-memory-e8p</link>
      <guid>https://dev.to/surrealdb/introducing-surrealdb-agent-memory-e8p</guid>
      <description>&lt;p&gt;Author: &lt;a href="https://x.com/tobiemh" rel="noopener noreferrer"&gt;Tobie Morgan Hitchcock&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AI agents have a memory problem: most of what they know lives either in the current context window, in local siloed memory solutions, or in an external retrieval system.&lt;/p&gt;

&lt;p&gt;That works up to a point. But once an agent needs to remember information across sessions, distinguish current facts from old ones, understand relationships between entities, or explain where a fact came from, storing conversation history or embedding chunks into a vector database stops being enough.&lt;/p&gt;

&lt;p&gt;Today, we’re introducing &lt;strong&gt;SurrealDB Agent Memory&lt;/strong&gt;, a memory and knowledge layer for AI agents built on SurrealDB. It takes conversations, documents, and structured data and turns them into persistent, queryable memory: entities, attributes, relationships, instructions, source information, embeddings, and retrieval traces stored together in SurrealDB.&lt;/p&gt;

&lt;p&gt;The goal is fairly simple: give agents persistent state that can change over time without losing track of what changed, when it changed, or why.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we benchmark Agent Memory
&lt;/h2&gt;

&lt;p&gt;Memory benchmarks are easy to quote and hard to compare. Scores can vary significantly depending on the answering model, judge model, number of retrieved results, and which settings are enabled. So we’ve published our results, methodology, and configuration on a dedicated &lt;a href="https://surrealdb.com/agent-memory/benchmarks" rel="noopener noreferrer"&gt;benchmarks page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On &lt;strong&gt;BEAM 1M&lt;/strong&gt;, a long-term memory benchmark based on conversations of around one million tokens, Agent Memory scores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;77.2%&lt;/strong&gt; mean score&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;57.1%&lt;/strong&gt; strict accuracy, where an answer only counts if it is fully correct&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;82.9%&lt;/strong&gt; of questions scoring at least 0.5&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We report strict accuracy alongside the mean because partially correct answers can raise the average. Strict accuracy shows how often the system produced a fully correct answer, which is an important distinction for production use.&lt;/p&gt;

&lt;p&gt;We also document where our run differs from the reference setup. The 77.2% result uses Agent Memory’s own retrieval and prompting pipeline rather than the paper’s top-5 baseline, enables ten retrieval and chat settings that are not on by default, and uses a different judge model from the authors’ reference implementation. Our weakest category is &lt;strong&gt;event ordering&lt;/strong&gt;, at &lt;strong&gt;49.7%&lt;/strong&gt;. Temporal reasoning remains an area we are actively working to improve.&lt;/p&gt;

&lt;p&gt;Our reporting follows four rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Name the models.&lt;/strong&gt; Every result identifies both the answering and grading models.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Show strict accuracy alongside the mean.&lt;/strong&gt; We don’t report only the more favorable aggregate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid ranking claims.&lt;/strong&gt; Different models, judges, retrieval settings, and configurations can make leaderboards compare setups rather than systems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document every deviation.&lt;/strong&gt; Any departure from the benchmark’s reference methodology is listed explicitly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Where other vendors publish per-question results, we calculate strict accuracy from those files using the same method. The benchmarks page also documents eleven practices that can materially affect scores and shows which apply to each published result, including ours.&lt;/p&gt;

&lt;p&gt;We’ll publish our per-question results and run configuration so the numbers can be independently checked. Results for &lt;strong&gt;BEAM 10M&lt;/strong&gt; and &lt;strong&gt;LoCoMo&lt;/strong&gt; are available on the same page.&lt;/p&gt;

&lt;h2&gt;
  
  
  From retrieval to structured, evolving memory
&lt;/h2&gt;

&lt;p&gt;The simplest implementation of agent memory is to store previous messages, generate embeddings, and retrieve the most similar chunks when the agent needs context. That works for basic recall, but it becomes harder to manage as information changes over time.&lt;/p&gt;

&lt;p&gt;If a user first says: "&lt;em&gt;I work at Pied Piper as VP of Engineering&lt;/em&gt;&lt;em&gt;" and later says: "*I’ve moved to Hooli as CTO&lt;/em&gt;"&lt;em&gt;, both statements may be relevant to the question “*Where does this person work?&lt;/em&gt;”. Similarity alone does not tell the system which one is current. SurrealDB Agent Memory treats this as a state-management problem, not just a retrieval problem.&lt;/p&gt;

&lt;p&gt;When new information arrives, it is first extracted into structured memory such as entities, attributes, relationships, instructions, and uncertainties. That structured information is then reconciled against what the system already knows.&lt;/p&gt;

&lt;p&gt;Reconciliation determines whether the new information should be added, update an existing fact, supersede an older one, or remain uncertain because sources disagree. So instead of storing a growing collection of disconnected chunks, Agent Memory maintains an evolving model of what is currently believed, what was true previously, and how that state changed over time.&lt;/p&gt;

&lt;p&gt;This makes it possible to answer both: "&lt;em&gt;Gilfoyle’s role now is CTO&lt;/em&gt;" and "&lt;em&gt;Gilfoyle's role last year was VP of Engineering&lt;/em&gt;". The older fact is not deleted. It remains part of the historical record while the newer fact becomes current.&lt;/p&gt;

&lt;h2&gt;
  
  
  Every fact keeps its source
&lt;/h2&gt;

&lt;p&gt;A useful memory system should be able to answer more than “&lt;em&gt;What do I know?&lt;/em&gt;”. It should also be able to answer:&lt;em&gt;"Where did I learn this?&lt;/em&gt;". Fact-bearing records in Agent Memory carry structured provenance. This can include the originating conversation or document, the location of the source text, the source type, its trust level, and lineage when a fact was derived from other information. This means an application can trace a stored fact back to the conversation turn or document passage that produced it.&lt;/p&gt;

&lt;p&gt;That is useful when debugging an agent, but it also changes how applications can present answers. Instead of simply generating a response and hoping the retrieved context was correct, applications can expose the underlying sources that contributed to it. Agent Memory also stores retrieval, reconciliation, and response traces, making it possible to inspect which records were considered and how a stored belief changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Time is part of the data model
&lt;/h2&gt;

&lt;p&gt;Facts often have more than one relevant timestamp. Something may have been true in January, mentioned in March, and stored by the database in April.&lt;/p&gt;

&lt;p&gt;Agent Memory uses a tri-temporal model to distinguish different notions of time, including when information was valid in the real world, when the system knew about it, and the database's own transaction history.&lt;/p&gt;

&lt;p&gt;This lets applications ask questions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is true now?&lt;/li&gt;
&lt;li&gt;What did we believe last month?&lt;/li&gt;
&lt;li&gt;What was true at a specific point in time?&lt;/li&gt;
&lt;li&gt;When was this information corrected?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without temporal modelling, older and newer facts tend to become competing chunks in the retrieval layer. With temporal state, the database itself can distinguish current information from historical information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documents and conversations in one graph
&lt;/h2&gt;

&lt;p&gt;Agents typically need two types of information: &lt;strong&gt;authoritative knowledge&lt;/strong&gt; (policies, documentation, repositories, product data, manuals, and other curated sources) and &lt;strong&gt;experiential knowledge&lt;/strong&gt; (what users said, decisions made during previous sessions, preferences, observations, and things the agent itself has learned). Agent Memory stores both in one SurrealDB substrate rather than maintaining separate databases for documents, conversations, vectors, and relationships.&lt;/p&gt;

&lt;p&gt;Because SurrealDB supports multiple data models in the same database, documents, entities, relations, embeddings, and traces can be stored and queried together under the same transactional system. That means a retrieval query can combine several different signals rather than requiring application code to join results from separate systems, improving accuracy, retrieval latency, and LLM token usage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retrieval is hybrid
&lt;/h2&gt;

&lt;p&gt;Not every memory question is a semantic-search problem. Finding a paraphrased passage benefits from vector search. Finding an exact product ID benefits from full-text search. Finding something related to a particular customer, person, or project can benefit from graph relationships.&lt;/p&gt;

&lt;p&gt;Agent Memory supports hybrid retrieval across these different signals. Vector similarity, full-text search, graph structure, and other ranking inputs can contribute to the same retrieval process. It also uses a tiered read path.&lt;/p&gt;

&lt;p&gt;Simple questions can resolve directly against structured memory. Previously generated responses can sometimes be reused when the facts they depended on remain current. More complex questions can escalate to broader hybrid retrieval and model synthesis.&lt;/p&gt;

&lt;p&gt;This is useful because asking “&lt;em&gt;What timezone does this user prefer&lt;/em&gt;?” should not necessarily require the same retrieval and inference path as “&lt;em&gt;Summarise everything relevant to this customer's current project.&lt;/em&gt;”&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory has a lifecycle
&lt;/h2&gt;

&lt;p&gt;Not everything an agent learns should remain equally important forever. Agent Memory separates three different operations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Supersession&lt;/strong&gt; handles information that has been replaced. The previous fact remains in history but is no longer current.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decay&lt;/strong&gt; reduces the importance of information as it becomes less relevant, while allowing frequently useful memories to be reinforced.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forget&lt;/strong&gt; removes information from the agent's active working set when explicit removal is required.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keeping these concepts separate prevents a common problem where “old,” “wrong,” and “deleted” all end up meaning the same thing. They are not the same thing, and applications often need different behaviour for each.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scoping memory to the right user, team, or agent
&lt;/h2&gt;

&lt;p&gt;Memory is only useful if the agent retrieves the right information for the current situation. SurrealDB Agent Memory uses &lt;strong&gt;scopes&lt;/strong&gt; to partition memory within a Context. A scope is a hierarchical path such as: &lt;code&gt;org/piedpiper/user/gilfoyle&lt;/code&gt; or &lt;code&gt;org/piedpiper/project/thebox&lt;/code&gt;. This lets applications decide which memories belong to an organisation, user, team, project, or another boundary that makes sense for the product.&lt;/p&gt;

&lt;p&gt;For example, a customer-support agent might store company-wide policies at: &lt;code&gt;org/piedpiper&lt;/code&gt; while Gilfoyle's preferences and previous interactions live under: &lt;code&gt;org/piedpiper/user/hooli&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When the agent is working with Gilfoyle, it can retrieve both the organisation-level knowledge and Gilfoyle's own memory without exposing another user's information. Session scopes are also propagated to the records created during that session, so new memories remain attributed to the right part of the application.&lt;/p&gt;

&lt;p&gt;Scopes are different from permissions. Scope determines where a memory belongs; grants determine who is allowed to read or write it. Together, they provide a practical way to build multi-user and multi-tenant agents without maintaining a separate memory database for every user.&lt;/p&gt;

&lt;p&gt;For stronger isolation, Agent Memory uses &lt;strong&gt;Contexts&lt;/strong&gt;. A useful rule is: scopes partition data within the same application; Contexts separate entirely different memory environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built on SurrealDB
&lt;/h2&gt;

&lt;p&gt;Agent Memory runs as an application layer in front of SurrealDB. A Context provides the isolation boundary for a memory environment, with its own SurrealDB namespace and database. Within a Context, conversations, documents, entities, relationships, embeddings, traces, and other memory state live together.&lt;/p&gt;

&lt;p&gt;Contexts are managed through SurrealDB Studio, where developers can work with conversations, inspect known entities, upload documents, explore the knowledge graph, and see what the system retrieved and learned during individual interactions.&lt;/p&gt;

&lt;p&gt;Applications can integrate through the REST API, MCP, Python and TypeScript SDKs, or adapters for agent frameworks including LangChain, OpenAI Agents, and Vercel AI SDK.&lt;/p&gt;

&lt;p&gt;A basic workflow looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Remember&lt;/strong&gt;: Send a conversation turn, document, or fact to Agent Memory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extract&lt;/strong&gt;: Convert unstructured input into entities, attributes, relationships, instructions, and other structured state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reconcile&lt;/strong&gt;: Compare that information with existing memory and decide what is new, what changed, and where uncertainty exists.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Store&lt;/strong&gt;: Write the resulting state, provenance, embeddings, relationships, and traces into SurrealDB.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recall&lt;/strong&gt;: Query memory through structured lookups or hybrid retrieval, scoped to the relevant user, agent, organisation, or application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That creates a loop in which the agent's state can continue evolving between conversations instead of being reconstructed from scratch every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory as persistent application state
&lt;/h2&gt;

&lt;p&gt;We think agent memory becomes much easier to reason about once it is treated less like a cache around an LLM and more like persistent application state. Agents need to know what is currently true, what used to be true, where information came from, which sources should be trusted, and how different pieces of information relate to one another. Those are fundamentally data problems.&lt;/p&gt;

&lt;p&gt;SurrealDB Agent Memory brings those capabilities together in one layer: structured memory, document knowledge, graph relationships, temporal history, provenance, reconciliation, and retrieval, backed by SurrealDB.&lt;/p&gt;

&lt;p&gt;The result is agents that do not simply retrieve previous text, but can can maintain a persistance, queryable shared memory layer of what it has learned - and update that layer as the world changes. &lt;a href="https://studio.surrealdb.com/current/contexts" rel="noopener noreferrer"&gt;Get started with Agent Memory&lt;/a&gt; or &lt;a href="https://surrealdb.com/docs/agent-memory" rel="noopener noreferrer"&gt;explore the documentation&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>surrealdb</category>
      <category>agentmemory</category>
      <category>ai</category>
      <category>agents</category>
    </item>
    <item>
      <title>We are replacing RocksDB with SurrealKV 1.0</title>
      <dc:creator>Mark Gyles</dc:creator>
      <pubDate>Wed, 14 Oct 2026 08:30:00 +0000</pubDate>
      <link>https://dev.to/surrealdb/we-are-replacing-rocksdb-with-surrealkv-10-4pi9</link>
      <guid>https://dev.to/surrealdb/we-are-replacing-rocksdb-with-surrealkv-10-4pi9</guid>
      <description>&lt;p&gt;Author: &lt;a href="https://x.com/tobiemh" rel="noopener noreferrer"&gt;Tobie Morgan Hitchcock&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SurrealKV 1.0 is a new open source persistent storage engine for SurrealDB, written in Rust and released under Apache 2.0 on 13 October 2026. With synchronous durability, it reads 7.95× faster than RocksDB and 73.7× faster than SlateDB, and it will be the only persistent storage engine in SurrealDB 4.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why replace RocksDB?
&lt;/h2&gt;

&lt;p&gt;RocksDB is a very good engine, and SurrealDB has run on it for years. It is also a large C++ library that SurrealDB does not control. SurrealKV is an engine we can read from end to end, change when SurrealDB needs it to change, and ship as a Rust crate.&lt;/p&gt;

&lt;p&gt;SurrealKV is a log-structured merge-tree with snapshot-isolated transactions. It runs embedded in an application and as the storage layer of a SurrealDB server.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does SurrealKV reach these numbers?
&lt;/h2&gt;

&lt;p&gt;Three design decisions each remove shared work or shared waiting from a hot path.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A radix-tree memtable.&lt;/strong&gt; Writes land in a concurrent adaptive radix tree allocated from a fixed arena. RocksDB and Pebble use skiplists.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A commit ring.&lt;/strong&gt; Many committers validate their transactions at the same time. One flusher task then orders what has accumulated into a group, appends it to the write-ahead log with at most one fsync, applies it to the memtable and publishes it. A burst of commits costs one log append.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cheap reads.&lt;/strong&gt; A read pins a sequence number and nothing else.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What else does SurrealKV include?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Versioned trees&lt;/strong&gt;, opt in. &lt;code&gt;get_at&lt;/code&gt; reads a key as of a time, &lt;code&gt;history&lt;/code&gt; returns every version of a key, and compaction keeps versions for a retention period that you set.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Value separation&lt;/strong&gt;, opt in, for values larger than 1 KiB, so that compaction does not rewrite large values again and again.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encryption at rest&lt;/strong&gt;, transparent, with AES-256-GCM or XChaCha20-Poly1305.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Differential testing&lt;/strong&gt; against an in-memory reference model: 500 seeds of 5,000 steps each, 2,500,000 operations, in every CI run. Any divergence fails the run.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What do the benchmarks show?
&lt;/h2&gt;

&lt;p&gt;With synchronous durability, every commit is flushed to disk before it returns. SurrealKV 1.0 delivered these results on 13 October 2026:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Engine&lt;/th&gt;
&lt;th&gt;Point reads (OPS)&lt;/th&gt;
&lt;th&gt;Creates (OPS)&lt;/th&gt;
&lt;th&gt;Updates (OPS)&lt;/th&gt;
&lt;th&gt;Deletes (OPS)&lt;/th&gt;
&lt;th&gt;Scans (OPS)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SurrealKV&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6,804,864&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;229,376&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;221,341&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;264,089&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;905,132&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RocksDB&lt;/td&gt;
&lt;td&gt;855,851&lt;/td&gt;
&lt;td&gt;8,568&lt;/td&gt;
&lt;td&gt;36,263&lt;/td&gt;
&lt;td&gt;32,043&lt;/td&gt;
&lt;td&gt;852,661&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SlateDB&lt;/td&gt;
&lt;td&gt;92,303&lt;/td&gt;
&lt;td&gt;8,257&lt;/td&gt;
&lt;td&gt;8,122&lt;/td&gt;
&lt;td&gt;8,242&lt;/td&gt;
&lt;td&gt;17,985&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Against RocksDB, SurrealKV is 7.95× faster on point reads, 6.10× faster on updates, 8.24× faster on deletes and 1.06× faster on range scans. Against SlateDB, which ran on local disk and not on object storage, it is 73.7× faster on point reads and 27.3× faster on updates.&lt;/p&gt;

&lt;p&gt;SurrealKV creates records 26.8× faster than RocksDB. RocksDB's create rate with synchronous durability is far below its own update rate of 36,263 operations a second, and we have not explained why, so this post does not headline it.&lt;/p&gt;

&lt;p&gt;The benchmark ran with &lt;a href="https://github.com/surrealdb/crud-bench" rel="noopener noreferrer"&gt;crud-bench&lt;/a&gt; on an AMD Ryzen Threadripper 9970X (32 cores, 64 threads) with 128 GB of RAM and a 4 TB NVMe SSD. It used 500,000 keys, 48 worker threads and 128 clients. The harness runs SurrealKV with value separation on and a larger memtable than the engine's defaults. Each figure is a single run. Fjall, ReDB, LMDB and libmdbx are not in the table, because their runs with synchronous durability were too slow to finish at this dataset size.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where is RocksDB faster?
&lt;/h2&gt;

&lt;p&gt;Without synchronous durability, RocksDB is faster at writes. SurrealKV is 1.88× slower on creates, 2.22× slower on updates and 2.41× slower on deletes, and 8.26× faster on point reads.&lt;/p&gt;

&lt;p&gt;Without synchronous durability, the engines also make different promises about what survives a crash, so those figures measure speed and not safety. Only the synchronous-durability table compares engines that each flush before acknowledging.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do range scans compare?
&lt;/h2&gt;

&lt;p&gt;Without synchronous durability, SurrealKV scans the first 100 key-value pairs of the dataset 896,366 times a second. LMDB leads that scan at 1,192,772 scans a second, and RocksDB manages 851,848. The table shows scans per second over the same 500,000 keys, with 5,000,000 iterations of each scan.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Engine&lt;/th&gt;
&lt;th&gt;Limit (OPS)&lt;/th&gt;
&lt;th&gt;Keys, limit (OPS)&lt;/th&gt;
&lt;th&gt;Skip + limit (OPS)&lt;/th&gt;
&lt;th&gt;Keys, skip + limit (OPS)&lt;/th&gt;
&lt;th&gt;Full count (OPS)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SurrealKV&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;896,366&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2,313,942&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;96,365&lt;/td&gt;
&lt;td&gt;98,612&lt;/td&gt;
&lt;td&gt;402&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RocksDB&lt;/td&gt;
&lt;td&gt;851,848&lt;/td&gt;
&lt;td&gt;851,580&lt;/td&gt;
&lt;td&gt;35,539&lt;/td&gt;
&lt;td&gt;35,902&lt;/td&gt;
&lt;td&gt;159&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SlateDB&lt;/td&gt;
&lt;td&gt;26,187&lt;/td&gt;
&lt;td&gt;26,266&lt;/td&gt;
&lt;td&gt;7,460&lt;/td&gt;
&lt;td&gt;7,477&lt;/td&gt;
&lt;td&gt;87&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fjall&lt;/td&gt;
&lt;td&gt;132,698&lt;/td&gt;
&lt;td&gt;151,861&lt;/td&gt;
&lt;td&gt;4,335&lt;/td&gt;
&lt;td&gt;4,383&lt;/td&gt;
&lt;td&gt;42.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ReDB&lt;/td&gt;
&lt;td&gt;561,837&lt;/td&gt;
&lt;td&gt;571,629&lt;/td&gt;
&lt;td&gt;44,438&lt;/td&gt;
&lt;td&gt;44,462&lt;/td&gt;
&lt;td&gt;249&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LMDB&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1,192,772&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1,195,166&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;549,220&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;552,090&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;902&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;libmdbx&lt;/td&gt;
&lt;td&gt;384,128&lt;/td&gt;
&lt;td&gt;260,769&lt;/td&gt;
&lt;td&gt;183,361&lt;/td&gt;
&lt;td&gt;185,073&lt;/td&gt;
&lt;td&gt;848&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Limit&lt;/strong&gt; (&lt;code&gt;select(*) limit(100)&lt;/code&gt;) returns the first 100 key-value pairs of the range. &lt;strong&gt;Keys, limit&lt;/strong&gt; (&lt;code&gt;select(id) limit(100)&lt;/code&gt;) returns only the keys.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skip + limit&lt;/strong&gt; (&lt;code&gt;select(*) start(5000) limit(100)&lt;/code&gt;) walks and discards 5,000 entries before returning 100. &lt;strong&gt;Keys, skip + limit&lt;/strong&gt; returns only the keys.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full count&lt;/strong&gt; (&lt;code&gt;count()&lt;/code&gt;) visits every key in the range.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Against RocksDB, SurrealKV is 1.05× faster on the first 100 pairs, 2.72× faster on a keys-only scan of the first 100 entries, 2.71× faster on scans that skip 5,000 entries and 2.53× faster on full counts. SurrealKV leads every engine on the keys-only scan, at 2,313,942 scans a second.&lt;/p&gt;

&lt;p&gt;LMDB leads SurrealKV on the first 100 key-value pairs (1.33× faster), on scans that skip 5,000 entries (5.70× faster) and on full counts (2.24× faster).&lt;/p&gt;

&lt;h2&gt;
  
  
  How much memory does SurrealKV use?
&lt;/h2&gt;

&lt;p&gt;SurrealKV has the lowest resting memory of the seven engines measured, at 221 MiB, against 590 MiB for RocksDB. Resting and peak memory are the lowest and highest process memory sampled across the whole benchmark run, without synchronous durability.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Engine&lt;/th&gt;
&lt;th&gt;Resting memory&lt;/th&gt;
&lt;th&gt;Peak memory&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SurrealKV&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;221 MiB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1.79 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RocksDB&lt;/td&gt;
&lt;td&gt;590 MiB&lt;/td&gt;
&lt;td&gt;1.02 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SlateDB&lt;/td&gt;
&lt;td&gt;265 MiB&lt;/td&gt;
&lt;td&gt;2.73 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fjall&lt;/td&gt;
&lt;td&gt;627 MiB&lt;/td&gt;
&lt;td&gt;1.71 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ReDB&lt;/td&gt;
&lt;td&gt;257 MiB&lt;/td&gt;
&lt;td&gt;2.17 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LMDB&lt;/td&gt;
&lt;td&gt;776 MiB&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;826 MiB&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;libmdbx&lt;/td&gt;
&lt;td&gt;40.98 GiB&lt;/td&gt;
&lt;td&gt;117.71 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;SurrealKV's peak memory of 1.79 GiB is higher than that of RocksDB (1.02 GiB) and LMDB (826 MiB), because parallel commits buffer active batches. The libmdbx figures are what the harness measured, and we have not investigated them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where is the design written down?
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://surrealdb.com/static/whitepapers/surrealkv.pdf" rel="noopener noreferrer"&gt;SurrealKV whitepaper&lt;/a&gt;, "A Versioned LSM Engine with Radix-Tree Memtables and a Commit Ring", explains how SurrealKV reaches these numbers, what each design decision costs and what the measurements do not cover.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can you run the benchmark yourself?
&lt;/h2&gt;

&lt;p&gt;Every figure comes from one command on one machine. Run it on your own hardware:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;CRUD_BENCH_CONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;config/memory.toml ./run.sh &lt;span class="nt"&gt;-d&lt;/span&gt; surrealkv &lt;span class="nt"&gt;--no-build&lt;/span&gt; &lt;span class="nt"&gt;--optimised&lt;/span&gt; &lt;span class="nt"&gt;--sync&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; 500000 &lt;span class="nt"&gt;-c&lt;/span&gt; 128 &lt;span class="nt"&gt;-t&lt;/span&gt; 48
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change the &lt;code&gt;-d&lt;/code&gt; flag to run a comparator, and remove &lt;code&gt;--sync&lt;/code&gt; to run without synchronous durability. If you find a fairer configuration for a comparator, open an issue or a pull request on the &lt;a href="https://github.com/surrealdb/crud-bench" rel="noopener noreferrer"&gt;crud-bench repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;SurrealKV is open source on &lt;a href="https://github.com/surrealdb/surrealkv" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. To use it in a Rust project, add the crate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo add surrealkv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Speed or durability? Yes. Stop choosing.&lt;/p&gt;

</description>
      <category>database</category>
      <category>news</category>
      <category>opensource</category>
      <category>storageengine</category>
    </item>
    <item>
      <title>Our commitment to open source: show the code, run the numbers</title>
      <dc:creator>Mark Gyles</dc:creator>
      <pubDate>Tue, 13 Oct 2026 09:03:27 +0000</pubDate>
      <link>https://dev.to/surrealdb/our-commitment-to-open-source-show-the-code-run-the-numbers-3oj7</link>
      <guid>https://dev.to/surrealdb/our-commitment-to-open-source-show-the-code-run-the-numbers-3oj7</guid>
      <description>&lt;p&gt;Author: &lt;a href="https://x.com/tobiemh" rel="noopener noreferrer"&gt;Tobie Morgan Hitchcock&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We commit to three things: show the code, run the numbers, and say what we did not measure. SurrealKV and SurrealMX are open source under Apache 2.0, SurrealDB is source available under the Business Source License 1.1, and every benchmark we publish comes with the command, the hardware and the method behind it.&lt;/p&gt;

&lt;p&gt;A database is a trust relationship. It holds your data, it decides what survives a crash, and it decides who can see what. Infrastructure that agents depend on, running unattended at a scale nobody can supervise, has to earn that trust in a way anyone can check. This post sets out how we intend to earn it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why does SurrealDB publish its code?
&lt;/h2&gt;

&lt;p&gt;A claim about a database is only worth what you can check. There are three ways to check ours: read the code, run the benchmark, and read the paper that explains the design and its limits. We publish all three.&lt;/p&gt;

&lt;p&gt;That is why you can read the SurrealDB source, why the two new storage engines are open source, and why every benchmark we publish comes with the command to run it. When a database tells you it is fast, correct or safe, you should not have to take its word for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does source available mean?
&lt;/h2&gt;

&lt;p&gt;We use two terms and keep them apart.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Source available&lt;/strong&gt; means you can read the code and run it yourself, under a licence that restricts some uses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open source&lt;/strong&gt; means an Apache 2.0 or MIT licence with no such restriction.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SurrealDB is source available. It is released under the Business Source License 1.1, which is free for internal use and converts to Apache 2.0 after four years. SurrealDB Cloud and Enterprise Edition are commercial products. Everything this post calls open source is under Apache 2.0 or MIT.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is open source today?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Project&lt;/th&gt;
&lt;th&gt;Licence&lt;/th&gt;
&lt;th&gt;What it is&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/surrealdb/surrealkv" rel="noopener noreferrer"&gt;SurrealKV 1.0&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Apache 2.0&lt;/td&gt;
&lt;td&gt;A persistent storage engine: a log-structured merge-tree with snapshot-isolated transactions and optional versioned trees, built on a concurrent adaptive radix tree memtable and a commit ring. It will be the only persistent storage engine in SurrealDB 4.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/surrealdb/surrealmx" rel="noopener noreferrer"&gt;SurrealMX 1.0&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Apache 2.0&lt;/td&gt;
&lt;td&gt;An in-memory storage engine: multi-version concurrency control over a concurrent adaptive radix tree, with lock-free reads and optional persistence.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/surrealdb/crud-bench" rel="noopener noreferrer"&gt;crud-bench&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Apache 2.0&lt;/td&gt;
&lt;td&gt;The benchmark harness behind every performance number we publish.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Our SDKs and tools, and many of the libraries beneath SurrealDB, are also open source under Apache 2.0 or MIT. The full list is at &lt;a href="https://surrealdb.com/opensource" rel="noopener noreferrer"&gt;surrealdb.com/opensource&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Each storage engine has a whitepaper. It explains how the engine reaches its performance, what we measured, and what we did not. We will also publish accompanying technical or academic papers for a number of our product launches.&lt;/p&gt;

&lt;h2&gt;
  
  
  What stays open source?
&lt;/h2&gt;

&lt;p&gt;The storage engines, our SDKs and tools, and the libraries listed at &lt;a href="https://surrealdb.com/opensource" rel="noopener noreferrer"&gt;surrealdb.com/opensource&lt;/a&gt; stay open source, under Apache 2.0 or MIT.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can I run the benchmarks myself?
&lt;/h2&gt;

&lt;p&gt;Every performance number we publish comes from &lt;a href="https://github.com/surrealdb/crud-bench" rel="noopener noreferrer"&gt;crud-bench&lt;/a&gt;, on one machine: an AMD Ryzen Threadripper 9970X (32 cores, 64 threads) with 128 GB of RAM and a 4 TB NVMe SSD. The same harness and the same command run each comparator, so a number and the number it is compared with are measured the same way.&lt;/p&gt;

&lt;p&gt;We say what we compared. When an engine runs in memory, we say it runs in memory. When we compare against an engine on disk, we say it is on disk.&lt;/p&gt;

&lt;p&gt;SurrealKV runs with synchronous durability, against RocksDB, SlateDB (on disk, not object storage), Fjall, ReDB, LMDB and libmdbx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;CRUD_BENCH_CONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;config/memory.toml ./run.sh &lt;span class="nt"&gt;-d&lt;/span&gt; surrealkv &lt;span class="nt"&gt;--no-build&lt;/span&gt; &lt;span class="nt"&gt;--optimised&lt;/span&gt; &lt;span class="nt"&gt;--sync&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; 500000 &lt;span class="nt"&gt;-c&lt;/span&gt; 128 &lt;span class="nt"&gt;-t&lt;/span&gt; 48
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SurrealMX runs against LMDB and RocksDB, both in memory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;CRUD_BENCH_CONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;config/memory.toml ./run.sh &lt;span class="nt"&gt;-d&lt;/span&gt; surrealmx &lt;span class="nt"&gt;--no-build&lt;/span&gt; &lt;span class="nt"&gt;--optimised&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; 15000000 &lt;span class="nt"&gt;-c&lt;/span&gt; 128 &lt;span class="nt"&gt;-t&lt;/span&gt; 48
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change the &lt;code&gt;-d&lt;/code&gt; flag to run a comparator.&lt;/p&gt;

&lt;p&gt;Run it on your own hardware. If you find a fairer configuration for a comparator, or an engine we should have included, open an issue or a pull request on &lt;a href="https://github.com/surrealdb/crud-bench" rel="noopener noreferrer"&gt;crud-bench&lt;/a&gt;. A benchmark that only we can run is not a benchmark.&lt;/p&gt;

&lt;h2&gt;
  
  
  Whose work does SurrealDB build on?
&lt;/h2&gt;

&lt;p&gt;None of this started with us. SurrealKV belongs to the line of log-structured merge-trees that runs from Bigtable through LevelDB and RocksDB, and we compare it against them. SurrealMX builds on the adaptive radix tree and on the multi-version designs of Hekaton and Silo.&lt;/p&gt;

&lt;p&gt;Those ideas were published by people who let strangers read their work, and several of the engines we compare against are open source. We owe that openness a return. The whitepapers cite what we learned from.&lt;/p&gt;

&lt;h2&gt;
  
  
  What will you hold us to?
&lt;/h2&gt;

&lt;p&gt;Three things.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Show the code.&lt;/strong&gt; The engines and tools above stay open source.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run the numbers.&lt;/strong&gt; Every benchmark ships with its command, its hardware and its method.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Say what we did not measure.&lt;/strong&gt; Each whitepaper lists what its measurements leave out, and we will keep doing that.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hold us to them. If we fall short, tell us.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking forward
&lt;/h2&gt;

&lt;p&gt;We want infrastructure that anyone can inspect and anyone can challenge. Agents change what a database has to do. They work in volume, they share state, they carry context from one session to the next, and they need to show their work. The launches from 12 to 16 October 2026 cover that stack from the bottom up: from the storage engine, to the database layer, to the collaborative primitives that enable agents to work at pace, and at scale. All of it sits on one database, SurrealDB, and every benchmark comes with the command to run it.&lt;/p&gt;

&lt;p&gt;That is the foundation. We will set out our full view of infrastructure for the agentic future in a separate post.&lt;/p&gt;

</description>
      <category>database</category>
      <category>opensource</category>
      <category>sourceavailable</category>
      <category>surrealdb</category>
    </item>
    <item>
      <title>Introducing SurrealMX: SurrealDB’s new in-memory storage engine</title>
      <dc:creator>Mark Gyles</dc:creator>
      <pubDate>Tue, 13 Oct 2026 08:18:24 +0000</pubDate>
      <link>https://dev.to/surrealdb/introducing-surrealmx-surrealdbs-new-in-memory-storage-engine-3m69</link>
      <guid>https://dev.to/surrealdb/introducing-surrealmx-surrealdbs-new-in-memory-storage-engine-3m69</guid>
      <description>&lt;p&gt;Author: &lt;a href="https://x.com/tobiemh" rel="noopener noreferrer"&gt;Tobie Morgan Hitchcock&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today, we are introducing &lt;strong&gt;SurrealMX 1.0&lt;/strong&gt;, our new high-performance in-memory storage engine for SurrealDB.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/surrealdb/surrealmx" rel="noopener noreferrer"&gt;SurrealMX&lt;/a&gt; is an embedded, transactional key-value engine with lock-free reads, designed for workloads where latency and throughput matter most. By keeping the working dataset in memory and combining multi-version concurrency control with a highly concurrent architecture, SurrealMX can process millions of operations per second while maintaining transactional guarantees.&lt;/p&gt;

&lt;p&gt;It gives developers a new storage option for low-latency applications, high-concurrency workloads, caching, temporary data, and applications where the dataset can comfortably reside in memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why we built SurrealMX
&lt;/h2&gt;

&lt;p&gt;Not every workload needs the same storage model. For applications where durability and datasets larger than memory are the priority, disk-backed storage makes sense. But there is another class of workloads where the main requirement is simple: make reads and writes as fast as possible (e.g. real-time applications, caching layers, ephemeral state, simulations, agent workloads, testing environments, and applications serving large numbers of concurrent requests). SurrealMX is designed specifically for these workloads.&lt;/p&gt;

&lt;p&gt;Instead of optimising a disk-backed database for in-memory use, SurrealMX starts with memory as the primary storage medium. This lets us remove much of the overhead that comes with disk-oriented architectures and design the engine around fast concurrent access.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built for performance
&lt;/h2&gt;

&lt;p&gt;SurrealMX combines a concurrent adaptive radix tree with multi-version concurrency control and a lock-free circular commit ring. The result is high throughput across reads, writes, updates, deletes, and scans.&lt;/p&gt;

&lt;p&gt;In our latest bare-metal benchmarks, SurrealMX delivered:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Engine&lt;/th&gt;
&lt;th&gt;Point reads (OPS)&lt;/th&gt;
&lt;th&gt;Creates (OPS)&lt;/th&gt;
&lt;th&gt;Updates (OPS)&lt;/th&gt;
&lt;th&gt;Deletes (OPS)&lt;/th&gt;
&lt;th&gt;Scans (OPS)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SurrealMX&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;21,506,711&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1,887,149&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1,595,009&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1,814,037&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;18,031,692&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LMDB (in-memory)&lt;/td&gt;
&lt;td&gt;1,226,897&lt;/td&gt;
&lt;td&gt;232,805&lt;/td&gt;
&lt;td&gt;241,431&lt;/td&gt;
&lt;td&gt;177,198&lt;/td&gt;
&lt;td&gt;1,188,365&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RocksDB (in-memory)&lt;/td&gt;
&lt;td&gt;759,060&lt;/td&gt;
&lt;td&gt;616,649&lt;/td&gt;
&lt;td&gt;572,246&lt;/td&gt;
&lt;td&gt;705,773&lt;/td&gt;
&lt;td&gt;836,666&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That translates to more than &lt;strong&gt;21.5 million point reads per second&lt;/strong&gt;, nearly &lt;strong&gt;1.9 million creates per second&lt;/strong&gt;, and over &lt;strong&gt;18 million range scans per second&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Compared with RocksDB configured for in-memory workloads, SurrealMX achieved approximately:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;28× higher point-read throughput&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;3.1× higher create throughput&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2.8× higher update throughput&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2.6× higher delete throughput&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;22× higher range-scan throughput&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The benchmark was run on bare metal using an AMD Ryzen Threadripper 9970X with 128 GB DDR5 RAM, across &lt;strong&gt;15 million keys, 48 concurrent worker threads and 128 clients&lt;/strong&gt;. Each figure is the best of three runs of that benchmark, for every engine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designed for concurrency
&lt;/h2&gt;

&lt;p&gt;Modern applications rarely execute one operation at a time. SurrealMX is designed around multiple concurrent readers and writers without requiring a global lock. Its lock-free circular commit ring provides constant-time atomic slot claiming, while a sharded active-reader registry reduces contention between CPU cores. Reads can inspect version chains without taking locks, allowing the engine to scale more effectively as concurrency increases.&lt;/p&gt;

&lt;p&gt;For point reads, SurrealMX can also bypass transaction-pool checkout and reader registration entirely, returning the latest committed value directly. This architecture is particularly useful for applications where many threads or clients are continuously accessing and changing the same in-memory dataset.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transactions without giving up speed
&lt;/h2&gt;

&lt;p&gt;Being an in-memory database does not mean sacrificing transactional behaviour. SurrealMX supports full transactions, including rollbacks and savepoints, as well as both &lt;strong&gt;snapshot isolation and serializable snapshot isolation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Multi-version concurrency control allows transactions to operate against consistent snapshots while concurrent changes continue in parallel. For simpler workloads, direct operations such as &lt;code&gt;get&lt;/code&gt;, &lt;code&gt;set&lt;/code&gt;, &lt;code&gt;put&lt;/code&gt;, &lt;code&gt;delete&lt;/code&gt; and &lt;code&gt;exists&lt;/code&gt; provide a lower-overhead path without requiring developers to manually manage transactions. That means applications can choose between convenience and more advanced transactional control while using the same engine underneath.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fast scans, without the allocation overhead
&lt;/h2&gt;

&lt;p&gt;In-memory analytical and retrieval workloads often involve more than point lookups. SurrealMX provides zero-allocation range scanning, allowing applications to inspect borrowed keys and values directly rather than repeatedly creating and copying objects. In our benchmarks, this helped SurrealMX exceed &lt;strong&gt;18 million range scans per second&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For workloads involving repeated retrieval over subsets of an in-memory dataset, reducing this allocation overhead can make a significant difference both to latency and CPU utilisation.&lt;/p&gt;

&lt;h2&gt;
  
  
  In-memory first, with optional persistence
&lt;/h2&gt;

&lt;p&gt;SurrealMX is fundamentally an in-memory engine, and its fastest configuration keeps data entirely in memory. In this mode, data disappears when the process terminates. This makes it particularly well suited to workloads such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Caching and temporary state&lt;/li&gt;
&lt;li&gt;Real-time application data&lt;/li&gt;
&lt;li&gt;Development and testing&lt;/li&gt;
&lt;li&gt;Simulations&lt;/li&gt;
&lt;li&gt;Reconstructable datasets&lt;/li&gt;
&lt;li&gt;Low-latency application state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But some workloads need the speed of an in-memory database while still requiring recovery after a restart. For those cases, SurrealMX also supports optional persistence. Developers can configure append-only logging, periodic snapshots, asynchronous persistence, configurable &lt;code&gt;fsync&lt;/code&gt; behaviour, and LZ4 snapshot compression.&lt;/p&gt;

&lt;p&gt;This makes durability a spectrum rather than an all-or-nothing decision. Applications can optimise for maximum throughput, maximum durability, or somewhere in between.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reliability under concurrency
&lt;/h2&gt;

&lt;p&gt;Highly concurrent database engines are difficult to test using conventional unit and integration tests alone. SurrealMX uses deterministic simulation testing: seeded, reproducible runs compared against a sequential reference model, to validate its behaviour across many interleavings of open transactions.&lt;/p&gt;

&lt;p&gt;The engine has been tested across &lt;strong&gt;25 million simulated operations with zero divergences&lt;/strong&gt;. Its persistence layer also protects transactions using checksummed append-only log frames. If a crash interrupts a write, recovery can distinguish incomplete data at the end of the log from valid committed transactions, ensuring transactions are recovered atomically rather than partially applied.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built for embedded and browser applications
&lt;/h2&gt;

&lt;p&gt;Like SurrealDB itself, SurrealMX is designed to operate in more than traditional server environments. It is an embedded Rust engine, meaning applications can run it directly inside their own process rather than communicating with a separate database server.&lt;/p&gt;

&lt;p&gt;SurrealMX also supports WebAssembly, opening the door to running an extremely fast transactional database directly inside browser-based applications. This makes it useful across everything from high-performance backend services to desktop applications and browser environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  SurrealKV and SurrealMX
&lt;/h2&gt;

&lt;p&gt;With SurrealKV and SurrealMX, SurrealDB now has storage engines designed for two different priorities. &lt;strong&gt;SurrealKV&lt;/strong&gt; is our durable storage engine, designed for high-performance persistent workloads where data lives on disk. &lt;strong&gt;SurrealMX&lt;/strong&gt; is our in-memory engine, designed for workloads where the entire dataset can remain in memory and minimum latency is the priority.&lt;/p&gt;

&lt;p&gt;Both are being built around the same principle: rather than treating storage as an external dependency, we can design the underlying engines around the workloads SurrealDB needs to support. That lets us optimise more of the stack ourselves, from the query layer all the way down to how data is stored and accessed. For more information, see our &lt;a href="https://surrealdb.com/docs/manage/self-hosted/deployment-models" rel="noopener noreferrer"&gt;Deployment guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A new option for low-latency SurrealDB workloads
&lt;/h2&gt;

&lt;p&gt;SurrealMX gives SurrealDB a storage engine designed specifically for the fastest end of the performance spectrum.&lt;/p&gt;

&lt;p&gt;With more than &lt;strong&gt;21 million reads per second&lt;/strong&gt;, millions of writes per second, lock-free reads, transactional guarantees, and configurable persistence, it provides a new foundation for applications where every microsecond counts.&lt;/p&gt;

&lt;p&gt;SurrealMX brings the full power of an in-memory transactional storage engine to SurrealDB - built for speed, concurrency, and the next generation of real-time applications.&lt;/p&gt;

&lt;p&gt;Go to the &lt;a href="https://github.com/surrealdb/surrealmx" rel="noopener noreferrer"&gt;SurrealMX GitHub repository&lt;/a&gt;, read the &lt;a href="https://surrealdb.com/static/whitepapers/surrealmx.pdf" rel="noopener noreferrer"&gt;whitepaper&lt;/a&gt;, or check out our &lt;a href="https://surrealdb.com/docs/manage/self-hosted/deployment-models" rel="noopener noreferrer"&gt;Deployment guide&lt;/a&gt; for more information.&lt;/p&gt;

</description>
      <category>storageengine</category>
      <category>inmemory</category>
      <category>news</category>
      <category>database</category>
    </item>
    <item>
      <title>SurrealDB Cloud is now available on Microsoft Azure</title>
      <dc:creator>Mark Gyles</dc:creator>
      <pubDate>Thu, 17 Sep 2026 15:13:29 +0000</pubDate>
      <link>https://dev.to/surrealdb/surrealdb-cloud-is-now-available-on-microsoft-azure-1ina</link>
      <guid>https://dev.to/surrealdb/surrealdb-cloud-is-now-available-on-microsoft-azure-1ina</guid>
      <description>&lt;p&gt;Author: &lt;a href="https://x.com/tobiemh" rel="noopener noreferrer"&gt;Tobie Morgan Hitchcock&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SurrealDB Cloud now runs on Microsoft Azure. Three Azure regions are live today - US East 2, Germany and Brazil - and the provider is now a choice you make alongside the region when you create an instance.&lt;/p&gt;

&lt;p&gt;Until now every managed SurrealDB instance ran on AWS. That was fine if AWS was already where your workloads lived. If your organisation had standardised on Azure, it wasn't: a managed database on another provider meant a second cloud to review, a second network to connect and a second contract to negotiate.&lt;/p&gt;

&lt;h2&gt;
  
  
  One less cloud to get approved
&lt;/h2&gt;

&lt;p&gt;Running on Azure puts the database inside the perimeter your security and procurement teams have already signed off. With Azure Private Link, instances are reachable over a private endpoint in your own virtual network, so traffic between your applications and your database never touches the public internet or crosses a provider boundary. That takes both the cross-cloud egress line item and the latency of that hop off the table.&lt;/p&gt;

&lt;p&gt;For regulated workloads it also answers the residency question in the terms auditors actually ask about. German and EU customer data stays stored and processed in Germany; Brazilian data stays in Brazil, with more regions coming soon.&lt;/p&gt;

&lt;p&gt;The controls are identical on both providers and in every region: SOC 2 Type 2, ISO 27001, GDPR, and encryption at rest and in transit. So are the mechanics. Every tier is available, from Free and development instances through to production and Scale, and instance types, versions, backups and the API all behave exactly as they do on AWS. Existing automation needs nothing more than the new region value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where SurrealDB Cloud runs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;On AWS:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;• US East (N. Virginia)&lt;br&gt;
• US East (Ohio)&lt;br&gt;
• US West (Oregon)&lt;br&gt;
• Europe (Ireland)&lt;br&gt;
• Asia Pacific (Mumbai)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On Azure:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;• US East 2 (Virginia)&lt;br&gt;
• Europe (Germany)&lt;br&gt;
• South America (Brazil)&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started
&lt;/h2&gt;

&lt;p&gt;Create an instance in &lt;a href="https://studio.surrealdb.com/current/instances/deploy?_gl=1*1188y7r*FPAU*MTE2OTI3MjA3NS4xNzg5MTQzMzAz*_ga*Mzc3MDk1MzUwLjE3ODkxNDMzMDM.*_ga_J1NWM32T1V*czE3ODk2NTc3NTYkbzE3JGcxJHQxNzg5NjU3NzY3JGo0OSRsMCRoMTkxNjg4NTUzOA..*_fplc*Y2hYYnNsWDYwWHVncU9LTWpmR1NaJTJGcE9makFmaVRVMnNmTTZPcGdnJTJCUzV5ZHdJdyUyQkxUZVlRSnduQTVndHU5Z2tubWhRR2Q5eVMwNGdVRVVBdDlVbklsVHlkaFRJT2Y1OEpEdVFYMCUyRlZpQ0lRU2dIZHhSWiUyQjVZaU96WlNmUSUzRCUzRA.." rel="noopener noreferrer"&gt;SurrealDB Cloud&lt;/a&gt; and pick an Azure region from the list. The Free tier costs nothing, so you can put a real instance in your own Azure region before you take anything to a review board.&lt;/p&gt;

&lt;p&gt;If you are running SurrealDB in production and want high availability alongside in-region deployment, the &lt;a href="https://surrealdb.com/blog/introducing-scale-surrealdb-cloud-built-for-high-availability-and-scale" rel="noopener noreferrer"&gt;Scale tier&lt;/a&gt; gives you multi-node, multi-availability-zone clusters.&lt;/p&gt;

&lt;p&gt;A listing on the Azure Marketplace is coming soon, so you will be able to procure SurrealDB Cloud through the same channel as the rest of your Azure spend. In the meantime, if Azure is your standard and that is why you have been self-hosting until now, that trade-off is gone. &lt;a href="https://surrealdb.com/contact" rel="noopener noreferrer"&gt;Get in touch&lt;/a&gt; to talk through an enterprise deployment.&lt;/p&gt;

</description>
      <category>surrealdb</category>
      <category>cloud</category>
      <category>azure</category>
      <category>microsoft</category>
    </item>
    <item>
      <title>SurrealDB Cloud is now available in Frankfurt, Germany</title>
      <dc:creator>Mark Gyles</dc:creator>
      <pubDate>Mon, 07 Sep 2026 10:11:28 +0000</pubDate>
      <link>https://dev.to/surrealdb/surrealdb-cloud-is-now-available-in-frankfurt-germany-33lm</link>
      <guid>https://dev.to/surrealdb/surrealdb-cloud-is-now-available-in-frankfurt-germany-33lm</guid>
      <description>&lt;p&gt;Author: &lt;a href="https://x.com/tobiemh" rel="noopener noreferrer"&gt;Tobie Morgan Hitchcock&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SurrealDB Cloud can now be deployed in Frankfurt, Germany. The new region is live today - pick it from the region list when you create an instance.&lt;/p&gt;

&lt;p&gt;For teams across the DACH region and continental Europe, this is a second European option and, for most of them, the closer one. Until now the nearest place to run a managed SurrealDB instance was Ireland, on the far western edge of the continent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Latency and data residency for your workloads
&lt;/h2&gt;

&lt;p&gt;Running in Frankfurt puts the database closer to your users across continental Europe, next to the interconnect that most European traffic already passes through. It also keeps German and EU customer data stored and processed in Germany, satisfying data-residency requirements that previously ruled out a managed deployment. All this while maintaining the same SOC 2 Type 2 controls, ISO 27001, GDPR, encryption and network isolation options as every other region. Agents gain twice over: the region removes the distance, and SurrealDB removes the fan-out. Vector search, graph traversal, full-text search and document reads all resolve in one query against one store rather than separate calls to a vector database, a search engine and a primary database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where SurrealDB Cloud runs
&lt;/h2&gt;

&lt;p&gt;Frankfurt joins six other regions:&lt;/p&gt;

&lt;p&gt;• US East (N. Virginia)&lt;br&gt;
• US East (Ohio)&lt;br&gt;
• US West (Oregon)&lt;br&gt;
• Europe (Ireland)&lt;br&gt;
• Europe (Frankfurt)&lt;br&gt;
• Asia Pacific (Mumbai)&lt;br&gt;
• South America (São Paulo)&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started
&lt;/h2&gt;

&lt;p&gt;Create an instance in &lt;a href="https://studio.surrealdb.com/current/instances/deploy?_gl=1*13wbmse*FPAU*OTA4NzQ0MTAxLjE3ODgzNTQzMDM.*_ga*MTU2ODc2ODY1OS4xNzg4MzU0MzAz*_ga_J1NWM32T1V*czE3ODg3NzIyNTgkbzE1JGcxJHQxNzg4Nzc1NjA3JGo1MyRsMCRoNTYwNTMzMjcz*_fplc*MUglMkJld1JLJTJCWnlxSU5RZFJBYlNKaFdCRmJCSUNFVjNaSk5samQ4aEpUa3RGWVFTdHFVZmhEamNJYmdPMzVQMmNQZllHZDZvZmtpaiUyQnhZSU5MZ1NkZTFyUlg1ZXNDZVVrTXkwbHBBVFJYa0h1QWtlVkh6aHNWbXNKbFgwS3R3JTNEJTNE" rel="noopener noreferrer"&gt;SurrealDB Cloud&lt;/a&gt; and select Europe (Germany) as the region. Everything else - tiers, instance types, versions, backups - works exactly as it does elsewhere, so existing automation needs nothing more than the new region value.&lt;/p&gt;

&lt;p&gt;If you are running SurrealDB in production and want high availability alongside in-region deployment, the &lt;a href="https://surrealdb.com/blog/introducing-scale-surrealdb-cloud-built-for-high-availability-and-scale" rel="noopener noreferrer"&gt;Scale tier&lt;/a&gt; gives you multi-node, multi-availability-zone clusters.&lt;/p&gt;

</description>
      <category>news</category>
      <category>surrealdbcloud</category>
      <category>database</category>
      <category>cloud</category>
    </item>
    <item>
      <title>SurrealDB Cloud is now available in São Paulo, Brazil</title>
      <dc:creator>Mark Gyles</dc:creator>
      <pubDate>Mon, 07 Sep 2026 09:51:34 +0000</pubDate>
      <link>https://dev.to/surrealdb/surrealdb-cloud-is-now-available-in-sao-paulo-brazil-1o89</link>
      <guid>https://dev.to/surrealdb/surrealdb-cloud-is-now-available-in-sao-paulo-brazil-1o89</guid>
      <description>&lt;p&gt;Author: &lt;a href="https://x.com/IgnacioPaz87" rel="noopener noreferrer"&gt;Ignacio Paz&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SurrealDB Cloud can now be deployed in São Paulo, Brazil. The new region is live today - pick it from the region list when you create an instance.&lt;/p&gt;

&lt;p&gt;For teams building in Brazil and across Latin America, this closes the last big gap in the deployment story: until now the nearest place to run a managed SurrealDB instance was North America, and every query paid for the trip.&lt;/p&gt;

&lt;h2&gt;
  
  
  Latency and data residency for your workloads
&lt;/h2&gt;

&lt;p&gt;Running in São Paulo puts the database closer to your customers for our South American users. It also keeps Brazilian customer data stored and processed in Brazil, satisfying data-residency requirements that previously ruled out a managed deployment. All this while maintaining the same SOC 2 Type 2 controls, ISO 27001, GDPR, encryption and network isolation options as every other region. Agents gain twice over: the region removes the distance, and SurrealDB removes the fan-out. Vector search, graph traversal, full-text search and document reads all resolve in one query against one store rather than separate calls to a vector database, a search engine and a primary database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where SurrealDB Cloud runs
&lt;/h2&gt;

&lt;p&gt;São Paulo joins five other regions:&lt;/p&gt;

&lt;p&gt;• US East (N. Virginia)&lt;br&gt;
• US East (Ohio)&lt;br&gt;
• US West (Oregon)&lt;br&gt;
• Europe (Ireland)&lt;br&gt;
• Asia Pacific (Mumbai)&lt;br&gt;
• South America (São Paulo)&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started
&lt;/h2&gt;

&lt;p&gt;Create an instance in &lt;a href="https://studio.surrealdb.com/current/instances/deploy?_gl=1*cfkuhl*FPAU*OTA4NzQ0MTAxLjE3ODgzNTQzMDM.*_ga*MTU2ODc2ODY1OS4xNzg4MzU0MzAz*_ga_J1NWM32T1V*czE3ODg3NzIyNTgkbzE1JGcxJHQxNzg4Nzc0Mjg2JGo2MCRsMCRoNTYwNTMzMjcz*_fplc*MUglMkJld1JLJTJCWnlxSU5RZFJBYlNKaFdCRmJCSUNFVjNaSk5samQ4aEpUa3RGWVFTdHFVZmhEamNJYmdPMzVQMmNQZllHZDZvZmtpaiUyQnhZSU5MZ1NkZTFyUlg1ZXNDZVVrTXkwbHBBVFJYa0h1QWtlVkh6aHNWbXNKbFgwS3R3JTNEJTNE" rel="noopener noreferrer"&gt;SurrealDB Cloud&lt;/a&gt; and select &lt;strong&gt;South America (Brazil)&lt;/strong&gt; as the region. Everything else - tiers, instance types, versions, backups - works exactly as it does elsewhere, so existing automation needs nothing more than the new region value.&lt;/p&gt;

&lt;p&gt;If you are running SurrealDB in production and want high availability alongside in-region deployment, the &lt;a href="https://surrealdb.com/blog/introducing-scale-surrealdb-cloud-built-for-high-availability-and-scale" rel="noopener noreferrer"&gt;Scale tier&lt;/a&gt; gives you multi-node, multi-availability-zone clusters. The &lt;a href="https://surrealdb.com/docs/manage/cloud" rel="noopener noreferrer"&gt;Cloud documentation&lt;/a&gt; covers the full set of options.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://studio.surrealdb.com/current/instances/deploy?_gl=1*13c3trd*FPAU*OTA4NzQ0MTAxLjE3ODgzNTQzMDM.*_ga*MTU2ODc2ODY1OS4xNzg4MzU0MzAz*_ga_J1NWM32T1V*czE3ODg3NzIyNTgkbzE1JGcxJHQxNzg4Nzc0Mjg2JGo2MCRsMCRoNTYwNTMzMjcz*_fplc*MUglMkJld1JLJTJCWnlxSU5RZFJBYlNKaFdCRmJCSUNFVjNaSk5samQ4aEpUa3RGWVFTdHFVZmhEamNJYmdPMzVQMmNQZllHZDZvZmtpaiUyQnhZSU5MZ1NkZTFyUlg1ZXNDZVVrTXkwbHBBVFJYa0h1QWtlVkh6aHNWbXNKbFgwS3R3JTNEJTNE" rel="noopener noreferrer"&gt;Deploy in São Paulo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>surrealdbcloud</category>
      <category>database</category>
      <category>cloud</category>
      <category>news</category>
    </item>
    <item>
      <title>How Cobrainer built graph-based agent memory on one engine</title>
      <dc:creator>Mark Gyles</dc:creator>
      <pubDate>Mon, 07 Sep 2026 09:32:35 +0000</pubDate>
      <link>https://dev.to/surrealdb/how-cobrainer-built-graph-based-agent-memory-on-one-engine-2a6k</link>
      <guid>https://dev.to/surrealdb/how-cobrainer-built-graph-based-agent-memory-on-one-engine-2a6k</guid>
      <description>&lt;p&gt;Author: &lt;a href="https://x.com/IgnacioPaz87" rel="noopener noreferrer"&gt;Ignacio Paz&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An AI agent is only as useful as what it can remember - and how well it can connect the things it remembers. Most teams hand their agent a memory by reaching for a vector store: embed everything, retrieve by similarity, hope the relevant context comes back. It works, until you notice the agent keeps surfacing things that are near the question but not actually connected to it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.cobrainer.com/" rel="noopener noreferrer"&gt;Cobrainer&lt;/a&gt;, a skills-intelligence company based in Munich, took a different route. They gave their AI agent a memory that lives in the database as a graph, where the agent builds the relationships between nodes as it goes. They did it without adding a graph database, a vector engine, or a search engine to their stack. It all runs on SurrealDB, alongside a Rust-native agentic graph RAG built on the same store.&lt;/p&gt;

&lt;p&gt;Here's how, and why a single engine made the difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with flat memory
&lt;/h2&gt;

&lt;p&gt;Cobrainer runs a skills-intelligence platform - the kind of system that reasons about how people, roles, skills, and capabilities relate to one another. That's an inherently graph-shaped problem. But their first retrieval setup wasn't graph-shaped at all.&lt;/p&gt;

&lt;p&gt;It pulled context through flat vector retrieval over an S3-and-OpenSearch pipeline, which carried two recurring costs:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accuracy&lt;/strong&gt;. Flat vector matches returned context that was loosely related - semantically near, but not necessarily connected in any meaningful way. The team wanted the agent to follow real relationships between entities, so its answers were grounded rather than approximate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tokens&lt;/strong&gt;. Broad vector matches meant stuffing a lot of marginally relevant context into every prompt - expensive, and more so with every call. The team wanted to fetch only the context that mattered.&lt;/p&gt;

&lt;p&gt;The obvious fix - adding a graph database on top of the vector and search systems they already ran - would have meant more infrastructure to operate. For a startup moving fast, that fragmentation was the thing to avoid, not embrace.&lt;/p&gt;

&lt;h2&gt;
  
  
  What they wanted instead
&lt;/h2&gt;

&lt;p&gt;Cobrainer's requirements were less about any single feature and more about not paying a tax for combining them.&lt;/p&gt;

&lt;p&gt;• &lt;strong&gt;An agent and a graph RAG on one store&lt;/strong&gt;: an AI agent whose memory lives in the database as a graph, plus an agentic graph RAG. Both are backed by a single engine for graph, vector, and full-text.&lt;/p&gt;

&lt;p&gt;• &lt;strong&gt;A self-building memory graph&lt;/strong&gt;: rather than hand-modelling every relationship up front, the agent should make use of the relations between nodes that it builds automatically as it works.&lt;/p&gt;

&lt;p&gt;• &lt;strong&gt;Grounding through structure&lt;/strong&gt;: retrieval that traverses real relationships, so answers are anchored in how things actually connect.&lt;/p&gt;

&lt;p&gt;• &lt;strong&gt;Token efficiency by design&lt;/strong&gt;: pull the relevant subgraph, not a broad similarity sweep.&lt;/p&gt;

&lt;p&gt;• &lt;strong&gt;Pace&lt;/strong&gt;: stand up new storage patterns quickly, without long migrations slowing the team down.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why did Cobrainer choose SurrealDB?
&lt;/h2&gt;

&lt;p&gt;SurrealDB gave Cobrainer graph, vector, and full-text in a single engine, all queried through SurrealQL - so the agentic use case didn't need pgvector or OpenSearch sitting alongside their database. (Their existing RDS Postgres stayed exactly where it was, doing the job it already did well.)&lt;/p&gt;

&lt;p&gt;A few things made the build land the way they wanted:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One engine, queried one way&lt;/strong&gt;. Documents, graphs, vectors, and full-text all live in one store - schemaless and schemafull side by side - and all reachable through SurrealQL. The agentic case added no new systems to operate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Graph-based agent memory that builds itself&lt;/strong&gt;. SurrealDB stores the agent's memory and its session checkpoints. As the agent works, it automatically creates the relations between the nodes it writes - so the memory graph forms on its own, and the agent can later traverse those connections instead of re-deriving them. The team described a multi-layered, graph-based memory model, and the thing that surprised them was how fast it came together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A Rust-native agentic graph RAG&lt;/strong&gt;. Cobrainer built the graph RAG natively in Rust on SurrealDB's Rust SDK, combining graph traversal and vector similarity in a single query. That's the piece that replaced the old S3-and-OpenSearch RAG - letting the agent walk relationships and rank by similarity in one round trip instead of orchestrating across services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Managed, and inside the EU boundary&lt;/strong&gt;. Because this is HR data, residency isn't optional. SurrealDB Cloud let a lean team run the engine as a managed service with EU-region data residency, keeping everything inside the boundary they're required to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  The results
&lt;/h2&gt;

&lt;p&gt;Cobrainer went from evaluation to a customer-facing production deployment in roughly &lt;strong&gt;three months&lt;/strong&gt;. As of August 2026, that deployment is live. Measured against their previous S3-and-OpenSearch pipeline, the team reports three changes.&lt;/p&gt;

&lt;p&gt;• &lt;strong&gt;Better accuracy&lt;/strong&gt;: grounding the agent in real graph relationships, rather than loose vector matches, made its responses more reliable.&lt;/p&gt;

&lt;p&gt;• &lt;strong&gt;Lower token cost per call&lt;/strong&gt;: fetching only graph-relevant context - instead of a broad vector sweep - trimmed the tokens going into each prompt.&lt;/p&gt;

&lt;p&gt;• &lt;strong&gt;A flexible platform for what's next&lt;/strong&gt;: graph-based agent memory and a Rust-native agentic graph RAG, both on one engine, ready to absorb new use cases without another round of stack expansion.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"As a startup, we didn't want to fragment our stack every time we add a capability. For our agentic graph RAG, the alternative was weighing Postgres with pgvector and search extensions against bolting on OpenSearch - instead we got graph, vector, and full-text from one engine. What surprised us was how quickly we stood up a multi-layered, graph-based memory model for our AI agent, with SurrealDB handling its memory and session checkpoints. And SurrealDB Cloud kept all of it inside our EU data boundary."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Daniel Alker, Senior Cloud Platform Engineer, Cobrainer&lt;/p&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;Giving an agent a memory doesn't have to mean giving it another database. Cobrainer's story is a small proof of a larger idea. When one engine handles graph, vector, and full-text together, and the agent can build its own memory graph on top of it, the "right" architecture stops being a collection of specialised services. It starts being a single query.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://surrealdb.com/cloud" rel="noopener noreferrer"&gt;Start with SurrealDB Cloud&lt;/a&gt; or explore &lt;a href="https://surrealdb.com/docs" rel="noopener noreferrer"&gt;the docs&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>agentmemory</category>
      <category>surrealdb</category>
      <category>database</category>
    </item>
    <item>
      <title>Graph engineering is missing a graph</title>
      <dc:creator>Mark Gyles</dc:creator>
      <pubDate>Thu, 13 Aug 2026 13:08:08 +0000</pubDate>
      <link>https://dev.to/surrealdb/graph-engineering-is-missing-a-graph-6b4</link>
      <guid>https://dev.to/surrealdb/graph-engineering-is-missing-a-graph-6b4</guid>
      <description>&lt;p&gt;Author: &lt;a href="https://x.com/tobiemh" rel="noopener noreferrer"&gt;Tobie Morgan Hitchcock&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Graph engineering is having a moment.&lt;/p&gt;

&lt;p&gt;The definition going round is a good one, and I am not going to try to redefine it. Complex agents increasingly look like graphs: nodes do the work, edges decide what happens next, state moves between them. That is real, it matches what production actually looks like, and the people saying it are right.&lt;/p&gt;

&lt;p&gt;Almost nobody makes the next observation. Those agents are still fed context from flat vector chunks, a separate document store, a relational database and some ephemeral session memory. While the execution architecture became a graph, the data architecture underneath it did not.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Graph engineering is not just about graphing the agents. You also have to graph the context they operate on.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or, less politely: you cannot graph-engineer the agent and leave its memory as a pile of chunks.&lt;/p&gt;

&lt;p&gt;This is my attempt to say what graph engineering has to mean if it is going to outlive the meme.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rename cycle
&lt;/h2&gt;

&lt;p&gt;We have been renaming the same struggle for a few years. Prompt engineering optimised instructions. Context engineering optimised what goes into the window. Harness engineering, loop engineering, and now graph engineering optimise how agents work together.&lt;/p&gt;

&lt;p&gt;I do not mind the labels. They appear when builders hit a wall. This wall is real. One agent loop in one chat window stops scaling the moment the work looks like a team: parallel reviewers, a fixer, a security check with veto power, a human gate before anything irreversible. That structure is a graph. It always was.&lt;/p&gt;

&lt;p&gt;Every one of those renames moved up the stack, and every one of them left the data layer where it was.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two graphs. Say which one you mean.
&lt;/h2&gt;

&lt;p&gt;When someone says graph engineering, they could mean one of three things and rarely say which:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A graph of loops&lt;/strong&gt;, which is really a claim about control flow: what you get when one loop stops being enough.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;An execution graph.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A context graph.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The loop graph folds into the execution graph, so two are left standing, and most threads blur even those. Sometimes people mean both. They almost never say so.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fet6cf1xni6qvbzb0e475.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fet6cf1xni6qvbzb0e475.png" alt="execution graph" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The execution graph
&lt;/h3&gt;

&lt;p&gt;What runs next, in what order, with what rights. It determines what your agents &lt;strong&gt;do&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Nodes are work: a classifier, a tool call, a coding agent, a reviewer. Edges are transitions: success, fail, escalate, fan out. State is the scratchpad the system mutates. Verifiers sit on a separate path when the stakes are high. Stop rules exist so the thing does not burn tokens until the card declines.&lt;/p&gt;

&lt;p&gt;This is a state machine with probabilistic nodes inside it. LangGraph made the case earliest and loudest, and Google's ADK, Mastra, CrewAI, Microsoft's agent frameworks, or a boring job runner you wrote yourself all live on the same plane. Useful, necessary for a lot of production agents, and on its own not sufficient.&lt;/p&gt;

&lt;h3&gt;
  
  
  The context graph
&lt;/h3&gt;

&lt;p&gt;What is true, what is related, what was true when, and who said so. It determines what your agents &lt;strong&gt;know&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here the nodes are entities, documents, events, users and assets, and the edges between them carry properties of their own: since, confidence, source. Provenance, time, permissions and hybrid retrieval all matter, because the world is not only triples and it is not only embeddings.&lt;/p&gt;

&lt;p&gt;Classic knowledge graphs and GraphRAG both sit on this plane. It gets a paragraph in most threads and a whiteboard in almost none.&lt;/p&gt;

&lt;p&gt;So:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The execution graph engineers the graph of work. The context graph engineers the graph of knowledge.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most teams have engineered the first and are still running the second as a pile of chunks in a vector store.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where they meet: the turn
&lt;/h2&gt;

&lt;p&gt;Every serious agent turn is three moves: read, think, write. Read means traverse relations, pull vectors, load history and permissions. Think means the model reasons over a complete packet, not three partial dumps from three systems that disagree with each other. Write means decisions, new entities, and memories land somewhere the next turn can actually see them.&lt;/p&gt;

&lt;p&gt;If your execution graph is elegant and your write path is "maybe the vector DB, maybe the graph DB, maybe a JSON blob in object storage," the whiteboard never became system truth. You choreographed forgetting.&lt;/p&gt;

&lt;p&gt;That is the definition I use:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Graph engineering is how you design the execution graph of agent work and the context graph of durable knowledge, then keep them consistent across every turn.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The meme covers the execution graph. Production dies on the other two.&lt;/p&gt;

&lt;h2&gt;
  
  
  Loops, graphs, context. Stack them.
&lt;/h2&gt;

&lt;p&gt;A loop is fine when one goal, one verifier, and one stop condition cover the job.&lt;/p&gt;

&lt;p&gt;An execution graph earns its keep when you need parallel specialists, explicit escalations, or policy gates.&lt;/p&gt;

&lt;p&gt;Context engineering is what you do on every node either way: put the right facts, tools, and state in front of the model at the right time. Widening the context window does not solve a wrong-context problem, it just raises the price of getting it wrong.&lt;/p&gt;

&lt;p&gt;Harnesses and frameworks host all of this. I am not here to sell you an orchestrator. We did not build SurrealDB to replace your control plane.&lt;/p&gt;

&lt;p&gt;We built it because the existing data planes under those nodes were a mess.&lt;/p&gt;

&lt;h2&gt;
  
  
  GraphRAG is one chapter, not the book
&lt;/h2&gt;

&lt;p&gt;People swap the words, but they should not.&lt;/p&gt;

&lt;p&gt;GraphRAG is a retrieval pattern: extract structure from a corpus, then use the graph, and often community summaries, to ground generation. It is a good technique, and one node in a larger system can run it just fine. You can also run GraphRAG with almost no multi-agent workflow at all. Microsoft's own documentation makes the honest version of the argument: vector-only retrieval struggles when answering a question requires connecting information across relationships.&lt;/p&gt;

&lt;p&gt;If graph engineering is going to mean anything durable, it is how the whole system moves, remembers, and stays correct. Retrieval is necessary, but it is not the architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retrieval is not three searches and a re-ranker
&lt;/h2&gt;

&lt;p&gt;Almost everyone ships the same pattern. Fire a vector search. Fire a keyword search. Maybe fire a graph query. Take fifty from each, throw the pile at a re-ranker, keep what floats, stuff it in the prompt.&lt;/p&gt;

&lt;p&gt;That pipeline has a structural flaw, and it is not latency. Each leg searches blind to the constraints the other legs know about. The vector index does not know this question is about one customer's contracts; it knows only that a question-shaped vector is near some passage-shaped vectors. So it returns fifty candidates and hopes. The keyword leg does the same. The graph leg returns a neighbourhood with no idea which parts are relevant to the sentence that was asked. Then a re-ranker, which can see the text and none of the structure, is asked to reconcile three lists that were each built without the others' information.&lt;/p&gt;

&lt;p&gt;You over-fetch because that is the only defence against three blind legs. Over-fetching grows your token bill. Then you pay a second time, because the pile you carried back is mostly padding, and padding in the context window is not free: it costs money on the way in and accuracy on the way out, since a longer prompt gives the model more chances to ground its answer in the wrong sentence.&lt;/p&gt;

&lt;p&gt;Run the similarity inside the traversal rather than beside it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuw6xvlko0vnmp8106qq8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuw6xvlko0vnmp8106qq8.png" alt="three blind legs" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If embeddings are a field on the entity, and full-text indexes sit on the same rows, and relations are edges between those same rows, then one query expresses the whole thing: start from what the question is about, walk the relations that matter, and score by similarity and text relevance as you go, with permissions and time bounds applied in the same pass. Roughly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;stated_by&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;source&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;provenance&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;works_at&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;company&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;acme&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;valid_until&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;NONE&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;|&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The structure prunes before similarity scores, and similarity ranks within what the structure allows. You are not searching a corpus and hoping the answer's neighbourhood comes with it. You are searching a neighbourhood you already have reason to believe in.&lt;/p&gt;

&lt;p&gt;That buys two things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fewer tokens.&lt;/strong&gt; You stop over-fetching, because a constrained candidate set does not need a wide net to be safe. You carry back a small precise set instead of three large ones minus whatever the re-ranker threw away, and you stop paying for the same fact three times because three stores each returned their own copy of it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Higher accuracy.&lt;/strong&gt; Every filter that was inexpressible in the vector leg (this entity, this scope, this time window, this permission, currently true rather than superseded) becomes expressible, because it is evaluated in the same statement as the similarity. Constraints you could only apply after ranking are now applied before it.&lt;/p&gt;

&lt;p&gt;Our own numbers say the same thing from the other direction. When we were first developing Spectron, our memory layer, we tried the obvious thing: reduce each extracted fact to a short sentence, embed it, and add it as another dense leg in the hybrid mix. It fixed roughly a hundred benchmark questions and broke roughly as many again, landing slightly negative and inside the noise. Meanwhile the two changes that clearly won were both structural: routing from a resolved entity into its typed facts, and expanding a hit into its conversational neighbours. Both worth a couple of points on their own.&lt;/p&gt;

&lt;p&gt;The lesson we took: reducing a typed fact to a sentence and matching it by cosine throws away exactly the structure that made extracting it worthwhile. A similarity list also cannot abstain. It always returns its k, so when the right answer is not there it returns something else with total confidence, and something else lands in the prompt. Structure can return nothing, which is frequently the correct answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  A context graph is not an extraction job
&lt;/h2&gt;

&lt;p&gt;The obvious objection: fine, &lt;em&gt;so I bolt a graph database onto my stack and run an extractor over my corpus.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You can. What you get is a pile of assertions in a vocabulary the model improvised one turn at a time, and the difference shows up months later as retrieval that cannot find things you know are in there.&lt;/p&gt;

&lt;p&gt;Here are the numbers from one conversation we ingested end to end. Of the attribute keys the extractor produced, &lt;strong&gt;85% were used exactly once&lt;/strong&gt;: 236 distinct keys across 325 facts, an average of 1.4 uses per key. Action verbs were nearly as bad, 80% used once. The two most common verbs in the whole set were &lt;code&gt;shared_image&lt;/code&gt; and &lt;code&gt;shared&lt;/code&gt;, describing the same act, counted separately.&lt;/p&gt;

&lt;p&gt;Now consider what that does to a query. &lt;code&gt;WHERE key = 'residence'&lt;/code&gt; finds nothing if this turn's extraction called it &lt;code&gt;lives_in&lt;/code&gt;, and the next one called it &lt;code&gt;home_city&lt;/code&gt;, and a third called it &lt;code&gt;current_residence&lt;/code&gt;. The structured path, the one that was supposed to make the graph worth building, stays dark. Retrieval falls through to similarity, and you are back to the pattern in the previous section, paying for a graph you cannot query.&lt;/p&gt;

&lt;p&gt;The interesting part is the control case. One relation family in that same measurement was &lt;strong&gt;not&lt;/strong&gt; fragmented: 4.3 uses per label instead of 1.4, only 40% singletons. It was the one family where the extraction prompt already showed the model the vocabulary the system had established, with an instruction to reuse an existing label and only mint a new one when nothing fits. Same model, same text, same run. The only difference was whether the graph told the extractor what it already knew.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F114530s6m70r4jsod51u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F114530s6m70r4jsod51u.png" alt="same model" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A context graph is a loop with itself, not a function over text.&lt;/strong&gt; Feed the established vocabulary back. Canonicalise predicates at write time so two spellings of one idea land in one bucket. Resolve mentions against entities that already exist, rather than minting a new node for every phrasing, because the same customer becoming five nodes means every traversal lies.&lt;/p&gt;

&lt;p&gt;Some hard-won specifics, since this is where the work actually is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There is no correct base form a priori.&lt;/strong&gt; We tried folding inflections and the naive rules are landmines: strip a trailing &lt;code&gt;e&lt;/code&gt; and &lt;code&gt;care&lt;/code&gt; merges with &lt;code&gt;car&lt;/code&gt;; undouble a consonant and &lt;code&gt;roll&lt;/code&gt; merges with &lt;code&gt;role&lt;/code&gt;; strip a trailing &lt;code&gt;s&lt;/code&gt; and &lt;code&gt;news&lt;/code&gt; becomes &lt;code&gt;new&lt;/code&gt;. Any stemmer aggressive enough to bucket reliably produces non-words that then surface in your API responses. What worked was narrower and duller: only ever fold onto a spelling this graph already uses, never toward an invented lemma.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Semantic merging is a judgement about meaning, not a normalisation.&lt;/strong&gt; &lt;code&gt;home_city&lt;/code&gt; and &lt;code&gt;city_of_residence&lt;/code&gt; probably mean the same thing. "Use metric units" and "always answer in metric" probably do too. Fold them wrongly and you have discarded something a user explicitly said. We left that undone deliberately, and said so, rather than pretending a string function had settled it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time is two axes and they are not the same axis.&lt;/strong&gt; When a fact was stated is not when the thing happened. If you store one and render it as the other, "when did X happen" gets answered with when it was mentioned, confidently and wrongly. Relative phrases are worse: "last week" is a window, not an instant, and letting the answering model do calendar arithmetic at read time from whatever dates happened to be in its context is exactly the failure you are trying to remove. Resolve at write time, against the source's own date, and store what was actually stated. Store nothing when nothing was stated, so that "no event time" and "the event time equals the ingest time" stop being the same value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dates do not belong in the text you embed.&lt;/strong&gt; We had resolved windows interpolated into the fact sentence that was both the keyword document and the embedded vector. Those date tokens say nothing about what the fact means, and they pollute the retrieval key for every query. Dates live in columns. Renderers read columns. Text and columns cannot disagree if there is only one copy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Half of what extraction produces is not linked to anything.&lt;/strong&gt; In our measurement, 52% of action objects were free text rather than a resolved entity: the graph recorded that somebody did something to a string. That string is invisible to traversal. Extraction reported success. The graph got nothing it can walk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An edge nothing reads is not memory.&lt;/strong&gt; We shipped an alias edge, wrote a careful writer for it, and then pulled it, because no retrieval path traversed it. It was structure with no consequence.&lt;/p&gt;

&lt;p&gt;All of this decides whether the context graph means anything. Meaning cannot be extrapolated from a graph that was never normalised, because the meaning was discarded before the write. And none of it is a one-time import: entity resolution and temporal invalidation are standing jobs, running every turn, or "what is true" decays into "what was true in March."&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually breaks
&lt;/h2&gt;

&lt;p&gt;Skip the forty-agent overnight graph. That is how you max a bill and learn nothing.&lt;/p&gt;

&lt;p&gt;Here is what fails.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;State lives only in the transcript.&lt;/strong&gt; You cannot debug it, audit it, or resume it cleanly if that is the only place it lives. IDs, permissions, and intermediate facts need a home outside the prompt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Everything is agentic.&lt;/strong&gt; Money movement, PII, deletes, external side effects: those edges should be code, not model judgement. Give the model freedom where exploration actually pays off, and encode the paths you already know are correct.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verifiers share the same spoiled context.&lt;/strong&gt; Agents on the same model, reading the same flawed packet, agree with each other at industrial scale, which is why verifier context needs to be separated and drawn from evidence outside the graph: tests that ran, money that moved, a human weighing in before the expensive push. Organised nonsense is still nonsense.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You drew a DAG and production needed cycles.&lt;/strong&gt; Retries, clarification, a human pausing and resuming the flow: these are not a design smell, they are how work actually works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your context graph is a pile of triples with no ontology.&lt;/strong&gt; Model the domain before you extract at scale. Schema is what stops you from lying to yourself about what the graph actually means, not overhead for its own sake.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extraction is stateless.&lt;/strong&gt; Every turn invents its own vocabulary because nothing showed it the vocabulary that already exists. This is the single cheapest thing to fix and the one most people have not fixed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The graph is built once and never maintained.&lt;/strong&gt; Extraction is the easy day. Entities need resolving, or the same customer becomes five nodes and every traversal lies. Facts need expiry, or superseded beliefs sit next to current ones and both look true.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retrieval is three searches and a re-ranker.&lt;/strong&gt; Each leg is blind to the others' constraints, so you over-fetch to compensate, pay for the same fact three times, and hand a re-ranker the job of guessing what the query planner should have known.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write-back is optional.&lt;/strong&gt; The agent learns a preference, a failed approach, a new link between entities. If that write is not durable and visible under the same permissions as the read, the next node is guessing again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No stop rule.&lt;/strong&gt; Parallel agents without token, time, and tool budgets will happily burn through a budget without producing anything you can point to.&lt;/p&gt;

&lt;h2&gt;
  
  
  The shape everyone ships
&lt;/h2&gt;

&lt;p&gt;Most "graph engineered" demos still look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6m3oihziwgc4zxyzbd6x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6m3oihziwgc4zxyzbd6x.png" alt="five separate systems" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Four taxes, every time.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Context leaks at the seams. Relationships, history, and metadata fragment whenever they cross a boundary.&lt;/li&gt;
&lt;li&gt;The same fact enters the prompt three times, and you pay for it three times.&lt;/li&gt;
&lt;li&gt;No query can be planned across the whole picture, so every retrieval is a wide guess narrowed after the fact.&lt;/li&gt;
&lt;li&gt;Ops multiplies: five configs, five monitors, five failure modes, and the glue quietly becomes the product.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You want the context graph and the durable data to be one thing. A context graph that cannot hold your application records, your documents, your vectors and your temporal state is a copy of your real data that you will spend the next year syncing.&lt;/p&gt;

&lt;p&gt;This is why I flinch when graph engineering is reduced to "use a graph database." A graph-only store solves a real slice, but agents need documents, vectors, time, session state, and above all the ability to ask one question that is simultaneously a traversal, a similarity search and a filter. Split those across stores and that question stops being expressible at any price.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this looks like inside a bank
&lt;/h2&gt;

&lt;p&gt;Most of the graph-engineering conversation right now is about routing and reliability: how do I get five agents to hand work to each other without falling over. That is a startup's version of the problem.&lt;/p&gt;

&lt;p&gt;Ask the same question inside a bank, an insurer or a global enterprise and the requirements change shape entirely. Every enterprise conversation I have had this year has landed on some version of the same list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shared context, not per-agent context.&lt;/strong&gt; Twenty agents across four teams need the same view of the same customer. If each one has its own vector store, you do not have twenty agents, you have twenty inconsistent opinions with an org chart.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Permissions that travel with the data.&lt;/strong&gt; Not permissions checked at the API gateway and then discarded. If retrieval cannot enforce who may see which fact inside the query itself, then every prompt is a potential exfiltration path and every new agent is a new review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Provenance carried on the facts themselves.&lt;/strong&gt; Who said this, in which document, on what date, and is that source still authoritative. "The model said so" is not a defensible answer when the fact ends up in a regulatory filing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auditable retrieval.&lt;/strong&gt; Not just what the agent answered, but what it read to get there, and why those rows and not others. A re-ranker's opinion over three fused lists is close to unexplainable. A query with predicates in it explains itself.&lt;/p&gt;

&lt;p&gt;Underneath all of it sits temporal truth: what did we believe on the day the decision was made, not what do we believe now. In a regulated firm the record exists to answer that question, which means facts need validity intervals and reads need to resolve as of a point in time rather than as of now. And the graph needs a boundary in both directions, with control over what is allowed into it and over what is allowed out of it into a prompt.&lt;/p&gt;

&lt;p&gt;None of that is served by a prettier flowchart, and none of it is served by a vector store with a metadata filter bolted on. It is served by the context graph being a real database: transactional, permissioned, temporal, and auditable. The current discourse is not covering this, and it is what enterprises are buying.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we set out to build
&lt;/h2&gt;

&lt;p&gt;I am biased. I will say that up front.&lt;/p&gt;

&lt;p&gt;We built SurrealDB as a multi-model engine: documents, graphs, vectors, time-series, full-text, relational, and auth in one system with one query language over them. The reason has nothing to do with graphs being fashionable. It is that the useful query is almost never one shape. It is "things related to this, that resemble that, that were true then, that this user may see," and every system that stores those four facts separately can only answer it by approximation and reassembly.&lt;/p&gt;

&lt;p&gt;On the context side that means schema as ontology. Edges carry confidence, time, and source as fields rather than afterthoughts. Vectors live on the entities they came from, so similarity is an operator inside a traversal rather than a separate service you join against afterwards. Traversal, similarity, full-text, and filters resolve in one statement, planned together, instead of three round trips and a sync cron you forgot about until it pages you at 2am. Write-back lands transactionally under the same permission model you read from, which matters, but it is the floor rather than the pitch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcs3ab6rfyn31gmykll51.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcs3ab6rfyn31gmykll51.png" alt="Where the layers actually sit" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Spectron is the memory layer we built on that engine: entity extraction, predicate normalisation, entity resolution, temporal facts, and hybrid retrieval that is one query rather than three. Most of the engineering effort there has gone into what happens between the text arriving and the graph existing, rather than into retrieval algorithms. When the session ends, the context window forgets, but the system should not.&lt;/p&gt;

&lt;p&gt;We are also building the comparison, because I would not take my word for it either: the same multi-agent application twice, once on an orchestrator plus a vector store plus a relational database plus a session cache, and once on the same orchestrator with a single context graph underneath. Same agents, same tasks, same model. Measured on context accuracy, tokens consumed, latency, network hops and lines of glue.&lt;/p&gt;

&lt;p&gt;The control plane stays yours. We are complementary on purpose. The question I would ask is not whose orchestrator you use, but whether your retrieval can express a traversal and a similarity search in the same breath, and whether anything understood your data before it became a graph.&lt;/p&gt;

&lt;h2&gt;
  
  
  A checklist I would actually use
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scope
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;One recurring job with a real success metric, not a general assistant.&lt;/li&gt;
&lt;li&gt;Someone owns the ontology, someone owns the workflow, and early on that can be the same person.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Execution graph
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Label nodes: code / single LLM call / tool / full agent.&lt;/li&gt;
&lt;li&gt;Edges only where work actually flows.&lt;/li&gt;
&lt;li&gt;A verifier path with fresh context for high-risk output.&lt;/li&gt;
&lt;li&gt;A human gate on irreversible actions.&lt;/li&gt;
&lt;li&gt;Explicit stops and budgets.&lt;/li&gt;
&lt;li&gt;Cycles where retries and clarification are real.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Before the context graph exists
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Entity and relation types written down before bulk extraction.&lt;/li&gt;
&lt;li&gt;Extraction shown the vocabulary the graph already uses, with an instruction to reuse it.&lt;/li&gt;
&lt;li&gt;Predicates canonicalised at write time, folding only onto spellings the graph already has.&lt;/li&gt;
&lt;li&gt;Mentions resolved to existing entities, with the unresolved rate measured rather than assumed.&lt;/li&gt;
&lt;li&gt;Event time and mention time stored as separate columns, resolved at write time, absent when nothing was stated.&lt;/li&gt;
&lt;li&gt;Nothing in your embedded text that is not part of what the fact means.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Context graph
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Provenance on facts and edges.&lt;/li&gt;
&lt;li&gt;Temporal validity, and a job that actually retires superseded beliefs.&lt;/li&gt;
&lt;li&gt;A retrieval path that constrains before it ranks, explainable in one sentence.&lt;/li&gt;
&lt;li&gt;Write-back after every turn for memories, entities, decisions.&lt;/li&gt;
&lt;li&gt;Permissions enforced inside retrieval, not at the gateway.&lt;/li&gt;
&lt;li&gt;Graph statistics on a dashboard: predicates per fact, unresolved mentions, duplicate entities. If you cannot see fragmentation, you will not fix it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Reality checks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Outside-the-graph evidence for ship decisions.&lt;/li&gt;
&lt;li&gt;Evals that include multi-hop and time questions.&lt;/li&gt;
&lt;li&gt;Cost and latency budgets per node type.&lt;/li&gt;
&lt;li&gt;Replayable state when something fails.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Grow the graph when the work forces you, not when a meme does.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would ignore
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Renaming your orchestrator and calling it strategy.&lt;/li&gt;
&lt;li&gt;Forty agents overnight.&lt;/li&gt;
&lt;li&gt;Treating GraphRAG, context graphs, and execution graphs as the same slide.&lt;/li&gt;
&lt;li&gt;Bigger context windows as a substitute for structure.&lt;/li&gt;
&lt;li&gt;A better re-ranker as a substitute for a query that could have been planned properly.&lt;/li&gt;
&lt;li&gt;Holy wars about anyone's database. The architectural gap is enough, and the market does not need another feud.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;Graph engineering became the new buzzword because one chatty loop is not enough for real work. Good. Draw the execution graph. Be honest about where the model decides and where code decides.&lt;/p&gt;

&lt;p&gt;Then do the half most threads skip. Understand the data before you write it: one vocabulary, resolved entities, real event times, facts that expire. Put the vectors on those entities rather than in another system, so retrieval is one query that traverses and ranks together instead of three searches arguing through a re-ranker. Make permissions and provenance properties of the data rather than of the API in front of it.&lt;/p&gt;

&lt;p&gt;The label will get renamed again. It always does, and I would not build a roadmap on the word. But the two graphs are not a naming fashion. Every serious agent system has an execution graph and a context graph whether or not anyone drew the second one, and the gap between them is where the accuracy goes, where the token bill comes from, and where the audit fails.&lt;/p&gt;

&lt;p&gt;Frameworks draw the graph of work. Something has to hold the graph of knowledge, keep it true, and survive the write-back. That is the problem we set out to solve with SurrealDB, and with Spectron, the memory layer we built on top of it. If your agent topology is getting serious and your context layer is still five separate systems you are hoping stay in sync, that is the seam to fix.&lt;/p&gt;

</description>
      <category>graphengineering</category>
      <category>ai</category>
      <category>database</category>
      <category>agents</category>
    </item>
    <item>
      <title>Introducing Scale: SurrealDB Cloud, built for high availability and scale</title>
      <dc:creator>Mark Gyles</dc:creator>
      <pubDate>Thu, 02 Jul 2026 15:53:29 +0000</pubDate>
      <link>https://dev.to/surrealdb/introducing-scale-surrealdb-cloud-built-for-high-availability-and-scale-2ib</link>
      <guid>https://dev.to/surrealdb/introducing-scale-surrealdb-cloud-built-for-high-availability-and-scale-2ib</guid>
      <description>&lt;p&gt;Author: &lt;a href="https://x.com/tobiemh" rel="noopener noreferrer"&gt;Tobie Morgan Hitchcock&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today we're launching Scale, a new tier of SurrealDB Cloud built for the workloads you can't afford to have go down.&lt;/p&gt;

&lt;p&gt;Our first tier, Start, was designed for building and shipping fast. Scale is designed for what happens next: production traffic, uptime commitments, and the kind of resilience your users never notice because there are always available nodes. It's the tier for teams running SurrealDB as the scalable context layer behind real applications and AI agents in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you get with Scale
&lt;/h2&gt;

&lt;p&gt;Scale is about one thing: keeping your database available and consistent under real-world conditions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Highly-available, fault-tolerant clusters.&lt;/strong&gt; Scale runs your database as a multi-node cluster designed to survive node and infrastructure failures without dropping writes or losing consistency. A single point of failure is no longer a single point of downtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multiple availability-zone deployment.&lt;/strong&gt; Your cluster is distributed across multiple availability zones, so even the loss of an entire zone doesn't take your database with it. Traffic keeps flowing while the cluster recovers in the background.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Horizontal scale.&lt;/strong&gt; As demand grows, Scale grows with it. Add capacity by scaling out across nodes rather than being capped by the size of a single machine. Start with three nodes, and keep adding to scale your application or agent's needs.&lt;/p&gt;

&lt;p&gt;See more information about SurrealDB Cloud Scale architecture &lt;a href="https://surrealdb.com/docs/manage/cloud/architecture#scale" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built on SurrealDS
&lt;/h2&gt;

&lt;p&gt;Scale is powered by &lt;a href="https://surrealdb.com/platform/surrealds" rel="noopener noreferrer"&gt;SurrealDS&lt;/a&gt;, SurrealDB's distributed storage engine and the foundation that makes all of this possible.&lt;/p&gt;

&lt;p&gt;SurrealDS is a new generation distributed storage architecture, rethought from first principles. Instead of coupling storage to compute on a single box or to a proprietary cloud tier, SurrealDS embeds consensus directly in SurrealDB nodes and separates the two layers cleanly. Here's what that architecture gives you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture overview
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Compute and storage separation.&lt;/strong&gt; Scale compute for QPS and storage for capacity independently, so you provision for the dimension that's actually under pressure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No single leader.&lt;/strong&gt; Each availability-zone node writes locally, writes scale horizontally, and transactions commit once a quorum acknowledges them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multi-write nodes.&lt;/strong&gt; Every write node in the cluster can accept and coordinate transactions - there's no bottleneck routing all writes through one leader.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reduced operational overhead.&lt;/strong&gt; Consensus is embedded directly in SurrealDB nodes, eliminating external coordination services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fewer network dependencies.&lt;/strong&gt; A single broadcast replaces multi-hop coordination, reducing latency.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lower latency than leader-based replication.&lt;/strong&gt; With no single leader and each AZ node writing locally, transactions avoid the extra round trips of traditional leader-based systems.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Future roadmap
&lt;/h2&gt;

&lt;p&gt;Several SurrealDS capabilities are on the near-term roadmap and will land in the Scale tier as they ship:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Object-storage backed.&lt;/strong&gt; Persist transactional data directly to commodity object storage - storage costs drop and capacity scales far beyond any single disk.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cross-region replication.&lt;/strong&gt; Data flows through object storage rather than between nodes, significantly reducing data-transfer costs while keeping regions in sync.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Instant recovery.&lt;/strong&gt; A crashed node restores from object storage, with recovery time almost instant regardless of dataset size.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Instant branching.&lt;/strong&gt; Clone a petabyte-scale database in seconds for development, testing, or experimentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Get started
&lt;/h2&gt;

&lt;p&gt;If you're running SurrealDB in production, or getting ready to, Scale gives you the availability and fault-tolerance your workloads need, on the storage architecture no one else has.&lt;/p&gt;

&lt;p&gt;Explore the tier in &lt;a href="https://surrealdb.com/cloud" rel="noopener noreferrer"&gt;SurrealDB Cloud&lt;/a&gt;, and dig into the engine underneath at &lt;a href="https://surrealdb.com/platform/surrealds" rel="noopener noreferrer"&gt;SurrealDS&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>surrealdb</category>
      <category>surrealdbcloud</category>
      <category>cloud</category>
      <category>database</category>
    </item>
    <item>
      <title>SurrealDB is now available on the Nebius AI Cloud Marketplace</title>
      <dc:creator>Mark Gyles</dc:creator>
      <pubDate>Thu, 18 Jun 2026 15:33:29 +0000</pubDate>
      <link>https://dev.to/surrealdb/surrealdb-is-now-available-on-the-nebius-ai-cloud-marketplace-34fj</link>
      <guid>https://dev.to/surrealdb/surrealdb-is-now-available-on-the-nebius-ai-cloud-marketplace-34fj</guid>
      <description>&lt;p&gt;Author: &lt;a href="https://x.com/tobiemh" rel="noopener noreferrer"&gt;Tobie Morgan Hitchcock&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We're excited to announce that SurrealDB is now officially available on the Nebius AI Cloud Marketplace.&lt;/p&gt;

&lt;p&gt;This launch reflects our commitment to meeting developers and AI teams where they build, and deepens our partnership with Nebius to make SurrealDB easier to adopt, deploy, and scale on one of the fastest-growing AI cloud platforms in the world.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Nebius?
&lt;/h2&gt;

&lt;p&gt;Nebius is a full-stack AI cloud built for the demands of modern AI workloads. Powered by the latest GPU and high-performance networking infrastructure, with managed platform, serverless AI, and storage built for the entire AI lifecycle, Nebius gives teams the infrastructure to train, tune, and serve models at scale.&lt;/p&gt;

&lt;p&gt;As an NVIDIA Reference Platform Cloud Partner with infrastructure across Europe and the US, Nebius pairs bare-metal performance with the operational simplicity and cost efficiency that AI teams need to move from experiment to production. It's a natural home for SurrealDB - giving you a unified data layer right alongside the compute powering your AI and agentic applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why SurrealDB?
&lt;/h2&gt;

&lt;p&gt;SurrealDB combines document, graph, and relational capabilities in one unified database - designed for agent memory, context layers, modern applications, real-time systems, and AI-powered workloads.With flexible schema, SurrealQL, and built-in real-time features, SurrealDB enables you to build semantic and context layers powered by knowledge graphs for agent memory and multi-agentic workflows. &lt;/p&gt;

&lt;p&gt;SurrealDB simplifies your technology stack, reduces Total Cost of Ownership and operational complexity, and allows you to ship products and features in days rather than weeks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started
&lt;/h2&gt;

&lt;p&gt;SurrealDB is available now on the &lt;a href="https://console.nebius.com/project-e00j0yxxpr003gvmj7t4vd/applications/surrealdb" rel="noopener noreferrer"&gt;Nebius AI Cloud Marketplace&lt;/a&gt;. We can't wait to see what you build, join our &lt;a href="https://discord.com/invite/surrealdb" rel="noopener noreferrer"&gt;Discord community&lt;/a&gt; and let us know how you get on!&lt;/p&gt;

</description>
      <category>surrealdb</category>
      <category>database</category>
      <category>nebius</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
