Skip to main content
Writing · № 03

All posts

Long-form notes on software, distributed systems, and the craft of building. Shipping one a week.

All Posts
36 posts
Distributed Systems01

Read-Your-Writes Is a Session Contract, Not a Database Setting

I added a read replica and within a day users reported edits that "didn't save" — they had saved, but the reads raced the replication stream and lost. These are my notes on why read-your-writes is a session contract rather than a replica setting, reproduced with a pinned 50 ms lag in Go, and the three ways to carry it — sticky routing, a GTID-style version token, and a bounded-staleness wait — compared on cost.

Jul 22
Engineering02

When SQL Is Enough for Streaming: What Incremental View Maintenance Guarantees — and What It Refuses

The 2026 pitch is that a hand-written stream job collapses into one CREATE MATERIALIZED VIEW, so I built one in RisingWave and spent my study time trying to break it. These are my notes on the consistency the view actually delivers as events arrive, why every join in it is a standing memory bill, and the queries that refuse to be incremental — with a Node consumer riding the view's changefeed over the plain Postgres protocol.

Jul 19
Engineering03

Java 26 Landed: The Features to Track Before the Java 29 LTS

Most backend teams run only the LTS lines, so Java 26 looks skippable. It is not — it is the clearest preview of what the Java 29 LTS will contain. These are my notes on what is already final (AOT object caching with ZGC, a faster G1, HTTP/3), the one preview I would rewrite code for (Lazy Constants, with a runnable example), and the integrity change that will break builds.

Jul 15
Engineering04

The Shift Zone: The Backend Is Becoming Software That Sleeps

I have watched state break the monolith, then microservices, then serverless — and I have spent months reading the changelogs that convince me the third break just got fixed. These are my notes on the 2024–2026 convergence of ephemeral compute and durable state, why the billing model is the tell, and the A/B experiment this post commits me to: rebuilding a problem I already solved in Spring Boot on the new substrate, with the numbers published either way.

Jul 12
Engineering05

The Server Is a Sync Relay Now: Architecting Around Client-Owned State

At QCon London 2026 Kleppmann described local-first as the best of Google Sheets and the best of Git, and this year the sync engines shipped. From my reading of Electric, Zero, and LiveStore side by side, these are my notes on what changes when the client's copy becomes primary: where conflicts resolve, what the server still owns, and the merge-vs-refuse line that decides which apps must never be built this way.

Jul 8
Distributed Systems06

Hybrid Logical Clocks: Making Last-Write-Wins Mean the Later Write

Wall-clock last-write-wins keeps the write from the faster clock, not the later event — and silently drops causally newer data under skew. These are my notes on rebuilding a Hybrid Logical Clock in Go: a 64-bit, monotonic, causal timestamp, why its counter stays bounded, and what it costs in CockroachDB-style uncertainty restarts.

Jul 8
Engineering07

Turning Repo Maintenance into Markdown: Keeping a Rust Codebase Alive with Agentic Workflows

Long-lived repositories drift: deprecated components linger, layers bleed, and tests miss the functions that actually break. In my own study I turned three recurring chores into scheduled markdown workflows the repo runs on itself, then wrote up what I learned about capping blast radius, pairing LLM checks with deterministic scans, and letting agents draft shapes while I write the substance.

Jul 5
Engineering08

What APISIX in the Trial Ring Actually Buys You: Notes on Its etcd-Backed Control Plane

Volume 34 of the Thoughtworks Technology Radar moved Apache APISIX into the Trial ring. I spent a week digging through the docs, source code, and a couple of bug reports to convince myself the etcd-backed dynamic-routing claim was real — and to weigh the operational cost it hides. These are my notes on the watch mechanism, the connection-scaling cliff at 263 long polls, and when I would and would not reach for APISIX in 2026.

Jul 1
Engineering09

Structured Concurrency Looks the Same in Four Runtimes — Until a Child Fails

I wrote the same fan-out four times — Java 25 StructuredTaskScope, Kotlin coroutineScope, Swift withThrowingTaskGroup, Python asyncio.TaskGroup — and the surface API is nearly interchangeable. The cancellation and exception-aggregation semantics are not. These are my notes on what diverges on the failure path and why only Python hands you every failure by default.

Jun 28
Engineering10

A Fitness Function Is Just a Test That Fails the Build When the Architecture Drifts

A fitness function is not a framework artifact — it is a build-failing test that encodes one architectural invariant. I encode a layering rule in about 60 lines of TypeScript using the compiler's own API, test the test against good, bad, and generated-code trees, then draw the line between an invariant worth gating and a metric gate that backfires under Goodhart's law.

Jun 24