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.

backendapinetworkingperformance

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.

databaseperformancetoolingbest-practices

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.

databasepostgresqlperformancebackend

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.

backendnetworkinginfrastructurereliability

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.

apibackendrate-limitingnetworking

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.

databasescalingpostgresqlarchitecture

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.

best-practicesengineeringmaintainability

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.

frontendjavascriptcompatibilityweb-development

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.

frontendperformancetoolingweb-development

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.

frontendreactweb-development

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.

frontendreactcompatibilityweb-development

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.

frontendperformanceaccessibilitycssweb-development

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.

designuxfrontendbest-practices

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.

debuggingfrontendengineeringbest-practices

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.

documentationengineeringbest-practicesproductivity

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.

documentationaiclaudeengineeringproductivity

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.

architecturefastapipythonbackend

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.

fastapisqlalchemypythonbackenddatabase

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.

apisecuritydatabasebackend

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.

backenddatabasepythonconcurrency