<?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: P SAHANA</title>
    <description>The latest articles on DEV Community by P SAHANA (@sahna9353).</description>
    <link>https://dev.to/sahna9353</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3840083%2F390f0c54-308c-4298-ac4b-71c26fcf03a4.png</url>
      <title>DEV Community: P SAHANA</title>
      <link>https://dev.to/sahna9353</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sahna9353"/>
    <language>en</language>
    <item>
      <title>Hindsight Over a Database</title>
      <dc:creator>P SAHANA</dc:creator>
      <pubDate>Mon, 23 Mar 2026 13:21:40 +0000</pubDate>
      <link>https://dev.to/sahna9353/hindsight-over-a-database-3fh5</link>
      <guid>https://dev.to/sahna9353/hindsight-over-a-database-3fh5</guid>
      <description>&lt;p&gt;Why Our Team Chose Hindsight Over a Database&lt;/p&gt;

&lt;p&gt;The obvious solution was a database. A simple SQLite file, a tasks table, a decisions table — done in 20 minutes. Our AI Group Project Manager would read from it on every request and write to it after every interaction. Clean, predictable, debuggable.&lt;/p&gt;

&lt;p&gt;We didn't do that. Here's why, and what we learned from the choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With the Database Approach
&lt;/h2&gt;

&lt;p&gt;When we sat down to design the system, the database option felt safe. But the moment we thought through what the agent actually needed to do, the cracks appeared.&lt;/p&gt;

&lt;p&gt;A database stores rows. What we needed was for the agent to answer questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;"What's still pending from last week?"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"Who's most overloaded right now?"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"What decisions are relevant to Keerthana's current task?"&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These aren't row lookups. They're semantic queries over connected information. A SQL query for "what's relevant to this question?" doesn't exist. You'd have to build a retrieval layer on top of the database anyway — essentially building a memory system from scratch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/vectorize-io/hindsight" rel="noopener noreferrer"&gt;Hindsight&lt;/a&gt; is that memory system, already built.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Hindsight Gave Us Instead
&lt;/h2&gt;

&lt;p&gt;The core idea in &lt;a href="https://vectorize.io/features/agent-memory" rel="noopener noreferrer"&gt;Hindsight's agent memory architecture&lt;/a&gt; is that you store content — raw text describing what happened — and Hindsight handles the rest: extracting structured facts, building a knowledge graph, indexing for multiple retrieval strategies.&lt;/p&gt;

&lt;p&gt;From our FastAPI backend, every meaningful event goes through two operations:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;retain&lt;/strong&gt; — store something that happened:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_retain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;project&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;aretain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;bank_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;BANK_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;recall&lt;/strong&gt; — retrieve what's relevant to a question:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_recall_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&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="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arecall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bank_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;BANK_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&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;memories&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;hasattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;results&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;memories&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No prior project history found.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;- &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;memories&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;hasattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the entire memory layer. Two async methods. No schema design, no migrations, no query builder.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture Decision That Saved Us Time
&lt;/h2&gt;

&lt;p&gt;We had 8 hours. Three people. One working demo at the end.&lt;/p&gt;

&lt;p&gt;With a database approach, the time would have gone to: schema design, ORM setup, query writing for each endpoint, and then — critically — building some kind of retrieval layer to make the agent's answers actually good rather than just technically correct.&lt;/p&gt;

&lt;p&gt;With Hindsight, the time went to: wiring two methods into the agent, and tuning the LLM prompts. The retrieval layer was already there.&lt;/p&gt;

&lt;p&gt;Our FastAPI routes stayed clean because the agent handled everything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/assign-task&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;assign_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TaskInput&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;assigned_to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assigned_to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;deadline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deadline&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;result&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No database session. No ORM model. The agent's &lt;code&gt;assign_task&lt;/code&gt; method retains the memory and returns an LLM-generated response. The route just passes data through.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a Database Would Have Missed
&lt;/h2&gt;

&lt;p&gt;The most revealing moment came during testing. After storing a task for Sinchana and a separate decision to use React for the frontend, we asked: &lt;em&gt;"What is Sinchana working on?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The agent answered with the task — expected. But it also mentioned the React decision as relevant context for the frontend work, even though we'd never linked those two things explicitly.&lt;/p&gt;

&lt;p&gt;Hindsight's observation consolidation had connected them. The knowledge graph it builds internally recognised that a frontend task and a frontend technology decision were related, and the graph retrieval strategy surfaced both together.&lt;/p&gt;

&lt;p&gt;A database with a tasks table and a decisions table would have returned the task row. It would not have returned the decision. Making that connection would have required either a join we'd have to design in advance, or an embedding search we'd have to build ourselves.&lt;/p&gt;

&lt;p&gt;Hindsight did it automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Trade-offs We Accepted
&lt;/h2&gt;

&lt;p&gt;Choosing Hindsight over a database wasn't free of downsides.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No structured queries.&lt;/strong&gt; We can't ask "give me all tasks with status PENDING." We can ask "what tasks are still pending?" and get a good answer, but it's a semantic retrieval, not a structured filter. For a reporting dashboard with exact counts and filters, a database would be better.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The first session is thin.&lt;/strong&gt; Hindsight's recall quality improves as the bank grows. A fresh bank with one retained memory gives weaker answers than a bank with twenty. A database would have consistent behaviour from the first row.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Debugging is less direct.&lt;/strong&gt; With a database you can open a SQL client and see exactly what's stored. With Hindsight you query the bank and see what gets recalled — which is useful, but different from inspecting raw rows.&lt;/p&gt;

&lt;p&gt;For our use case — a conversational agent that answers semantic questions about project state — the trade-offs were worth it. For a system that needed exact counts, filters, and structured reporting, the database would have been the right call.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Tell Someone Making the Same Decision
&lt;/h2&gt;

&lt;p&gt;Use Hindsight if your agent needs to answer natural language questions about what happened. Use a database if your agent needs to filter, count, or join structured records.&lt;/p&gt;

&lt;p&gt;In many real systems you'd use both: a database for structured state, Hindsight for the memory layer that makes the agent's responses feel contextual and intelligent.&lt;/p&gt;

&lt;p&gt;For our 8-hour build, one layer was enough. And the layer that made the demo impressive — the cross-session memory, the connected recall, the agent that remembered who owned what after a full restart — was Hindsight.&lt;/p&gt;

&lt;p&gt;The code is on GitHub: &lt;a href="https://github.com/SinchanaNagaraj/ai-group-project-manager" rel="noopener noreferrer"&gt;github.com/SinchanaNagaraj/ai-group-project-manager&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're at the same decision point — database or memory system — &lt;a href="https://hindsight.vectorize.io/" rel="noopener noreferrer"&gt;Hindsight's documentation&lt;/a&gt; has a good RAG vs Memory comparison that helped clarify our thinking. Worth reading before you commit to either path.&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.amazonaws.com%2Fuploads%2Farticles%2F03if2uv5jrfatj2ule0x.jpeg" 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.amazonaws.com%2Fuploads%2Farticles%2F03if2uv5jrfatj2ule0x.jpeg" alt=" " width="800" height="376"&gt;&lt;/a&gt;&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.amazonaws.com%2Fuploads%2Farticles%2Fyj77kg84gr2v4cuz897t.jpeg" 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.amazonaws.com%2Fuploads%2Farticles%2Fyj77kg84gr2v4cuz897t.jpeg" alt=" " width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>hindsight</category>
      <category>ai</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
