Socket Activation Keeps Connections Waiting, Not Refused, During a systemd Restart

A runbook for replacing a running daemon without dropping requests, tested on a small TCP server under real systemd. A plain restart refused or reset connections every time; starting the new version beside the old one avoided refusals but still reset a connection in some runs, and a kernel setting made those resets go away; socket activation produced no errors. Also covered: draining in-flight work against TimeoutStopSec, and a release swap that checks the new version and rolls back.

October 3, 2026 | 18 min

systemd Kills the Updater Your Service Started, Even With setsid

A daemon that updates itself by starting a helper and restarting its own unit has a trap: the helper starts inside the service’s cgroup, and systemd kills everything in that cgroup on restart. In a throwaway systemd, a setsid’d helper vanished before its last log line, KillMode=process kept it alive but leaked it into the next instance, and systemd-run gave it its own unit. This post shows the evidence, the fix, and what I did not test.

September 28, 2026 | 12 min

Two write() Calls Can Stall a TCP Connection for 40 ms

Send a header and a body as two small write() calls, then wait for a reply, and every round trip can stall for about 40 ms on an idle machine with an idle network. Neither Nagle’s algorithm nor delayed ACK is a bug; together they deadlock until a timer fires. This post predicts the stall, reproduces it with a 50-line script, reads it off a packet trace, and compares the four ways out.

September 1, 2026 | 13 min

Edge-Triggered epoll Hangs After a Partial Read, and Event Streams Break the Same Way

epoll’s edge-triggered mode stalls after a partial read; level-triggered mode cannot. The same distinction decides whether a realtime client survives lost, duplicated and reordered events. A reproducible epoll experiment, a five-way simulation on a lossy channel, and a 40-line invalidator that handles the race everyone misses: an event that arrives while the refetch is running.

August 25, 2026 | 18 min

A Dead TCP Peer Goes Unnoticed for 15 Minutes on Writes, Forever on Reads

TCP never tells you that the peer is gone. A reader blocks forever, a writer keeps retransmitting for a quarter of an hour, and SO_KEEPALIVE does nothing while data is unacknowledged. This post builds a one-file Linux lab with no root, climbs a ladder of mechanisms (nothing, keepalive, TCP_USER_TIMEOUT, an application heartbeat), measures how long each takes to notice, and shows where NAT and the RFCs fit in.

August 23, 2026 | 19 min