Blog
Notes on software engineering, architecture, and how systems get built.
August 28, 20264 min read
What 'Traffic' Actually Means at the Backend and API Layer
Requests per second, concurrent connections, and bandwidth sound like the same idea. They aren't, and conflating them is a common source of capacity-planning mistakes.
August 28, 20266 min read
Connection Pooling: The General Idea and the Tools That Implement It
Opening a new connection is expensive enough that reusing a small set of already-open ones is almost always faster. Here's the mechanic behind pooling, and how PgBouncer, HikariCP, and HTTP keep-alive each apply it.
August 28, 20265 min read
Why Database Traffic Isn't the Same Problem as API Traffic
A backend can serve light API traffic while its database is under heavy load, or the reverse. Here's why the two are genuinely decoupled, and why one common defense against overload barely exists at the database layer.
August 28, 20266 min read
Load Balancing: Why L4 and L7 Are Genuinely Different Tools
A load balancer distributes traffic across servers, but not all load balancers can see the same information about that traffic. Here's what actually separates a Layer 4 balancer from a Layer 7 one, and when each is the right choice.
August 28, 20266 min read
Rate Limiting: The Algorithms and How Real APIs Implement Them
Rejecting too many requests sounds simple until the counting itself becomes the hard part. Here's how the standard algorithms actually work, and how Cloudflare, Stripe, and GitHub each apply them in production.
August 28, 20264 min read
Read Replicas, Sharding, and Scheduled Jobs: Three Ways Database Load Actually Gets Managed
Three distinct techniques get reached for when a database is under too much load, and they're easy to confuse for each other. Here's what each one actually does, and why they solve different problems.
August 27, 20264 min read
DRY and the Cost of a Value Typed Out More Than Once
The same number, string, or color typed into two places in a codebase looks harmless until one copy changes and the other doesn't. Here's the principle behind why that's worth avoiding, and where the line actually is.
August 27, 20263 min read
Feature Detection: Asking a Browser What It Can Do, Correctly
Not every browser supports every API, and guessing based on browser identity is a well-documented anti-pattern. Here's the actual, correct way to check what a browser can do before relying on it.
August 27, 20266 min read
Bundle Weight: The Hidden Cost of Everything a Page Ships
A page can feel instant to build and still hand a visitor's browser far more JavaScript than it needs. Here's what bundle weight actually is, why it accumulates invisibly, and how to measure it.
August 27, 20264 min read
Hydration Mismatch: When a Server and a Browser Disagree
Frameworks that render HTML on a server and then take over in the browser depend on both sides producing identical output. Here's what happens when they don't, and why it's a named, well-understood bug category rather than a mystery.
August 27, 20265 min read
Implicit Contracts: When a Component Assumes Something About Its Children
Wrapper components often make silent assumptions about what they're wrapping: a single child, a mounted-and-waiting tree. When those assumptions break, the failure is usually confusing rather than obvious.
August 26, 20267 min read
Adaptive Motion: Designing Animation That Respects the Device It Runs On
Smooth animation on a development machine can stutter badly on a mid-range phone. Here's why, and how to scale motion complexity to what a device can actually handle.
August 26, 20265 min read
Motion as a Signifier: Keeping Decoration Secondary to Content
A hover effect on something that isn't clickable isn't just unnecessary: it's a false signal. Here's the vocabulary for talking about when motion helps and when it misleads.
August 26, 20265 min read
Why the Fastest Debugging Step Is Testing the Real Build
A bug that only appears in a development environment can send debugging in the wrong direction entirely. Testing against a production build first is often the cheapest way to rule that out.
April 7, 20267 min read
Why Documentation Templates Are Worth Building
Ad-hoc documentation fails teams silently. Here's a structure that fixes it: template design, writing standards, and what to include.
April 7, 20268 min read
Using Claude to Write and Maintain Technical Documentation
How to use Claude as a documentation assistant: what to provide, what to expect, and how to keep docs accurate over time.
March 18, 20264 min read
The MSCR Pattern: Structuring Every FastAPI Backend
Fat route handlers are a trap. Here's the four-layer architecture that keeps backends testable, maintainable, and sane.
March 17, 20264 min read
Transaction Control: Why Only Services Should Commit
SQLAlchemy makes it easy to commit from anywhere, which is exactly why you shouldn't. Here's why services own the transaction boundary and repositories only flush.
March 16, 20263 min read
The Dual-ID Pattern: Stop Exposing Integer Primary Keys in Your API
Returning database IDs like 1, 2, 3 in your API is a quiet security mistake. Here's a two-field fix that keeps your internals private.
March 15, 20263 min read
Race Conditions in APIs: Why 'Check If Exists' Isn't Enough
The naive duplicate check breaks under concurrent load. The check-then-catch pattern uses both application logic and database constraints as a safety net.