Writing

Technical writing on
backend engineering.

18 long-form articles on Node.js, PostgreSQL, AWS infrastructure and system design — all of it distilled from running a production SaaS at 20,000+ user scale, not from tutorials. The recurring themes: making the server the authority, designing for at-least-once delivery, and keeping databases fast as load climbs. Most of it comes out of the systems I've shipped.

Topics: Backend (8) · DevOps (3) · System Design (7) · Subscribe via RSS

DevOps 13 min read

GitHub Just Shipped Stacked Pull Requests. I've Been Faking Them for Years.

GitHub's native stacked pull requests hit public preview on July 30, 2026 — dependent PRs that review as separate layers and rebase server-side when the bottom one merges. I've hand-rolled this workflow with 'depends on #142' comments and rebase cascades for years. Here's how the native version works, what it replaces, and where I'd still be careful.

System Design 21 min read

Same Row, Three Truths: A Three-Party Workflow in Postgres

Client, operator, caterer — one record, three audiences, none trusting the others. Modelling a three-party workflow in Postgres with read-time projections.

System Design 21 min read

Store Grams, Not Bags: Designing a Multi-Unit Inventory Ledger in Postgres

A kitchen buys in bags, cooks in grams, counts in kilos. How I modelled a multi-unit inventory ledger in PostgreSQL: one base unit, one lock target, one log.

Backend 10 min read

I Automated 90% of a Grungy Data-Entry Job Without an LLM — and Where an Agent Would Actually Earn Its Place

The hype says throw an AI agent at manual data entry. I automated a menu-onboarding pipeline — hundreds of items, images, matching — with boring deterministic code and a human-in-the-loop for the ambiguous 10%. Here's the pipeline, why an LLM would have been the wrong first tool, and the exact two places a vision-language model does earn its cost.

System Design 9 min read

Fine-Grained RBAC for a Multi-Tenant SaaS — Without a Policy Engine

You don't need OPA, Zanzibar, or a rules DSL to do least-privilege access control in a multi-tenant SaaS. A permission set, a role→permission map, and one tenant-scoped middleware get you fine-grained, auditable authorization in plain SQL. Here's the model, the two checks every request needs, and the mistakes that leak data across tenants.

Backend 9 min read

I Have Idempotent Search Endpoints Doing POST. Should They Be QUERY?

HTTP finally got a safe, idempotent, cacheable method that carries a request body — QUERY, standardized as RFC 10008 in June 2026. I have real filter endpoints that abuse POST for exactly this reason. Here's what QUERY actually fixes, what breaks if you adopt it today, and my honest verdict on whether to migrate.

System Design 14 min read

Never Trust the Client to Create the Order: Making Payment the Source of Truth

A restaurant order that exists only after the customer's app calls your API is one crashed screen away from a paid-but-missing order. Here's how I moved order creation behind the payment webhook — and the three layers of idempotency it took to survive the race that created.

System Design 12 min read

You Probably Don't Need Kafka: A Durable Outbox and Job Queue in Plain Postgres

Before you add Kafka to send an email after an order, look at the database you already run. A transactional outbox plus FOR UPDATE SKIP LOCKED gives you a durable, at-least-once job queue with exactly-once side effects — no broker, no second system to operate. Here's the whole pattern, and the four things that bite you in production.

Backend 9 min read

Everything I Got Wrong Building Real-Time Order Tracking with Socket.IO

Live order tracking looks trivial in the demo: emit an event, the map moves. Then production teaches you that a WebSocket is a lossy notification channel, not a database. Nine mistakes I made building real-time tracking on Socket.IO — disconnects, missed events, rooms, scaling across instances — and the one rule that fixes most of them.

System Design 11 min read

Reconciliation, Not Sync: Integrating a System That Also Webhooks You Back

You can't 'sync' two systems that both change the data and both notify each other — you get echo loops, out-of-order events, and fields that silently disagree. The honest model is reconciliation: pick an owner for every field, apply inbound events idempotently, and run a periodic sweep that repairs the delta. Here's the pattern, from a real bidirectional POS integration.

Backend 11 min read

15 Production Mistakes I Made Scaling a Node.js SaaS to 20,000 Users

An honest retrospective of 15 backend mistakes made while scaling a multi-tenant food-tech SaaS to 20,000+ users and 50,000 meals a month - from query assumptions and missing pagination to concurrency bugs, file storage, and optimizing too late.

Backend 12 min read

Scaling PostgreSQL in Production: Indexing, RPC Functions, Views, and Query Optimization

A practical look at how composite indexes, database views, Supabase RPC functions, pagination, and query optimization techniques improved the performance and maintainability of a multi-tenant PostgreSQL system handling over 120,000 daily database requests.

Backend 10 min read

Building an Atomic Delivery Dispatcher with PostgreSQL Row-Level Locking

How to design a high-reliability delivery batching and dispatch engine in TypeScript. Learn how to prevent rider capacity overload using PostgreSQL row-level locks, enforce strict order states, and store delivery tracking proofs using JSONB.

Backend 11 min read

Designing a Multi-Tenant Subsidy Engine with Concurrency-Safe Budget Tracking

How to architect a B2B meal allowance and subsidy calculation system in Node.js and PostgreSQL. We walk through schema mapping, resolving discount conflicts using the Maximum Rule, and preventing budget depletion race conditions.

DevOps 8 min read

How I Cut AWS Costs by 60% by Fixing Infrastructure Inefficiencies

How to cut an AWS bill by 60% without re-architecting: trim verbose request logging that floods CloudWatch and S3, add S3 lifecycle rules so logs and uploads expire, and move static asset serving off Node.js onto NGINX. A line-by-line breakdown of $1,250/month down to $480.

System Design 6 min read

Scaling a Food-Tech SaaS from 1K to 20K Users

What actually broke scaling an institutional food-services platform from 1,000 to 20,000+ users: queries that were fine at 10,000 rows and timed out at 200,000, connection churn, and an 80%-of-orders-in-90-minutes lunch rush. The fixes were composite indexes, pagination, pre-computed quotas and a background queue.

Backend 8 min read

Node.js Performance Optimization: From Slow APIs to Scalable Systems

Five Node.js performance fixes measured with Autocannon on one t3.medium: keeping CPU work off the event loop, PM2 cluster mode across cores, Redis caching for read-heavy routes, index-aware queries and gzip compression. Result: p95 latency 420ms to 18ms and throughput 240 to 4,200 req/sec.

DevOps 7 min read

Zero-Downtime Deployments with PM2 and NGINX

How to deploy a Node.js API with zero downtime using PM2 cluster mode and NGINX: rolling reloads instead of restarts, a SIGINT handler that drains in-flight requests, proxy_next_upstream retries, and a webhook-driven CI/CD pipeline. From a production platform that went from 30-second deploy outages to none.