<?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: puffball1567</title>
    <description>The latest articles on DEV Community by puffball1567 (@puffball1567).</description>
    <link>https://dev.to/puffball1567</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%2F4028036%2F318aece8-8f65-4e85-9c32-200838e42224.png</url>
      <title>DEV Community: puffball1567</title>
      <link>https://dev.to/puffball1567</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/puffball1567"/>
    <language>en</language>
    <item>
      <title>Hello, RocheDB! A Nim Database Built Around Data Locality</title>
      <dc:creator>puffball1567</dc:creator>
      <pubDate>Tue, 14 Jul 2026 06:00:43 +0000</pubDate>
      <link>https://dev.to/puffball1567/hello-rochedb-a-nim-database-built-around-data-locality-22co</link>
      <guid>https://dev.to/puffball1567/hello-rochedb-a-nim-database-built-around-data-locality-22co</guid>
      <description>&lt;p&gt;Hello! I am building &lt;strong&gt;RocheDB&lt;/strong&gt;, an open-source NoSQL document and vector store written in Nim.&lt;/p&gt;

&lt;p&gt;The project starts with a simple question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What if a database could avoid opening unrelated data before expensive&lt;br&gt;
retrieval and application processing begin?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Modern systems accumulate documents, tenant data, application state, embeddings, logs, and knowledge bases. A request can spend significant resources on data that is not ultimately useful: reading it, transferring it, holding it in memory, reranking it, summarizing it, or passing it into an LLM context.&lt;/p&gt;

&lt;p&gt;RocheDB is my attempt to make an application's natural data locality part of the storage and retrieval model.&lt;/p&gt;

&lt;h2&gt;
  
  
  The central idea: a ring
&lt;/h2&gt;

&lt;p&gt;RocheDB uses a &lt;strong&gt;ring&lt;/strong&gt; as a semantic and structural placement unit.&lt;/p&gt;

&lt;p&gt;An application or import rule chooses a ring when writing data. That same ring can then define the initial scope of a read.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docs/japan/support
tenant/acme/orders/2026
users/123/profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;These are not merely directory-like names. They are coordinates in the retrieval space. Records placed in the same ring are expected to be useful neighbors for retrieval.&lt;/p&gt;

&lt;p&gt;That makes a ring different from an ordinary collection label. It says both:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;where a record belongs; and&lt;/li&gt;
&lt;li&gt;which local region should be opened first for a request.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  A ring is not a B+ tree
&lt;/h2&gt;

&lt;p&gt;RocheDB rings are not intended to replace B+ trees.&lt;/p&gt;

&lt;p&gt;A B+ tree organizes data by ordered keys. It is excellent for primary-key reads, secondary-index lookups, time ranges, sorted pagination, and other queries that can be expressed as a key lookup or key range scan.&lt;/p&gt;

&lt;p&gt;A B+ tree answers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Where is this key or key range?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A RocheDB ring answers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which local region of the data should be opened first in this context?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They optimize different parts of a system. A B+ tree makes ordered key access efficient. A ring tries to reduce the semantic candidate set before more expensive downstream work begins.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why orbital mechanics?
&lt;/h2&gt;

&lt;p&gt;The naming and part of the model are inspired by orbital mechanics.&lt;/p&gt;

&lt;p&gt;In an orbital system, a body's position can be estimated from compact orbital elements such as period, phase or epoch, eccentricity, and semi-major axis.&lt;/p&gt;

&lt;p&gt;RocheDB uses that as an engineering abstraction.&lt;/p&gt;

&lt;p&gt;A ring is like a semantic data orbit. Records in a ring inherit lightweight orbital metadata, including values such as a period and &lt;code&gt;headAngle&lt;/code&gt;. This lets a ring act as both a placement unit and a small part of the query plan.&lt;/p&gt;

&lt;p&gt;The celestial-mechanics vocabulary—rings, orbits, encounters, and&lt;br&gt;
accretion—is not the value proposition. RocheDB is not a physics simulator.&lt;/p&gt;

&lt;p&gt;The useful idea is that placement, movement, proximity, and retrieval scope can be explicit and observable, rather than hidden behind a central directory or reconstructed for every request.&lt;/p&gt;


&lt;div class="crayons-card c-embed"&gt;

  &lt;br&gt;
&lt;strong&gt;The short version:&lt;/strong&gt; RocheDB uses application-level locality to reduce the candidate set &lt;em&gt;before&lt;/em&gt; expensive retrieval, reranking, memory use, network transfer, or LLM context construction begins.&lt;br&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A small example
&lt;/h2&gt;

&lt;p&gt;Here is what ring placement looks like from Nim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nim"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="n"&gt;rochedb&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rochedb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataDir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setRingDescription&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="s"&gt;"docs/japan"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;"Japanese product documentation and support articles"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;discard&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="s"&gt;"""{"slug":"refund","title":"Refund guide"}"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;ring&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"docs/japan"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;discard&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="s"&gt;"""{"slug":"setup","title":"Setup guide"}"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;ring&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"docs/japan"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If the application already knows that it needs Japanese documentation, it can&lt;br&gt;
start with that ring:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nim"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;listByRing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"docs/japan"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The same idea applies to vector retrieval:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nim"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;@[&lt;/span&gt;&lt;span class="mf"&gt;1.0'f32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.0'f32&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;hits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;retrieve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;ring&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"docs/japan"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;budget&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;hits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The important detail is that &lt;code&gt;docs/japan&lt;/code&gt; is not a label added after the retrieval. It is a placement decision at write time and an initial scope for reads.&lt;/p&gt;

&lt;p&gt;Applications are still responsible for designing useful rings. But many already know meaningful locality: tenant, region, product area, document domain, user, or time range. RocheDB is an attempt to let the database use that information directly.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why this matters for AI, RAG, and web systems
&lt;/h2&gt;

&lt;p&gt;For transactional workloads, an efficient indexed lookup is often enough.&lt;/p&gt;

&lt;p&gt;For retrieval-heavy workloads, finding one row is not always the expensive part. The larger cost can be dealing with a wide set of semantically weak candidates after the lookup.&lt;/p&gt;

&lt;p&gt;This is particularly relevant to AI and RAG systems. A database may efficiently retrieve a key range, but the result can still contain many weak candidates.&lt;/p&gt;

&lt;p&gt;Those candidates may then be embedded, reranked, summarized, kept in memory, or sent to an LLM.&lt;/p&gt;

&lt;p&gt;RocheDB tries to reduce that candidate set earlier.&lt;/p&gt;

&lt;p&gt;When ring placement reflects useful locality, the expected benefits are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fewer records to rank;&lt;/li&gt;
&lt;li&gt;fewer payloads held in memory;&lt;/li&gt;
&lt;li&gt;fewer bytes transferred between services;&lt;/li&gt;
&lt;li&gt;fewer tokens passed to downstream LLMs;&lt;/li&gt;
&lt;li&gt;clearer boundaries for tenants, regions, backups, migrations, and
authorization.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What the early numbers show
&lt;/h2&gt;

&lt;p&gt;The current benchmarks do &lt;strong&gt;not&lt;/strong&gt; claim that RocheDB is universally faster than every B+ tree-based database.&lt;/p&gt;

&lt;p&gt;They test a narrower hypothesis: when ring placement captures useful locality, can RocheDB reduce the working set and downstream candidate volume while keeping the read path lightweight?&lt;/p&gt;


&lt;div class="crayons-card c-embed"&gt;

  &lt;br&gt;
&lt;strong&gt;Working-set benchmark&lt;/strong&gt;

&lt;p&gt;With 100 rings and 10,000 documents, the number of records scanned per query decreased from &lt;strong&gt;10,000 to 100&lt;/strong&gt;: a &lt;strong&gt;99% reduction&lt;/strong&gt; in the candidate working set.&lt;br&gt;

&lt;/p&gt;
&lt;/div&gt;




&lt;div class="crayons-card c-embed"&gt;

  &lt;br&gt;
&lt;strong&gt;Memory-pressure benchmark&lt;/strong&gt;

&lt;p&gt;With 100 rings, 100,000 documents, and 512-byte payloads, candidate memory per query decreased from &lt;strong&gt;93.079 MiB to 0.931 MiB&lt;/strong&gt;: also a &lt;strong&gt;99% reduction&lt;/strong&gt;.&lt;br&gt;

&lt;/p&gt;
&lt;/div&gt;



&lt;div class="crayons-card c-embed"&gt;

  &lt;br&gt;
&lt;strong&gt;RAG-oriented cases&lt;/strong&gt;

&lt;p&gt;In a fixed-quality synthetic RAG case, records scanned decreased from &lt;strong&gt;8,000 to 1,000&lt;/strong&gt; and tokens per query from &lt;strong&gt;3960 to 657.8&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In a 400-document, 6-ring AI/RAG case study, records scanned decreased from &lt;strong&gt;400 to 40&lt;/strong&gt;, while tokens per query decreased from &lt;strong&gt;615.2 to 231.6&lt;/strong&gt; with recall remaining &lt;strong&gt;1.000&lt;/strong&gt;.&lt;br&gt;

&lt;/p&gt;
&lt;/div&gt;


&lt;p&gt;These are early, reproducible results rather than universal performance claims.&lt;/p&gt;

&lt;p&gt;They depend on ring placement expressing useful locality. The benchmark scripts,&lt;/p&gt;

&lt;p&gt;their conditions, and their limitations are in the project repository.&lt;/p&gt;

&lt;p&gt;Source code, documentation, benchmark scripts, and issue tracking are available at &lt;a href="https://github.com/puffball1567/rochedb" rel="noopener noreferrer"&gt;github.com/puffball1567/rochedb&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A longer-term hope
&lt;/h2&gt;

&lt;p&gt;The immediate goal is practical: reduce unnecessary candidate data before expensive downstream processing.&lt;/p&gt;

&lt;p&gt;If that can also contribute over time to lower token consumption in AI and RAG systems, less energy spent on unnecessary reads and computation, and less pressure to continually expand memory, storage, and compute hardware capacity, that would be a meaningful result.&lt;/p&gt;

&lt;p&gt;RocheDB alone will not directly solve token, energy, or semiconductor demand.&lt;/p&gt;

&lt;p&gt;But avoiding unnecessary data movement seems like a useful place to start.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current boundaries
&lt;/h2&gt;

&lt;p&gt;RocheDB is not a replacement for every database or every B+ tree use case.&lt;/p&gt;

&lt;p&gt;It is most interesting when an application already has meaningful locality:&lt;br&gt;
tenants, users, regions, topics, document groups, time partitions,&lt;br&gt;
prompt/context stores, or RAG document collections.&lt;/p&gt;

&lt;p&gt;It is currently a technical preview. I am not presenting it as a production replacement for PostgreSQL, Redis, MongoDB, or dedicated vector databases.&lt;/p&gt;

&lt;p&gt;RocheDB provides a Nim API, CLI, server mode, C ABI, and language drivers. In this series, I plan to write about ring placement, retrieval, cluster behavior, benchmarks, Nim implementation details, and driver development.&lt;/p&gt;

&lt;p&gt;I hope RocheDB can be useful both as a practical experiment in reducing unnecessary data movement and as a way to explore what a locality-first database model can look like.&lt;/p&gt;

&lt;p&gt;Feedback, questions, and use cases are very welcome.&lt;/p&gt;

</description>
      <category>nim</category>
      <category>database</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
