<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>System-Design on Lorbic</title><link>http://localhost:1313/tags/system-design/</link><description>Recent content in System-Design on Lorbic</description><generator>Hugo</generator><language>en</language><lastBuildDate>Sun, 09 Aug 2026 14:00:00 +0530</lastBuildDate><atom:link href="http://localhost:1313/tags/system-design/index.xml" rel="self" type="application/rss+xml"/><item><title>Designing a Distributed Job Scheduler in Go: Partitioning, Locking, and Backpressure</title><link>http://localhost:1313/designing-a-distributed-job-scheduler/</link><pubDate>Sun, 09 Aug 2026 14:00:00 +0530</pubDate><guid>http://localhost:1313/designing-a-distributed-job-scheduler/</guid><description>&lt;p>Linux &lt;code>crontab&lt;/code> is one of the most elegant pieces of software ever written for single-host automation. It is simple, clear, and has kept Unix systems running reliably since 1975.&lt;/p>
&lt;p>The problem starts when we take a single-host tool and deploy it across a multi-node cloud setup.&lt;/p>
&lt;p>In &lt;a href="http://localhost:1313/how-multi-tenant-saas-works/">Relay&lt;/a>, a multi-tenant AI API gateway system design, background jobs power core operations: every top of the hour, a job rolls up raw API usage tokens into tenant billing metrics; every 15 minutes, another job scans for expired API keys and purges them from cache; every 30 seconds, a health checker pings upstream LLM provider endpoints.&lt;/p></description></item><item><title>Designing a Usage-Based Billing Pipeline for SaaS</title><link>http://localhost:1313/designing-a-usage-based-billing-pipeline-for-saas/</link><pubDate>Sat, 01 Aug 2026 17:26:52 +0530</pubDate><guid>http://localhost:1313/designing-a-usage-based-billing-pipeline-for-saas/</guid><description>&lt;p>In &lt;a href="http://localhost:1313/posts/2026-07-01-how-multi-tenant-saas-works/" data-preview-title="How Multi-Tenant SaaS Actually Works" data-preview-desc="A complete system design of Relay, a multi-tenant AI API gateway. Covers multi-tenant database architecture (silo vs pool vs bridge), API key authentication, provider routing with failover, dual-layer rate limiting, token-based billing, response caching, row-level security, tenant provisioning, and observability. Full Postgres schemas, mermaid diagrams, and Go snippets included." data-preview-time="37 min read">How Multi-Tenant SaaS Actually Works&lt;/a>, I left one major promise unfulfilled at the end: &lt;em>&amp;ldquo;Billing is an entire system design on its own. The billing pipeline gets its own post.&amp;rdquo;&lt;/em>&lt;/p></description></item><item><title>API Design for Backend Systems</title><link>http://localhost:1313/api-design-for-backend-systems/</link><pubDate>Sun, 26 Jul 2026 19:00:00 +0530</pubDate><guid>http://localhost:1313/api-design-for-backend-systems/</guid><description>&lt;p>A few weeks ago I designed &lt;a href="http://localhost:1313/how-multi-tenant-saas-works/">Relay&lt;/a>, a multi-tenant AI API gateway, as a system design exercise. That post covered the database, the auth, the billing. It did not cover the thing every one of those systems is sitting behind: the API itself.&lt;/p>
&lt;p>Here is the question that post left open. When someone builds &lt;code>GET /v1/requests&lt;/code> to list a tenant&amp;rsquo;s API call history, what should that endpoint actually look like? Offset or cursor pagination? What does the response envelope contain? What happens when Relay needs to add a filter that does not fit in a query string? What does a webhook payload look like when Relay tells a tenant &amp;ldquo;your batch job finished&amp;rdquo;? None of that is specific to AI gateways. It is the same decisions every backend API makes, made badly often enough that &amp;ldquo;REST API&amp;rdquo; has become a phrase that means &amp;ldquo;JSON over HTTP, structure unspecified.&amp;rdquo;&lt;/p></description></item><item><title>Designing a Distributed Rate Limiter with Redis</title><link>http://localhost:1313/designing-a-rate-limiter/</link><pubDate>Tue, 07 Jul 2026 17:00:00 +0530</pubDate><guid>http://localhost:1313/designing-a-rate-limiter/</guid><description>&lt;p>There is a class of bugs that only happen at midnight.&lt;/p>
&lt;p>Your API has a rate limit: 1000 requests per minute. A client hits 999 at 11:59:59 PM, then fires another 999 at 12:00:00 AM. Two windows, two clean counters, all 1998 requests allowed. Your database gets a spike it was never designed to handle, and you spend the next hour wondering how your rate limiter let this through.&lt;/p>
&lt;p>It did let it through. You just did not know it.&lt;/p></description></item><item><title>How Multi-Tenant SaaS Actually Works</title><link>http://localhost:1313/how-multi-tenant-saas-works/</link><pubDate>Wed, 01 Jul 2026 00:00:00 +0530</pubDate><guid>http://localhost:1313/how-multi-tenant-saas-works/</guid><description>&lt;p>For the past month I have been reading about multi-tenant SaaS architecture. Not as an academic exercise. I kept running into the same questions on every project I looked at: where exactly does tenant data go, how do you stop one customer&amp;rsquo;s bug from becoming every customer&amp;rsquo;s problem, how does billing actually work at the database level. The blog posts I found were either too abstract or skipped the hard parts entirely.&lt;/p></description></item><item><title>10 years of lorbic.com architecture</title><link>http://localhost:1313/10-years-of-lorbic.com-architecture/</link><pubDate>Thu, 02 Apr 2026 12:00:00 +0530</pubDate><guid>http://localhost:1313/10-years-of-lorbic.com-architecture/</guid><description>&lt;p>&lt;picture class="optimized-image-container">&lt;source srcset="http://localhost:1313/10-years-of-lorbic.com-architecture/evolution_hu_c3df73cc291f2d3a.webp 480w, http://localhost:1313/10-years-of-lorbic.com-architecture/evolution_hu_d6eb9db6213c4dc9.webp 800w, http://localhost:1313/10-years-of-lorbic.com-architecture/evolution_hu_156b083258cf7313.webp 1200w, http://localhost:1313/10-years-of-lorbic.com-architecture/evolution_hu_abf66fd5579991cd.webp 3068w" sizes="(max-width: 800px) 100vw, 800px" type="image/webp">&lt;img src="http://localhost:1313/10-years-of-lorbic.com-architecture/evolution_hu_abf66fd5579991cd.webp" width="3068" height="800" alt="Lorbic Evolution: 2017 vs 2026" loading="eager" decoding="async" fetchpriority="high" class="img-fluid" />
 &lt;/picture>&lt;/p>
&lt;p>This post tracks four architectural rewrites of my personal site over ten years: moving from managed platforms (Blogger) to dynamic backends (Django), static site generators (Jekyll/Hugo), and finally to a custom, zero-dependency architecture built for absolute control and performance.&lt;/p>
&lt;hr>
&lt;h2 id="technical-context">Technical Context&lt;a class="anchorjs-link" href="#technical-context" aria-label="Link to section: Technical Context">&lt;/a>&lt;/h2>&lt;p>For an engineer, a personal site is the only project where you have absolute authority over the stack. There are no product managers, no legacy constraints, and no enterprise technical debt: you own the metal.&lt;/p></description></item><item><title>Python Background Workers: Architecture, Queues, and Retry Strategies</title><link>http://localhost:1313/building-production-ready-background-workers-in-python/</link><pubDate>Sun, 01 Feb 2026 13:00:00 +0530</pubDate><guid>http://localhost:1313/building-production-ready-background-workers-in-python/</guid><description>&lt;p>I thought processing audio in the background was simple: spawn a thread, run the script, save the file. Then I hit 200 concurrent requests, and it failed epically.&lt;/p>
&lt;p>The CPU spiked to full usage because of pydub&amp;rsquo;s processing. The TTS API didn&amp;rsquo;t rate-limit me but, it was horribly slow. Then the jobs started failing. Half the jobs died silently. The other half wrote corrupted files because of race conditions I didn&amp;rsquo;t know existed. And when I deployed a little fix? The deployment killed in-flight jobs, leaving orphaned audio segments scattered across cloud storage directory.&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></channel></rss>