ML
Engineering Journal

Writing as a second form of thinking

Clear, practical essays on how real software gets designed, breaks, and ships. The failure modes I've run into, the trade-offs that turned out to matter, and the patterns that hold up in production.

Apache Kafka
Jul 06, 20269 min

The Order That Shipped Twice: A Rebalance in the Middle of a Long Batch

A Kafka consumer processed every message exactly once for months, and then one afternoon a handful of orders shipped twice. Nothing had crashed, no message was redelivered by a broker retry, and the offsets on the dashboard looked healthy. The consumer had committed an offset it had not actually finished processing, a rebalance handed the same partition to another instance, and that instance dutifully reprocessed a batch the first one was still working through.

KafkaConsumers
Read
Java / Spring
Jul 06, 20268 min

The Failover That the JVM Slept Through: A DNS Record Nobody Re-Resolved

A database failover completed in under a minute. DNS flipped the endpoint to the new primary's address almost immediately, every other service reconnected, and the incident should have been over. One Java service kept hammering the old, now demoted, host for the better part of an hour. It was not a bug in our code or a slow health check. The JVM had resolved that hostname once at startup and cached the IP address effectively forever.

JavaDNS
Read
Concurrency
Jul 02, 20269 min

The ABA Problem: When Compare-And-Swap Said Nothing Changed and It Lied

A lock-free stack built on compare-and-swap passed every load test and then corrupted itself in production, popping a node that had already been freed. The CAS never failed, and a failing CAS was the only case anyone had thought to worry about. The bug was a value swinging from A to B and back to A while a paused thread was not looking, so the compare saw the same bit pattern and happily proceeded on data that was no longer the data it started with.

ConcurrencyLock-Free
Read