<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Deep Dive on Lorbic</title><link>http://localhost:1313/series/deep-dive/</link><description>Recent content in Deep Dive on Lorbic</description><generator>Hugo</generator><language>en</language><lastBuildDate>Fri, 31 Jul 2026 23:00:00 +0530</lastBuildDate><atom:link href="http://localhost:1313/series/deep-dive/index.xml" rel="self" type="application/rss+xml"/><item><title>Couchbase Index Best Practices and Query Performance Tuning</title><link>http://localhost:1313/couchbase-index-best-practices-performance-tuning/</link><pubDate>Fri, 31 Jul 2026 23:00:00 +0530</pubDate><guid>http://localhost:1313/couchbase-index-best-practices-performance-tuning/</guid><description>&lt;p>Most Couchbase performance tickets I have seen end the same way: someone adds more nodes, the dashboard looks a little better for a week, and the same query shows up in the slow log a month later. The node count was never the problem. The index was.&lt;/p>
&lt;p>This is a working reference, not an essay. I already wrote &lt;a href="http://localhost:1313/what-couchbase-taught-me-about-system-thinking/">the reflective version&lt;/a> of what indexing in Couchbase teaches you about systems in general. This post skips the reflection and gets straight to the decisions: which index type to reach for, how to order composite keys, how to tell if a query is actually using what you built, and which four or five mistakes account for most of the slow queries you will ever debug. Couchbase&amp;rsquo;s own documentation is the primary source for the recommendations below. Every example runs against &lt;code>travel-sample&lt;/code>, the sample bucket Couchbase ships with every install, so you can paste these into your own cluster and see the plan yourself.&lt;/p></description></item><item><title>Why Your Goroutines Need a Speed Limit: Bounded Concurrency in Go</title><link>http://localhost:1313/bounded-concurrency-in-go/</link><pubDate>Fri, 10 Apr 2026 10:00:00 +0530</pubDate><guid>http://localhost:1313/bounded-concurrency-in-go/</guid><description>&lt;p>&lt;strong>TL;DR:&lt;/strong> Spawning &lt;code>go func()&lt;/code> without a limiter is a recipe for system collapse. This guide details how to use &lt;strong>Semaphores&lt;/strong> and &lt;strong>Worker Pools&lt;/strong> to prioritize predictable stability over absolute speed, protecting downstream dependencies from the thundering herd.&lt;/p>
&lt;hr>
&lt;p>It&amp;rsquo;s a rite of passage for every Go developer. You receive a list of 10,000 URLs to fetch or 50,000 rows to process. You wrap the workload in an unbounded &lt;code>go func()&lt;/code> loop, achieving maximum throughput in milliseconds.&lt;/p></description></item><item><title>Kubernetes on WSL2 and the macOS tunnel</title><link>http://localhost:1313/kubernetes-on-wsl2-macos-access/</link><pubDate>Wed, 01 Apr 2026 22:00:00 +0530</pubDate><guid>http://localhost:1313/kubernetes-on-wsl2-macos-access/</guid><description>&lt;p>&lt;strong>TL;DR:&lt;/strong> I run &lt;strong>k3s&lt;/strong> on a Windows gaming PC via &lt;strong>WSL2&lt;/strong> to master Kubernetes networking without cloud costs. This guide details a secure access model using &lt;strong>SSH&lt;/strong> and &lt;strong>kubectl port-forward&lt;/strong> to bypass NAT boundaries and maintain technical sovereignty.&lt;/p>
&lt;hr>
&lt;p>This guide omits Kubernetes feature tutorials. Instead, it details how to architect an environment where Kubernetes can exist without auxiliary hardware, idle cloud bills, or hidden networking realities.&lt;/p>
&lt;p>I wanted to learn Kubernetes properly, which meant understanding how &lt;strong>scheduling&lt;/strong>, &lt;strong>access paths&lt;/strong>, and &lt;strong>network boundaries&lt;/strong> behave under real constraints. The problem was simple: I lacked a reasonable execution environment.&lt;/p></description></item><item><title>ClickHouse data masking with regex</title><link>http://localhost:1313/clickhouse-regex-data-masking/</link><pubDate>Tue, 31 Mar 2026 22:30:00 +0530</pubDate><guid>http://localhost:1313/clickhouse-regex-data-masking/</guid><description>&lt;p>If you&amp;rsquo;re running a production observability stack, you&amp;rsquo;ve already leaked PII. An engineer forgot to redact an email in a log line, or a JWT token ended up in a stack trace.&lt;/p>
&lt;p>In most databases, the only fix is to &lt;code>DELETE&lt;/code> the data—killing your metrics along with the sensitive info. But ClickHouse has a more elegant approach: &lt;strong>Data Masking Policies&lt;/strong>.&lt;/p>
&lt;p>By defining a policy at the role level, you can use regex to swap sensitive patterns with &lt;code>[REDACTED]&lt;/code> in real-time, before the query results even leave the server.&lt;/p></description></item><item><title>Understanding CPU Caches in Go</title><link>http://localhost:1313/cpu-caches-in-go/</link><pubDate>Tue, 31 Mar 2026 22:15:00 +0530</pubDate><guid>http://localhost:1313/cpu-caches-in-go/</guid><description>&lt;p>When you&amp;rsquo;re building Go services that handle millions of operations per second, the hardware beneath your abstractions starts to matter. Specifically, the CPU cache hierarchy, and whether your data fits in it.&lt;/p>
&lt;hr>
&lt;h4 id="the-hardware-context-its-not-just-ram">The Hardware Context: It&amp;rsquo;s Not Just &amp;ldquo;RAM&amp;rdquo;&lt;a class="anchorjs-link" href="#the-hardware-context-its-not-just-ram" aria-label="Link to section: The Hardware Context: It&amp;rsquo;s Not Just &amp;ldquo;RAM&amp;rdquo;">&lt;/a>&lt;/h4>&lt;p>Your server has 32GB or 64GB of RAM, but the CPU avoids touching it whenever possible. Instead, it works through a chain of caches:&lt;/p></description></item><item><title>ClickHouse vs. Postgres: When to Move Your Logs Out of a Relational DB</title><link>http://localhost:1313/clickhouse-vs-postgres-log-storage/</link><pubDate>Mon, 30 Mar 2026 22:45:00 +0530</pubDate><guid>http://localhost:1313/clickhouse-vs-postgres-log-storage/</guid><description>&lt;p>Postgres is the most reliable tool in my stack. It handles users, configurations, and complex relations without breaking a sweat. But databases, like any physical system, have a &amp;ldquo;design limit&amp;rdquo;. For Postgres, that limit usually appears when you try to use it as a dumping ground for high-velocity logs and metrics.&lt;/p>
&lt;p>When your &lt;code>ANALYZE&lt;/code> commands start taking minutes and your indexes consume more RAM than your data, you aren&amp;rsquo;t facing a Postgres bug; you&amp;rsquo;re facing an architectural mismatch.&lt;/p></description></item><item><title>WSL2 Is Slow? Fix /mnt/c/ File System Performance &amp; Go Latency</title><link>http://localhost:1313/wsl2-performance-tax-go-windows/</link><pubDate>Sun, 29 Mar 2026 22:30:00 +0530</pubDate><guid>http://localhost:1313/wsl2-performance-tax-go-windows/</guid><description>&lt;p>WSL2 (Windows Subsystem for Linux) has been a godsend for developers who love Linux tools but need/have a Windows environment. But for Go developers, WSL2 isn&amp;rsquo;t just a &amp;ldquo;transparent layer&amp;rdquo;. If configured incorrectly, it becomes the bottleneck that can slow down builds by 3x and introduce mysterious latency in networked services.&lt;/p>
&lt;p>This isn&amp;rsquo;t a failure of WSL2; it&amp;rsquo;s a failure of understanding the &lt;strong>9p boundary&lt;/strong>.&lt;/p>
&lt;div class="details-block reveal-item">
 &lt;details>
 &lt;summary>
 &lt;div class="summary-inner">
 &lt;span class="details-label">Glossary //&lt;/span>
 &lt;span class="details-title">What is the 9P Boundary?&lt;/span>
 &lt;svg class="svg-icon icon-plus" aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">&lt;path d="M256 80c0-17.7-14.3-32-32-32s-32 14.3-32 32V224H48c-17.7 0-32 14.3-32 32s14.3 32 32 32H192V432c0 17.7 14.3 32 32 32s32-14.3 32-32V288H400c17.7 0 32-14.3 32-32s-14.3-32-32-32H256V80z"/>&lt;/svg>
 &lt;svg class="svg-icon icon-minus" aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">&lt;path d="M432 256c0 17.7-14.3 32-32 32H48c-17.7 0-32-14.3-32-32s14.3-32 32-32H400c17.7 0 32 14.3 32 32z"/>&lt;/svg>
 &lt;/div>
 &lt;/summary>
 &lt;div class="details-content">
 &lt;p>WSL2 is a Virtual Machine. To let that VM see your Windows files, Microsoft uses the &lt;strong>9P protocol&lt;/strong> (Plan 9).&lt;/p></description></item><item><title>Go Struct Field Alignment: How Memory Padding Wastes Your RAM</title><link>http://localhost:1313/go-struct-field-alignment/</link><pubDate>Sat, 24 Jan 2026 10:00:00 +0530</pubDate><guid>http://localhost:1313/go-struct-field-alignment/</guid><description>&lt;p>You write a struct to represent a database entity. Maybe 10 fields, maybe 20. What could possibly go wrong?&lt;/p>
&lt;p>Nothing, according to your tests. But somewhere in production, your heap is 30% larger than it should be, your Garbage Collector is working overtime, and your L1 cache is not used properly. The reason? &lt;strong>Invisible padding bytes&lt;/strong> silently inflating every instance of your struct.&lt;/p>
&lt;p>This is the story of struct field alignment: a memory optimization that costs nothing to implement but can significantly improve performance.&lt;/p></description></item><item><title>Memory Mechanics In Go - Stack vs Heap</title><link>http://localhost:1313/memory-mechanics-stack-vs-heap-in-go/</link><pubDate>Mon, 12 Jan 2026 00:10:00 +0530</pubDate><guid>http://localhost:1313/memory-mechanics-stack-vs-heap-in-go/</guid><description>&lt;p>We often talk about &amp;ldquo;fast&amp;rdquo; code in terms of Big O notation or algorithmic complexity. But in systems programming languages like Go, &amp;ldquo;fast&amp;rdquo; is often a function of &lt;em>where&lt;/em> your data lives in memory.&lt;/p>
&lt;p>When optimizing for high throughput, efficient loops and database indexes are only part of the story. Eventually, you have to talk about the Stack and the Heap.&lt;/p>
&lt;p>Understanding the difference isn&amp;rsquo;t just trivia. It is the difference between a service that hums along at 100k OPS with flat latency, and one that chokes on Garbage Collection (GC) pauses every few seconds.&lt;/p></description></item><item><title>OLTP vs OLAP - Why You Need Two Databases</title><link>http://localhost:1313/oltp-vs-olap-why-you-need-two-databases/</link><pubDate>Sun, 11 Jan 2026 21:00:00 +0530</pubDate><guid>http://localhost:1313/oltp-vs-olap-why-you-need-two-databases/</guid><description>&lt;p>At a recent ClickHouse conference in New Delhi, I attended this Saturday. There were many interesting sessions, but one that stood out was a talk on multi-tenant analytics at scale. I was reminded of a fundamental truth in backend engineering: &amp;ldquo;The database that runs your app cannot be the database that analyzes your app&amp;rdquo;.&lt;/p>
&lt;p>Early in a startup&amp;rsquo;s life, we shove everything into one database. User profiles, session data, logs, and analytics events all live in the same Postgres, Mongo, or Couchbase instance. It works, until it throttles.&lt;/p></description></item><item><title>Go Garbage Collector Mechanics: Pacer, GOGC, and Allocation Latency</title><link>http://localhost:1313/dont-take-out-the-garbage-go-gc-deep-dive/</link><pubDate>Wed, 07 Jan 2026 00:21:12 +0530</pubDate><guid>http://localhost:1313/dont-take-out-the-garbage-go-gc-deep-dive/</guid><description>&lt;p>In the world of high-throughput backend services, we often obsess over the usual suspects of performance: database indexing, network latency, and algorithmic complexity. But recently, while debugging our core gateway service (&lt;code>backend-gw&lt;/code>), I encountered a bottleneck that defied standard logic.&lt;/p>
&lt;p>The service was &lt;strong>CPU-bound&lt;/strong>, yet active heap usage was surprisingly low (~200MB). P99 latency was spiking at random intervals, but database queries were returning in milliseconds.&lt;/p>
&lt;p>The culprit was not the business logic. It was &lt;strong>memory management&lt;/strong>. I was effectively running a Denial-of-Service attack on my own runtime.&lt;/p></description></item><item><title>What Couchbase Taught Me About System Thinking</title><link>http://localhost:1313/what-couchbase-taught-me-about-system-thinking/</link><pubDate>Tue, 18 Nov 2025 02:20:06 +0530</pubDate><guid>http://localhost:1313/what-couchbase-taught-me-about-system-thinking/</guid><description>&lt;h2 id="couchbase-internals-indexes-queries-consistency-and-performance">Couchbase Internals: Indexes, Queries, Consistency, and Performance&lt;a class="anchorjs-link" href="#couchbase-internals-indexes-queries-consistency-and-performance" aria-label="Link to section: Couchbase Internals: Indexes, Queries, Consistency, and Performance">&lt;/a>&lt;/h2>&lt;h3 id="introduction">Introduction&lt;a class="anchorjs-link" href="#introduction" aria-label="Link to section: Introduction">&lt;/a>&lt;/h3>&lt;p>Over the last few years I&amp;rsquo;ve lived deep inside backend systems, and for the past year and a half Couchbase has been my daily companion. Working with Go services that depend on Couchbase taught me that the real lessons aren&amp;rsquo;t in the marketing slides or quick‑start guides. They&amp;rsquo;re in the internals: how indexes are built, how queries are planned, how consistency flags change the story, and how durability levels quietly decide whether your system survives a failure or not.&lt;/p></description></item><item><title>Understanding Private-Public Key Encryption</title><link>http://localhost:1313/private-public-key-encryption/</link><pubDate>Thu, 06 Nov 2025 22:01:23 +0530</pubDate><guid>http://localhost:1313/private-public-key-encryption/</guid><description>&lt;p>In today&amp;rsquo;s digital world, where secure communication, authentication, and data integrity are non-negotiable, &lt;strong>private-public key encryption&lt;/strong> (also called &lt;em>asymmetric cryptography&lt;/em>) plays a foundational role. From HTTPS in your browser to SSH logins, cryptocurrency wallets, and email encryption, this elegant cryptographic system enables trust without prior shared secrets.&lt;/p>
&lt;p>In this blog, we&amp;rsquo;ll dive into:&lt;/p>
&lt;ul>
&lt;li>The core concepts behind asymmetric encryption&lt;/li>
&lt;li>How it differs from symmetric encryption&lt;/li>
&lt;li>The mathematics (intuitively explained) behind popular algorithms like RSA and ECC&lt;/li>
&lt;li>Real-world examples and code snippets&lt;/li>
&lt;li>Common use cases and pitfalls&lt;/li>
&lt;/ul>
&lt;p>Whether you&amp;rsquo;re a curious beginner or a seasoned developer brushing up on fundamentals, you&amp;rsquo;ll find something valuable here.&lt;/p></description></item><item><title>How to Resolve Huge Git Merge Conflicts Without Losing Your Mind</title><link>http://localhost:1313/resolving-huge-merge-conflicts/</link><pubDate>Thu, 17 Jul 2025 20:56:00 +0000</pubDate><guid>http://localhost:1313/resolving-huge-merge-conflicts/</guid><description>&lt;p>&lt;strong>How to Resolve Huge Git Merge Conflicts Without Losing Your Mind&lt;/strong>&lt;/p>
&lt;p>If you&amp;rsquo;ve ever been knee-deep in a long-lived branch merge and thought, &lt;em>&amp;ldquo;this can&amp;rsquo;t be what version control was meant for&amp;rdquo;&lt;/em>, you&amp;rsquo;re not alone. Git gives us powerful tools, but resolving large merge conflicts, especially during major migrations or rewrites can feel like surgery without anesthesia.&lt;/p>
&lt;p>In this post, we&amp;rsquo;ll walk through how to approach and resolve massive merge conflicts systematically. Not with hand-wavy advice, but with actual steps, real mental models, and clear visual understanding.&lt;/p></description></item><item><title>Understanding T and *T method receivers in Go</title><link>http://localhost:1313/method-receivers-in-go/</link><pubDate>Sun, 23 Feb 2025 04:33:00 +0000</pubDate><guid>http://localhost:1313/method-receivers-in-go/</guid><description>&lt;p>In Go, method receivers determine whether a method acts on a copy of a value or a reference to it. This choice isn&amp;rsquo;t just about performance; it affects correctness and behavior, especially when dealing with synchronization primitives (mutex, wait group, etc), slices, and embedded types.&lt;/p>
&lt;p>In this post I explore when to use T (a value receiver) vs. *T (a pointer receiver) and why, in most cases, pointer receivers should be the default and preferred.&lt;/p></description></item></channel></rss>