<?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: Jamal Saad</title>
    <description>The latest articles on DEV Community by Jamal Saad (@slipxnot).</description>
    <link>https://dev.to/slipxnot</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%2F2167850%2Fcbf8ae49-817e-4ac7-926f-454941e22ef9.jpg</url>
      <title>DEV Community: Jamal Saad</title>
      <link>https://dev.to/slipxnot</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/slipxnot"/>
    <language>en</language>
    <item>
      <title>Why modern real-time apps require 5 different systems — and why I built one instead</title>
      <dc:creator>Jamal Saad</dc:creator>
      <pubDate>Mon, 09 Mar 2026 10:29:09 +0000</pubDate>
      <link>https://dev.to/slipxnot/why-modern-real-time-apps-require-5-different-systems-and-why-i-built-one-instead-1lm7</link>
      <guid>https://dev.to/slipxnot/why-modern-real-time-apps-require-5-different-systems-and-why-i-built-one-instead-1lm7</guid>
      <description>&lt;p&gt;Modern apps are expected to feel live.&lt;/p&gt;

&lt;p&gt;Chat apps, AI products, collaborative tools, notifications, activity feeds — they all need fast writes, real-time updates, and storage that does not become expensive as data grows.&lt;/p&gt;

&lt;p&gt;But the usual backend stack gets complicated fast.&lt;/p&gt;

&lt;p&gt;You store data in one system.&lt;br&gt;
You push live updates with another.&lt;br&gt;
You archive old data somewhere cheaper.&lt;br&gt;
You add extra glue code to keep everything in sync.&lt;/p&gt;

&lt;p&gt;That complexity is exactly what pushed me to build &lt;strong&gt;KalamDB&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;KalamDB is an open-source, SQL-first real-time database designed around a simple idea: keep recent data fast, move older data to cheaper storage, and let developers subscribe to changes directly from the database. The project is explicitly aimed at speed, efficiency, and minimal resource use, with a goal of reducing CPU, memory, storage, and infrastructure cost.&lt;/p&gt;

&lt;p&gt;At the core of KalamDB is a &lt;strong&gt;two-tier storage model&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;New writes first land in &lt;strong&gt;RocksDB hot storage&lt;/strong&gt;, which gives very fast acknowledgments and keeps recent data close for quick reads. Later, that data is flushed into &lt;strong&gt;columnar Parquet files&lt;/strong&gt; in filesystem or object storage, where it becomes much cheaper to keep for the long term. Queries can read across both tiers, so applications get fresh data from hot storage and older history from cold storage without needing separate systems.&lt;/p&gt;

&lt;p&gt;KalamDB also supports &lt;strong&gt;three table types&lt;/strong&gt;, and that matters a lot for cost and design.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;USER tables&lt;/strong&gt; isolate data per user and flush each user’s partition into separate Parquet files. That makes them a strong fit for chat history, tenant data, and privacy-sensitive workloads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SHARED tables&lt;/strong&gt; store global data once for everyone, which works well for configuration data, reference datasets, and cross-user analytics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STREAM tables&lt;/strong&gt; are designed for short‑lived real-time events like typing indicators, presence, AI thinking signals, or notifications. They stay in memory or RocksDB hot storage, use TTL-based eviction, and are never flushed to Parquet.&lt;/p&gt;

&lt;p&gt;Another big part of the design is the &lt;strong&gt;table-per-user architecture&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of putting all users into one giant shared table and filtering constantly, KalamDB stores each user’s data in isolated partitions. That makes real-time subscriptions simpler and helps the system scale more naturally for workloads like conversations, notifications, and AI history. The idea is to reduce complexity while keeping performance predictable as the number of users grows.&lt;/p&gt;
&lt;h2&gt;
  
  
  What it feels like to use KalamDB
&lt;/h2&gt;

&lt;p&gt;Instead of constantly polling the database for updates, applications can subscribe to changes directly from SQL.&lt;/p&gt;

&lt;p&gt;For example, a chat application can subscribe to new messages in a conversation:&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="n"&gt;SUBSCRIBE&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;conversation_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;OPTIONS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;last_rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whenever a new row is inserted into the table, the client instantly receives the update through a WebSocket connection.&lt;/p&gt;

&lt;p&gt;The same idea can be used from application code using the JavaScript SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Auth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SeqId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;kalam-link&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:8080&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;authProvider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;ACCESS_TOKEN&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stopMessages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;live&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="s2"&gt;`SELECT id, room, role, content, created_at
    FROM chat.messages`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// `chat.messages` can be a USER table.&lt;/span&gt;
    &lt;span class="c1"&gt;// The same query runs for every signed-in customer, but KalamDB only&lt;/span&gt;
    &lt;span class="c1"&gt;// returns that caller's rows.&lt;/span&gt;
    &lt;span class="nf"&gt;renderRows&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;subscriptionOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;last_rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SeqId&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;7262216745594062848&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;INSERT INTO chat.messages (room, role, content) VALUES ($1, $2, $3)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;main&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello from the browser&lt;/span&gt;&lt;span class="dl"&gt;'&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;This is the type of pattern KalamDB was designed for: real-time apps where data storage and live updates happen in the same system.&lt;/p&gt;

&lt;p&gt;That is the real reason I built KalamDB.&lt;/p&gt;

&lt;p&gt;Not to add another database to the world, but to cut down the amount of infrastructure developers have to stitch together just to build something real-time.&lt;/p&gt;

&lt;p&gt;Less glue code.&lt;br&gt;
Less storage waste.&lt;br&gt;
Less operational overhead.&lt;br&gt;
And a simpler path from fast writes to cheaper long-term storage.&lt;/p&gt;

&lt;p&gt;KalamDB is still in development, and I would describe &lt;strong&gt;file storage/BLOB support&lt;/strong&gt; and &lt;strong&gt;high availability&lt;/strong&gt; as part of the direction, not current production-ready features yet. But the core idea is already clear: a database built to make real-time apps simpler and cheaper to run.&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%2F0breybe9ph04f5x9cpc4.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.amazonaws.com%2Fuploads%2Farticles%2F0breybe9ph04f5x9cpc4.png" alt=" " width="800" height="613"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;If you want to explore KalamDB:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🌐 &lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://kalamdb.org" rel="noopener noreferrer"&gt;kalamdb.org&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;⭐ &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/jamals86/KalamDB" rel="noopener noreferrer"&gt;KalamDB on GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Quick Start:&lt;/strong&gt; &lt;a href="https://kalamdb.org/docs/getting-started" rel="noopener noreferrer"&gt;Run KalamDB locally&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;Docs:&lt;/strong&gt; &lt;a href="https://kalamdb.org/docs" rel="noopener noreferrer"&gt;Learn the SQL syntax&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>database</category>
      <category>backend</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
