APNs Stores One Pending Notification per App, So Treat Push as a Hint

Apple and Google both document what happens to a push when the device is offline, the app is killed or the sender is too chatty: messages are replaced, dropped, reordered or delayed. A table of those documented failure modes, and a small simulation showing that a client which pulls from a cursor converges where a client which applies push payloads does not.

September 19, 2026 | 9 min

Waiting for bufferedAmount Protects the Sender, Not a Slow Consumer

WebSocket send() never waits, and bufferedAmount only sees the part of the path that is in your own process. In a small lab, a sender that politely waited for bufferedAmount to drain still let a slow consumer queue nearly all 400 messages in its own memory, while a credit window of 8 kept the backlog at 8. This post goes through four common beliefs about send(), bufferedAmount, message size and backpressure, tests each one, and ends with a table for choosing between them.

September 6, 2026 | 14 min

Resuming an Event Stream with a Cursor, a Bounded Log and a Snapshot

How a client catches up after a reconnect without losing state, without duplicates, and without re-reading history. Built in steps (versions 0 to 4), from “read everything again” to a bounded log with a snapshot fallback, with what a real browser’s EventSource does on reconnect and on a non-200 response, a snapshot-ordering bug, and a decision tree.

September 4, 2026 | 17 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

Replace Polling with Change Subscriptions, and Keep the Poll as the Fallback

How a mobile client moved from timer-driven polling to shared change subscriptions over a per-message-billed relay. The subtle part is not the stream. It is deciding honestly when the fallback poll may stand down.

August 20, 2026 | 10 min

Separate the Live Document from the Saved Copy

Designing collaborative document editing with conflict-free synchronization, saved snapshots, and safeguards against overwriting content before initial sync.

August 13, 2026 | 12 min