<?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: Naman Vashistha</title>
    <description>The latest articles on DEV Community by Naman Vashistha (@namanvashistha).</description>
    <link>https://dev.to/namanvashistha</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%2F525517%2F7635be3e-aef0-4603-a260-93486fe7f908.jpg</url>
      <title>DEV Community: Naman Vashistha</title>
      <link>https://dev.to/namanvashistha</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/namanvashistha"/>
    <language>en</language>
    <item>
      <title>Technical Strategy: Thinking Beyond the Current Sprint</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Tue, 25 Aug 2026 15:24:00 +0000</pubDate>
      <link>https://dev.to/namanvashistha/technical-strategy-thinking-beyond-the-current-sprint-1o24</link>
      <guid>https://dev.to/namanvashistha/technical-strategy-thinking-beyond-the-current-sprint-1o24</guid>
      <description>&lt;p&gt;It’s easy to optimise for the thing directly in front of us.&lt;/p&gt;

&lt;p&gt;A feature needs to ship. A bug needs fixing. A deadline is approaching.&lt;/p&gt;

&lt;p&gt;So we make the decision that gets us there fastest.&lt;/p&gt;

&lt;p&gt;Sometimes that’s exactly the right decision.&lt;/p&gt;

&lt;p&gt;But technical strategy is about asking one more question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“What does this decision mean for us six months from now?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A technical decision usually has at least two dimensions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Immediate value&lt;/strong&gt; — Can we solve the problem now?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Long-term impact&lt;/strong&gt; — What will this make easier or harder later?&lt;/p&gt;

&lt;p&gt;This doesn’t mean building everything for the future.&lt;/p&gt;

&lt;p&gt;In fact, over-engineering can be just as harmful as technical debt.&lt;/p&gt;

&lt;p&gt;The useful question is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“What future are we actually likely to need?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example, if we’re repeatedly building similar AI applications from scratch, it might be worth investing in reusable infrastructure or common components.&lt;/p&gt;

&lt;p&gt;But if something has only been built once, building a large framework for hypothetical future use may simply create unnecessary complexity.&lt;/p&gt;

&lt;p&gt;So technical strategy isn’t about always choosing the “cleanest” architecture.&lt;/p&gt;

&lt;p&gt;It’s about making &lt;strong&gt;deliberate trade-offs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Things worth considering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What are we optimising for?&lt;/li&gt;
&lt;li&gt;What will this decision cost us later?&lt;/li&gt;
&lt;li&gt;Are we creating unnecessary coupling?&lt;/li&gt;
&lt;li&gt;Is this becoming a repeated pattern?&lt;/li&gt;
&lt;li&gt;What should be standardised?&lt;/li&gt;
&lt;li&gt;What should remain flexible?&lt;/li&gt;
&lt;li&gt;Where is technical debt actually worth taking?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal isn’t to predict the future perfectly.&lt;/p&gt;

&lt;p&gt;It’s to make decisions today while being conscious of the future they create.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good technical strategy isn’t building for every possible future. It’s avoiding decisions that unnecessarily limit the futures you may actually need.&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Checkpoints vs Micromanagement</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Tue, 25 Aug 2026 15:20:00 +0000</pubDate>
      <link>https://dev.to/namanvashistha/checkpoints-vs-micromanagement-4daa</link>
      <guid>https://dev.to/namanvashistha/checkpoints-vs-micromanagement-4daa</guid>
      <description>&lt;p&gt;If someone has ownership, when should you check on their work?&lt;/p&gt;

&lt;p&gt;Too little involvement can mean discovering problems too late.&lt;/p&gt;

&lt;p&gt;Too much involvement becomes micromanagement.&lt;/p&gt;

&lt;p&gt;I think the difference is &lt;strong&gt;what the checkpoint is trying to achieve&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A useful checkpoint asks:&lt;/p&gt;

&lt;p&gt;“Are we still solving the right problem, and do you need anything from me?”&lt;/p&gt;

&lt;p&gt;Micromanagement asks:&lt;/p&gt;

&lt;p&gt;“Why did you do it this way? Change this. Then do this next.”&lt;/p&gt;

&lt;p&gt;The first keeps ownership with the person.&lt;/p&gt;

&lt;p&gt;The second gradually takes it away.&lt;/p&gt;

&lt;p&gt;A checkpoint can be as simple as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agree on the approach before starting.&lt;/li&gt;
&lt;li&gt;Share an early draft.&lt;/li&gt;
&lt;li&gt;Discuss progress after a meaningful milestone.&lt;/li&gt;
&lt;li&gt;Review the result before it becomes difficult to change.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important part is that the checkpoint should happen &lt;strong&gt;early enough to change the outcome&lt;/strong&gt; , without requiring the person to get approval for every decision.&lt;/p&gt;

&lt;p&gt;The amount of checking should also change with the situation.&lt;/p&gt;

&lt;p&gt;A new engineer working on an unfamiliar problem may need frequent checkpoints.&lt;/p&gt;

&lt;p&gt;Someone experienced and familiar with the problem may need very little intervention.&lt;/p&gt;

&lt;p&gt;So the goal isn’t:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Never check.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It’s:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Check enough to reduce risk without taking away ownership.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A checkpoint should help someone succeed without making them dependent on you.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>leadership</category>
      <category>management</category>
    </item>
    <item>
      <title>Ownership: A Task or a Problem?</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Tue, 25 Aug 2026 15:13:00 +0000</pubDate>
      <link>https://dev.to/namanvashistha/ownership-a-task-or-a-problem-931</link>
      <guid>https://dev.to/namanvashistha/ownership-a-task-or-a-problem-931</guid>
      <description>&lt;p&gt;There’s a subtle difference between &lt;strong&gt;assigning someone a task&lt;/strong&gt; and &lt;strong&gt;giving someone ownership&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A task sounds like:&lt;/p&gt;

&lt;p&gt;“Implement this API.”&lt;/p&gt;

&lt;p&gt;Ownership sounds more like:&lt;/p&gt;

&lt;p&gt;“We need to solve this problem. You own figuring out the right solution.”&lt;/p&gt;

&lt;p&gt;The difference is who is responsible for thinking about the outcome.&lt;/p&gt;

&lt;p&gt;With a task, the person can successfully complete exactly what was asked and still fail to solve the underlying problem.&lt;/p&gt;

&lt;p&gt;With ownership, they have to understand the &lt;strong&gt;why&lt;/strong&gt; , make decisions, identify problems, and figure out when they need help.&lt;/p&gt;

&lt;p&gt;But ownership doesn’t mean leaving someone alone.&lt;/p&gt;

&lt;p&gt;Especially when someone is new, they may need more context, smaller checkpoints, or help thinking through the problem.&lt;/p&gt;

&lt;p&gt;A useful progression is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task → Responsibility → Ownership → Autonomy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And ownership should come with enough &lt;strong&gt;authority&lt;/strong&gt; to actually make decisions. Holding someone responsible for an outcome while making every decision for them isn’t really ownership.&lt;/p&gt;

&lt;p&gt;The goal isn’t to distribute tasks.&lt;/p&gt;

&lt;p&gt;It’s to gradually distribute &lt;strong&gt;problems, decisions, and responsibility for outcomes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Give people something to own, not just something to do.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>leadership</category>
      <category>management</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Feedback Loops: How Teams Get Better</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Tue, 25 Aug 2026 14:57:00 +0000</pubDate>
      <link>https://dev.to/namanvashistha/feedback-loops-how-teams-get-better-2790</link>
      <guid>https://dev.to/namanvashistha/feedback-loops-how-teams-get-better-2790</guid>
      <description>&lt;p&gt;A team can have good people, good processes, and clear goals - and still move slowly.&lt;/p&gt;

&lt;p&gt;One reason can be simple: &lt;strong&gt;the feedback loop is too long.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine someone spends three days working on something, only to discover during review that the approach was wrong.&lt;/p&gt;

&lt;p&gt;The problem isn’t necessarily the person.&lt;/p&gt;

&lt;p&gt;The team found out too late.&lt;/p&gt;

&lt;p&gt;A feedback loop is simply:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Action → Result → Feedback → Adjustment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The shorter the useful feedback loop, the faster the team can learn.&lt;/p&gt;

&lt;p&gt;This applies everywhere:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A small technical discussion before starting a large implementation.&lt;/li&gt;
&lt;li&gt;A quick design review before writing the whole thing.&lt;/li&gt;
&lt;li&gt;A PR reviewed while the context is still fresh.&lt;/li&gt;
&lt;li&gt;A short demo instead of waiting until everything is finished.&lt;/li&gt;
&lt;li&gt;A checkpoint when someone is exploring an unfamiliar problem.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But shorter doesn’t mean &lt;strong&gt;more meetings&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The goal is to find the &lt;strong&gt;cheapest point at which useful feedback can change the outcome&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There’s also a feedback loop at the team level.&lt;/p&gt;

&lt;p&gt;Something goes wrong → understand why → change something → see whether it worked.&lt;/p&gt;

&lt;p&gt;If the same problem keeps appearing, the team isn’t really learning from the feedback.&lt;/p&gt;

&lt;p&gt;So I think a useful question is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“How long does it take us to discover that we’re going in the wrong direction?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reducing that time can be one of the simplest ways to improve how a team works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don’t just create feedback. Create feedback early enough to matter.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>management</category>
      <category>productivity</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Clarity Before Autonomy</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Tue, 25 Aug 2026 14:43:00 +0000</pubDate>
      <link>https://dev.to/namanvashistha/clarity-before-autonomy-6m9</link>
      <guid>https://dev.to/namanvashistha/clarity-before-autonomy-6m9</guid>
      <description>&lt;p&gt;There is a balance I keep coming back to when working with a team:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much direction should I give, and how much should I leave to the person doing the work?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Too little direction creates confusion.&lt;/p&gt;

&lt;p&gt;Too much direction creates dependency.&lt;/p&gt;

&lt;p&gt;The useful middle ground seems to be:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;High clarity, high autonomy.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But what does clarity actually mean?&lt;/p&gt;

&lt;p&gt;Before handing over a problem, I think there are a few things worth making clear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Context:&lt;/strong&gt; Why are we doing this?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Outcome:&lt;/strong&gt; What are we trying to achieve?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Constraints:&lt;/strong&gt; What limitations or decisions already exist?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Definition of good:&lt;/strong&gt; What does a good result look like?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ownership:&lt;/strong&gt; Who is responsible for getting it there?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once these are clear, the &lt;strong&gt;how&lt;/strong&gt; can usually belong to the person doing the work.&lt;/p&gt;

&lt;p&gt;For example, instead of:&lt;/p&gt;

&lt;p&gt;“Build this using X, Y and Z.”&lt;/p&gt;

&lt;p&gt;it can be:&lt;/p&gt;

&lt;p&gt;“We need to solve X because of Y. These are the constraints. A successful solution should achieve Z. You own figuring out the approach.”&lt;/p&gt;

&lt;p&gt;That creates room for someone to think, make decisions, and learn.&lt;/p&gt;

&lt;p&gt;There is also an important distinction between &lt;strong&gt;autonomy and abandonment&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Giving someone ownership doesn’t mean disappearing. Checkpoints and feedback are still necessary, especially when someone is new or the problem is unfamiliar.&lt;/p&gt;

&lt;p&gt;So perhaps the simple model is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clarity → Autonomy → Checkpoints → Feedback&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Give enough clarity to start.&lt;/p&gt;

&lt;p&gt;Give enough autonomy to think.&lt;/p&gt;

&lt;p&gt;Use checkpoints to catch problems early.&lt;/p&gt;

&lt;p&gt;Use feedback to help the person improve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The goal isn’t to tell people what to do. It’s to give them enough clarity that they can figure out what to do next.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>leadership</category>
      <category>management</category>
      <category>productivity</category>
    </item>
    <item>
      <title>A Simple Framework for Working With a Team</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Tue, 25 Aug 2026 14:35:00 +0000</pubDate>
      <link>https://dev.to/namanvashistha/a-simple-framework-for-working-with-a-team-2iep</link>
      <guid>https://dev.to/namanvashistha/a-simple-framework-for-working-with-a-team-2iep</guid>
      <description>&lt;p&gt;A useful way to think about working with a team is through &lt;strong&gt;five areas&lt;/strong&gt; :&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Communication&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Create shared understanding.&lt;/strong&gt; Give context, expectations, and feedback clearly, and listen to make sure everyone is on the same page.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Execution&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Turn plans into reliable delivery.&lt;/strong&gt; Focus on prioritization, scoping, ownership, checkpoints, and follow-through.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. People Development&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Help people become better and more independent.&lt;/strong&gt; Use coaching, delegation, feedback, and progressively harder problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Systems Thinking&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Understand what is producing the outcome.&lt;/strong&gt; Look beyond individual events and examine processes, incentives, feedback loops, bottlenecks, and interactions between people and tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;5. Technical Strategy&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Balance today’s work with tomorrow’s technical health.&lt;/strong&gt; Make technical decisions with both immediate delivery and long-term consequences in mind.&lt;/p&gt;

&lt;p&gt;These areas overlap.&lt;/p&gt;

&lt;p&gt;For example, if someone repeatedly produces poor-quality work, it could be a &lt;strong&gt;people development&lt;/strong&gt; issue. But it could also involve &lt;strong&gt;communication&lt;/strong&gt; (unclear expectations), &lt;strong&gt;execution&lt;/strong&gt; (no checkpoints), or &lt;strong&gt;systems thinking&lt;/strong&gt; (a process that makes mistakes easy to miss).&lt;/p&gt;

&lt;p&gt;A useful sequence is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clarity → Ownership → Action → Feedback → Learning → Improvement&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The goal isn’t to control every part of the team’s work.&lt;/p&gt;

&lt;p&gt;It’s to create enough &lt;strong&gt;clarity, autonomy, feedback, and ownership&lt;/strong&gt; that good work becomes easier to repeat and people become increasingly independent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don’t just solve the immediate problem. Understand what produced it, then improve that part of the system.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>leadership</category>
      <category>management</category>
    </item>
    <item>
      <title>An ESP32 tracker. The largest number shows total active days for longt…</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Thu, 18 Jun 2026 13:46:00 +0000</pubDate>
      <link>https://dev.to/namanvashistha/an-esp32-tracker-the-largest-number-shows-total-active-days-for-longt-4mk4</link>
      <guid>https://dev.to/namanvashistha/an-esp32-tracker-the-largest-number-shows-total-active-days-for-longt-4mk4</guid>
      <description>&lt;p&gt;An ESP32 tracker. The largest number shows total active days for long-term accountability, the colour indicates today’s accountability status, and a separate indicator tracks weekly accountability.&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%2F2s0kjuw7qtmim5vsihqp.webp" 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%2F2s0kjuw7qtmim5vsihqp.webp" alt="An ESP32 accountability tracker display" width="800" height="1422"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Lately, I’ve been thinking about setting up my homelab again. I still…</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Thu, 18 Jun 2026 13:18:00 +0000</pubDate>
      <link>https://dev.to/namanvashistha/lately-ive-been-thinking-about-setting-up-my-homelab-again-i-still-3385</link>
      <guid>https://dev.to/namanvashistha/lately-ive-been-thinking-about-setting-up-my-homelab-again-i-still-3385</guid>
      <description>&lt;p&gt;Lately, I’ve been thinking about setting up my homelab again. I still have a small setup where I run my personal projects, but I want to deploy a full LLM stack. I also want to try Odyssey, although I don’t really have a use case for it yet.&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>infrastructure</category>
      <category>llm</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>Gardening and the Pace of Things</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Tue, 17 Feb 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/namanvashistha/gardening-and-the-pace-of-things-4ghi</link>
      <guid>https://dev.to/namanvashistha/gardening-and-the-pace-of-things-4ghi</guid>
      <description>&lt;p&gt;I am a software engineer, so most of my day is in front of a screen. Things respond quickly there. Code compiles or it doesn't, a message gets a reply, something either works or it breaks. I got used to that without really noticing I had.&lt;/p&gt;

&lt;p&gt;I had always liked the idea of gardening, just never done it. At some point the time and situation felt right and I started. Also wanted to do something that had nothing to do with screens or electronics. Soil, water, sunlight. That was the appeal.&lt;/p&gt;

&lt;p&gt;I water a plant and walk away not knowing if it did anything. The soil looks the same the next morning, the leaves don't visibly change, and if something is happening it's somewhere I can't see. Weeks went by where I couldn't really tell if I was helping or just showing up.&lt;/p&gt;

&lt;p&gt;Then one morning a leaf had an odd color, slightly yellow at the edges and curling inward. I took a photo and sent it to ChatGPT out of curiosity. It gave me a confident answer. I read it, tried to understand what the plant might need, and moved on. Somewhere along the way I realized I had started paying more attention to the plant itself rather than looking for someone to tell me what was wrong with it.&lt;/p&gt;

&lt;p&gt;The basics turned out to be most of it. Good soil, mostly. Something to hold moisture, something to let it drain, something to feed the roots. Soil, cocopeat &amp;amp; compost. The balance matters more than the ingredients. And water only when the soil asks for it, not before.&lt;/p&gt;

&lt;p&gt;One plant died and I still don't know why. By the time something was clearly wrong it was already too late. There was no obvious moment I could point to.&lt;/p&gt;

&lt;p&gt;The others came up slowly. Quietly, in their own order, at their own pace. It was nice to watch.&lt;/p&gt;

&lt;p&gt;Some plants have looked exactly the same for weeks now. Same height, same leaves, no visible change. I notice it, but it doesn't pull at me the way it used to. I water, I check the soil, I watch. Most mornings that's enough.&lt;/p&gt;

</description>
      <category>reflection</category>
      <category>gardening</category>
      <category>patience</category>
      <category>mindset</category>
    </item>
    <item>
      <title>Automating LimeDB LXC Container Deployment on Proxmox</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Fri, 21 Nov 2025 17:08:29 +0000</pubDate>
      <link>https://dev.to/namanvashistha/automating-limedb-lxc-container-deployment-on-proxmox-905</link>
      <guid>https://dev.to/namanvashistha/automating-limedb-lxc-container-deployment-on-proxmox-905</guid>
      <description>&lt;p&gt;Github: &lt;a href="https://github.com/namanvashistha/limedb/commit/8fe072ece279b6678243716f1f659e159da48c0c" rel="noopener noreferrer"&gt;namanvashistha/limedb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This commit introduces a new bash script, &lt;code&gt;proxmox/limedb_lxc.sh&lt;/code&gt;, designed to automate the provisioning and setup of a LimeDB instance within an LXC container on a Proxmox VE host.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Changed
&lt;/h3&gt;

&lt;p&gt;A new executable bash script (&lt;code&gt;limedb_lxc.sh&lt;/code&gt;) has been added to the repository's &lt;code&gt;proxmox/&lt;/code&gt; directory. This script provides a single-command solution for deploying a fully functional LimeDB server in a containerized environment on Proxmox.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why the Change Was Needed
&lt;/h3&gt;

&lt;p&gt;Deploying a distributed key-value store like LimeDB often involves repetitive setup steps, especially when provisioning multiple instances for a cluster or for development/testing environments. Manually creating LXC containers, configuring their resources, installing dependencies, downloading and setting up LimeDB, and configuring its systemd service can be time-consuming and prone to human error. This script aims to reduce operational overhead, ensure consistency across deployments, and lower the barrier for users to quickly get LimeDB running on Proxmox.&lt;/p&gt;

&lt;h3&gt;
  
  
  Design Choices Made
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Proxmox &lt;code&gt;pct&lt;/code&gt; Utility:&lt;/strong&gt; The script heavily relies on the &lt;code&gt;pct&lt;/code&gt; command-line interface provided by Proxmox for all container management operations, including creation, starting, and executing commands within the container.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Unprivileged LXC:&lt;/strong&gt; It creates an unprivileged container by default (&lt;code&gt;--unprivileged 1&lt;/code&gt;), which is a security best practice as it isolates the container processes more effectively from the host kernel.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Debian 12 Base:&lt;/strong&gt; A Debian 12 standard template (&lt;code&gt;debian-12-standard_12.2-1_amd64.tar.zst&lt;/code&gt;) is chosen as the default operating system for the container, offering a stable and widely-used base.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Resource Configuration:&lt;/strong&gt; Default parameters for CPU cores (&lt;code&gt;1&lt;/code&gt;), RAM (&lt;code&gt;512MB&lt;/code&gt;), swap (&lt;code&gt;512MB&lt;/code&gt;), and disk size (&lt;code&gt;2GB&lt;/code&gt;) are set, providing a lightweight yet functional setup suitable for initial deployments or development.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;DHCP Networking:&lt;/strong&gt; The container's network is configured to use DHCP on &lt;code&gt;vmbr0&lt;/code&gt;, simplifying network setup in most standard Proxmox environments.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Nesting Support:&lt;/strong&gt; The &lt;code&gt;--features nesting=1&lt;/code&gt; flag is included, which can be beneficial for running certain nested virtualization or containerization technologies within the LXC, though not strictly required for LimeDB itself.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Binary Installation:&lt;/strong&gt; LimeDB is installed by directly downloading a pre-compiled binary from its GitHub releases (&lt;code&gt;v0.0.2&lt;/code&gt;) into &lt;code&gt;/usr/local/bin&lt;/code&gt; inside the container. This avoids the need for a full build environment within the LXC.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Systemd Service Management:&lt;/strong&gt; A &lt;code&gt;systemd&lt;/code&gt; unit file (&lt;code&gt;limedb.service&lt;/code&gt;) is dynamically created and enabled within the container. This ensures LimeDB starts automatically on boot and is managed robustly by the system's init system.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Basic Error Handling and Feedback:&lt;/strong&gt; The script includes functions for informative messages, success indicators, and error reporting, with checks for root execution and successful container creation.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Trade-offs and Constraints
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Proxmox-Specific:&lt;/strong&gt; The script is tightly coupled to the Proxmox VE environment and cannot be used for deploying LimeDB on other virtualization platforms without significant modifications.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Default Parameters:&lt;/strong&gt; It uses hardcoded default values for container ID (&lt;code&gt;105&lt;/code&gt;), password, storage pool (&lt;code&gt;local-lvm&lt;/code&gt;), and OS template. Users need to ensure these defaults are appropriate for their specific Proxmox setup or modify the script variables directly.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Root Privileges:&lt;/strong&gt; The script itself must be run as root on the Proxmox host. Commands executed within the container (e.g., &lt;code&gt;apt-get&lt;/code&gt;, &lt;code&gt;wget&lt;/code&gt;, &lt;code&gt;systemctl&lt;/code&gt;) are also run as the root user.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Network Assumptions:&lt;/strong&gt; It assumes the presence of a network bridge named &lt;code&gt;vmbr0&lt;/code&gt; and a DHCP server on that network. Static IP configuration is not an option within the current script implementation.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;External Dependency:&lt;/strong&gt; The LimeDB binary is fetched directly from GitHub releases. This implies a dependency on GitHub's availability and the persistence of the specific release version.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Limited Customization:&lt;/strong&gt; While essential parameters are configured, more advanced LXC settings (e.g., CPU limits, IOPS limits, specific static IP addresses, custom bind mounts) are not exposed for easy modification.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Security Post-Setup:&lt;/strong&gt; The use of a default container password and root installation inside the container means that for production deployments, additional security hardening (e.g., changing passwords, creating dedicated unprivileged users for LimeDB) would be necessary.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Future Implications
&lt;/h3&gt;

&lt;p&gt;This script serves as a foundational automation tool for LimeDB on Proxmox. It significantly simplifies the initial deployment phase, making it easier for users to experiment with, test, and potentially scale LimeDB instances. Future enhancements could include making more parameters configurable via command-line arguments, supporting different OS templates, enabling static IP configuration, or integrating with configuration management systems for more advanced fleet management.&lt;/p&gt;

</description>
      <category>limedb</category>
      <category>proxmox</category>
      <category>lxc</category>
      <category>automation</category>
    </item>
    <item>
      <title>LimeDB: Architectural Shift to Go with Consistent Hashing</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Fri, 21 Nov 2025 00:00:00 +0000</pubDate>
      <link>https://dev.to/namanvashistha/limedb-architectural-shift-to-go-with-consistent-hashing-3207</link>
      <guid>https://dev.to/namanvashistha/limedb-architectural-shift-to-go-with-consistent-hashing-3207</guid>
      <description>&lt;p&gt;Github: &lt;a href="https://github.com/namanvashistha/limedb/commit/4dbdf30cc35b8884f47987ea15d8fa98d8360a4f" rel="noopener noreferrer"&gt;namanvashistha/limedb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This commit marks a pivotal architectural change for LimeDB, transitioning its core distributed key-value store implementation from a Java/Spring Boot foundation managed by Docker Compose to a new Go-based system. This complete rewrite focuses on performance, efficiency, and a streamlined deployment model.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Changed
&lt;/h2&gt;

&lt;p&gt;The primary change is the introduction of a complete Go implementation of LimeDB's distributed key-value store. This necessitated the removal of all previous Java-related Docker infrastructure, including &lt;code&gt;.dockerignore&lt;/code&gt;, &lt;code&gt;DOCKER.md&lt;/code&gt;, &lt;code&gt;docker-compose.yml&lt;/code&gt;, and &lt;code&gt;docker-compose.prod.yml&lt;/code&gt;. A &lt;code&gt;.gitignore&lt;/code&gt; update also reflects a new development environment preference.&lt;/p&gt;

&lt;p&gt;The new Go codebase introduces several key components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;cmd/server/main.go&lt;/strong&gt; : The application's entry point, responsible for loading configuration, initializing services, starting the HTTP server, and managing graceful shutdown.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;internal/config&lt;/strong&gt; : A package for parsing command-line arguments to configure node-specific parameters such as &lt;code&gt;NodeID&lt;/code&gt;, &lt;code&gt;ServerPort&lt;/code&gt;, a list of &lt;code&gt;Peers&lt;/code&gt;, and the number of &lt;code&gt;VirtualNodes&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;internal/server&lt;/strong&gt; : Implements the HTTP server using &lt;code&gt;github.com/valyala/fasthttp&lt;/code&gt;. It defines API endpoints for &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;SET&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt; operations, as well as cluster and ring state monitoring (&lt;code&gt;/api/v1/cluster/state&lt;/code&gt;, &lt;code&gt;/api/v1/cluster/ring&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;internal/node&lt;/strong&gt; : Contains the &lt;code&gt;NodeService&lt;/code&gt; which orchestrates key-value operations. It manages an in-memory &lt;code&gt;Store&lt;/code&gt; (based on &lt;code&gt;sync.Map&lt;/code&gt;) for local data and routes requests to the appropriate node using consistent hashing, forwarding them via an &lt;code&gt;fasthttp.Client&lt;/code&gt; if the key belongs to a remote peer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;internal/ring&lt;/strong&gt; : This package provides the &lt;code&gt;ConsistentHashRing&lt;/code&gt; implementation, which uses MD5 hashing to map keys to &lt;code&gt;int64&lt;/code&gt; values on the ring. It supports adding and removing physical nodes, each represented by a configurable number of virtual nodes, and efficiently determines the responsible node for a given key.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;go.mod and go.sum&lt;/strong&gt; : These files define the Go module &lt;code&gt;limedb-go&lt;/code&gt; and its dependencies, primarily &lt;code&gt;fasthttp&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;run_go_cluster.sh&lt;/strong&gt; : A shell script facilitating the local setup and execution of a multi-node Go LimeDB cluster, automatically generating the peer list.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;scripts/bulk_set.py&lt;/strong&gt; : The Python testing script was updated to support a higher number of nodes (up to 50) and increased concurrent key operations, reflecting the expected scalability improvements of the Go implementation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why the Change was Needed
&lt;/h2&gt;

&lt;p&gt;The transition from Java/Spring Boot to Go was driven by the pursuit of higher performance, reduced resource consumption, and improved concurrency characteristics. Go's design, with its lightweight goroutines and efficient memory management, offers significant advantages for building high-throughput distributed systems like LimeDB. The aim is to achieve lower latency and higher request per second (RPS) metrics compared to the previous Java-based setup, while also simplifying the deployment footprint by moving to a single-binary model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design Choices Made
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Go Language Adoption&lt;/strong&gt; : The primary decision was to rewrite the system in Go. This choice aligns with the project's goal of being a lightweight, fast, open-source distributed key-value store for high-performance systems. Go's built-in concurrency model and performance profile are well-suited for this.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;fasthttp for HTTP Communication&lt;/strong&gt; : &lt;code&gt;github.com/valyala/fasthttp&lt;/code&gt; was selected over Go's standard &lt;code&gt;net/http&lt;/code&gt; package for its optimized performance. In a key-value store where network I/O and request handling throughput are critical, &lt;code&gt;fasthttp&lt;/code&gt; provides a more performant foundation for inter-node communication and client APIs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consistent Hashing with Virtual Nodes&lt;/strong&gt; : The &lt;code&gt;ConsistentHashRing&lt;/code&gt; implementation is central to the distributed nature of LimeDB. By employing consistent hashing and distributing virtual nodes across physical nodes, the system achieves even data distribution, minimizes data movement during node additions/removals, and enhances fault tolerance. MD5 hashing to &lt;code&gt;int64&lt;/code&gt; provides a consistent mapping to the hash space.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;In-Memory sync.Map Storage&lt;/strong&gt; : For the initial phase of this rewrite, an in-memory &lt;code&gt;sync.Map&lt;/code&gt; was chosen for local key-value storage. This provides a simple, thread-safe, and highly performant local store, allowing the development focus to remain on the distributed routing and consistent hashing logic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Command-Line Configuration&lt;/strong&gt; : Node configuration is managed via command-line flags. This provides a transparent and explicit way to bootstrap and configure individual nodes, particularly useful in development and for static cluster deployments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Direct Request Forwarding&lt;/strong&gt; : When a request targets a key not owned by the current node, the &lt;code&gt;NodeService&lt;/code&gt; directly forwards the HTTP request to the responsible peer. This keeps the routing logic within the application layer, leveraging the consistent hash ring.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Trade-offs and Constraints
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Persistence (Current Constraint)&lt;/strong&gt;: The current &lt;code&gt;internal/node/store&lt;/code&gt; is an in-memory implementation, meaning data is not durable across restarts. This is a deliberate simplification for the initial Go rewrite phase, prioritizing the core distributed logic. For production readiness, a persistent storage layer will be required (the previous Java version used PostgreSQL, highlighting this need).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Static Peer Configuration&lt;/strong&gt; : The &lt;code&gt;node.peers&lt;/code&gt; list is currently static and defined at startup. This approach lacks dynamic cluster membership capabilities, meaning manual intervention is required to update peer lists when nodes join or leave the cluster. This could be a scalability bottleneck in highly elastic environments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;fasthttp Ecosystem&lt;/strong&gt; : While fast, &lt;code&gt;fasthttp&lt;/code&gt; has a smaller ecosystem of middleware and integrations compared to the standard &lt;code&gt;net/http&lt;/code&gt; package. This is an accepted trade-off for the performance gains it provides in a specialized service.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Basic API Routing&lt;/strong&gt; : The server's &lt;code&gt;router&lt;/code&gt; uses a basic &lt;code&gt;switch&lt;/code&gt; statement for URL matching. While functional, it could evolve into a more robust routing framework as the API surface grows.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Future Implications
&lt;/h2&gt;

&lt;p&gt;This Go-based rewrite provides a strong, high-performance foundation for LimeDB. Future development efforts will likely focus on enhancing its capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Durable Storage&lt;/strong&gt; : Implementing a persistent storage layer (e.g., integrating with a local embedded key-value store like BadgerDB or RocksDB, or a custom log-structured approach) to ensure data durability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Replication and Consistency&lt;/strong&gt; : Introducing robust data replication strategies (e.g., N-way replication, quorum reads/writes) to ensure high availability and strong consistency guarantees.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dynamic Cluster Membership and Discovery&lt;/strong&gt; : Developing mechanisms for nodes to dynamically discover each other, join/leave the cluster, and handle failures gracefully (e.g., using a gossip protocol or integrating with a service discovery system like Consul or etcd).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Load Balancing and Client-Side Hashing&lt;/strong&gt; : Exploring options for smarter client-side load balancing or direct client integration with the consistent hashing ring to minimize request forwarding overhead.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Advanced Observability&lt;/strong&gt; : Expanding metrics, logging, and tracing capabilities for better monitoring and debugging in production environments.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>database</category>
      <category>distributedsystems</category>
      <category>go</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Why I'm Building My Own Distributed Database</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Sat, 11 Oct 2025 21:09:44 +0000</pubDate>
      <link>https://dev.to/namanvashistha/why-im-building-my-own-distributed-database-3lj</link>
      <guid>https://dev.to/namanvashistha/why-im-building-my-own-distributed-database-3lj</guid>
      <description>&lt;p&gt;As a backend developer, I've worked with Redis, PostgreSQL, MongoDB, and countless other databases. But I always felt like there was something missing – a deeper understanding of how these systems actually work under the hood. So I decided to embark on a journey to build my own distributed key-value database from scratch.&lt;/p&gt;

&lt;p&gt;Meet &lt;strong&gt;LimeDB&lt;/strong&gt; – a distributed key-value store I'm currently building with Java 21 and Spring Boot. My goal is to create a truly custom database system that starts with PostgreSQL as a foundation but evolves into something much more ambitious, all wrapped in a horizontally scalable coordinator-shard architecture.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/namanvashistha/limedb" rel="noopener noreferrer"&gt;namanvashistha/limedb&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 Why Build Another Database?
&lt;/h2&gt;

&lt;p&gt;You might be thinking: "Why reinvent the wheel? Redis and PostgreSQL already exist!" And you're absolutely right. But here's the thing – as backend developers, we often treat databases as black boxes. We know &lt;em&gt;how&lt;/em&gt; to use them, but not &lt;em&gt;how&lt;/em&gt; they work.&lt;/p&gt;

&lt;p&gt;Building LimeDB is already teaching me more about distributed systems, consistency, partitioning, and database internals than years of just using existing solutions. It's like the difference between driving a car and understanding how the engine works.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 The Learning Goals
&lt;/h2&gt;

&lt;p&gt;When I started this project, I had several learning objectives:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Understand Distributed System Patterns&lt;/strong&gt; - How do you route requests across multiple nodes?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grasp Database Internals&lt;/strong&gt; - What happens when you store and retrieve data?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learn About Horizontal Scaling&lt;/strong&gt; - How do systems like Redis Cluster actually work?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Master Modern Java&lt;/strong&gt; - Put Java 21 features and Spring Boot to real use&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build Something Production-Adjacent&lt;/strong&gt; - Not just a toy, but something that could theoretically scale&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🏗️ Architecture Decisions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Coordinator-Shard Pattern
&lt;/h3&gt;

&lt;p&gt;Instead of a peer-to-peer system (like Cassandra) or a single-node system (like Redis), I chose a coordinator-shard architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client → Coordinator → Shard 1, 2, 3...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this pattern?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simplicity&lt;/strong&gt;: Clients only need to know about one endpoint&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routing Logic&lt;/strong&gt;: Centralized decision-making about where data lives&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operational Ease&lt;/strong&gt;: Easy to monitor and debug&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Familiar&lt;/strong&gt;: Similar to how many real systems work (think MongoDB's router)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Hash-Based Routing (For Now)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Simple but effective&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;shardIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;abs&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hashCode&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;numberOfShards&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is deliberately simple. I know consistent hashing is "better" for rebalancing, but I wanted to start with something I could fully understand and implement correctly. You can see this decision in the &lt;code&gt;ShardRegistryService&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getShardByKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;abs&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hashCode&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;shards&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;shards&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perfect? No. Educational? Absolutely.&lt;/p&gt;

&lt;h3&gt;
  
  
  PostgreSQL as a Starting Point
&lt;/h3&gt;

&lt;p&gt;Each shard currently uses its own PostgreSQL database (&lt;code&gt;limedb_shard_1&lt;/code&gt;, &lt;code&gt;limedb_shard_2&lt;/code&gt;, etc.). But here's the key - PostgreSQL is just my &lt;strong&gt;Phase 1&lt;/strong&gt; storage engine, not the final destination.&lt;/p&gt;

&lt;p&gt;Why start with PostgreSQL?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Quick Validation&lt;/strong&gt;: Get the distributed architecture working first&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ACID Guarantees&lt;/strong&gt;: Data survives restarts while I focus on routing logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Familiar Tooling&lt;/strong&gt;: Easy to inspect and debug during development&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stepping Stone&lt;/strong&gt;: Proven foundation before building custom storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The plan is to eventually replace PostgreSQL with custom storage engines optimized for key-value workloads. Think LSM trees, custom file formats, and memory-mapped storage - but PostgreSQL lets me focus on the distributed systems challenges first.&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 What I'm Learning Building This
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Distributed Systems Are Hard&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Even with this simple architecture, I'm already running into fascinating problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What happens when a shard goes down?&lt;/li&gt;
&lt;li&gt;How do you handle network timeouts?&lt;/li&gt;
&lt;li&gt;What about data consistency across shards?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These aren't academic questions anymore – they're real problems I need to solve as I build this system.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;The Power of Good Abstractions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The Spring Boot framework is letting me focus on the distributed systems logic rather than HTTP parsing and dependency injection. My controllers are staying clean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/get/{key}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;routingService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;notFound&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. &lt;strong&gt;Testing Distributed Systems is Different&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You can't just unit test individual methods. You need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start multiple services&lt;/li&gt;
&lt;li&gt;Test network failures&lt;/li&gt;
&lt;li&gt;Verify data consistency&lt;/li&gt;
&lt;li&gt;Check routing logic
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;set_values&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;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1_000&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;key&lt;/span&gt;&lt;span class="sh"&gt;"&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;key_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;value&lt;/span&gt;&lt;span class="sh"&gt;"&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;value_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;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;http://localhost:8080/api/v1/set&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. &lt;strong&gt;Configuration Management is Crucial&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;With multiple nodes, configuration becomes complex. Each shard needs to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which database to connect to&lt;/li&gt;
&lt;li&gt;What port to run on&lt;/li&gt;
&lt;li&gt;Its shard ID
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./gradlew bootRun &lt;span class="nt"&gt;--args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'--node.type=shard --server.port=7001 --shard.id=1'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🚀 Current Progress
&lt;/h2&gt;

&lt;p&gt;LimeDB currently supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ GET/SET/DELETE operations (Redis-like API)&lt;/li&gt;
&lt;li&gt;✅ Hash-based routing across 3 shards&lt;/li&gt;
&lt;li&gt;✅ PostgreSQL persistence per shard&lt;/li&gt;
&lt;li&gt;✅ REST API with proper error handling&lt;/li&gt;
&lt;li&gt;✅ Health monitoring endpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Performance? It's not going to beat Redis. But it's already handling operations smoothly and teaching me &lt;em&gt;why&lt;/em&gt; Redis is so fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 What's Next?
&lt;/h2&gt;

&lt;p&gt;The roadmap is ambitious and includes features I'm excited to tackle:&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2: Better Distribution
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Consistent Hashing&lt;/strong&gt;: Replace modulo with a proper hash ring&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health Checks&lt;/strong&gt;: Automatic failover when shards go down&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Replication&lt;/strong&gt;: Primary-replica setup for high availability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metrics&lt;/strong&gt;: Monitoring and observability&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Phase 3: Custom Storage Engine
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LSM Trees&lt;/strong&gt;: Replace PostgreSQL with custom key-value storage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory-Mapped Files&lt;/strong&gt;: Direct file system control&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom Serialization&lt;/strong&gt;: Optimized data formats&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WAL Implementation&lt;/strong&gt;: Write-ahead logging from scratch&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Phase 4: Advanced Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Custom Binary Protocol&lt;/strong&gt;: Move beyond HTTP/REST&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compression&lt;/strong&gt;: Custom compression algorithms&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache Layers&lt;/strong&gt;: Multi-level caching strategies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transaction Support&lt;/strong&gt;: ACID across multiple shards&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each phase represents deeper database internals knowledge - PostgreSQL is just the beginning!&lt;/p&gt;

&lt;h2&gt;
  
  
  💭 Why You Should Build One Too
&lt;/h2&gt;

&lt;p&gt;Building your own database isn't about competing with PostgreSQL or Redis. It's about:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Deep Learning&lt;/strong&gt;: Understanding systems from the ground up&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interview Prep&lt;/strong&gt;: Nothing impresses like saying "I built a distributed database"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Problem-Solving Skills&lt;/strong&gt;: Real distributed systems problems&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technology Mastery&lt;/strong&gt;: Push your programming language skills&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portfolio Project&lt;/strong&gt;: Something unique that stands out&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🛠️ Getting Started
&lt;/h2&gt;

&lt;p&gt;If this inspired you to build your own database, here's my advice:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start Simple&lt;/strong&gt;: Don't try to build Redis on day one&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pick Your Language&lt;/strong&gt;: Use something you're comfortable with&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose One Feature&lt;/strong&gt;: GET/SET is enough to start&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add Gradually&lt;/strong&gt;: Persistence, then distribution, then optimizations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document Everything&lt;/strong&gt;: Future you will thank you&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🔗 Follow the Journey
&lt;/h2&gt;

&lt;p&gt;Want to see the code as I build it? It's all open source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/namanvashistha/limedb" rel="noopener noreferrer"&gt;namanvashistha/limedb&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tech Stack&lt;/strong&gt;: Java 21, Spring Boot, PostgreSQL&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Current Status&lt;/strong&gt;: Basic coordinator-shard architecture working&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The README has setup instructions, and I'm trying to make the code as readable as possible for learning purposes. Feel free to star the repo and follow along as I tackle more distributed systems challenges!&lt;/p&gt;

&lt;h2&gt;
  
  
  🎉 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Building LimeDB is turning out to be one of the most educational projects I've undertaken as a backend developer. It's not going to be the fastest database, or the most feature-complete, but it's &lt;em&gt;mine&lt;/em&gt;. I understand every line of code, every architectural decision, and every trade-off I'm making along the way.&lt;/p&gt;

&lt;p&gt;In a world of microservices and cloud abstractions, there's something deeply satisfying about building a system from first principles. I'm already looking at Redis, PostgreSQL, and MongoDB differently after just starting this journey.&lt;/p&gt;

&lt;p&gt;So grab your favourite programming language, pick a simple data structure, and start building. The distributed systems knowledge you'll gain is worth its weight in gold.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What do you think? Have you ever built your own database or distributed system? What did you learn? Drop a comment below!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>database</category>
      <category>distributedsystems</category>
      <category>java</category>
      <category>springboot</category>
    </item>
  </channel>
</rss>
