Skip to content

Writing/Architecture

The cheap design that measurement ruled out

A pollable endpoint looked like it would do the job. Seventy-eight minutes of measuring two real accounts showed it was wrong by up to forty-three minutes, and that decided the architecture.

ISIonuț Sandu22 Aug 2026 · 8 min readArchitectureReliabilityMeasurement

I wanted a notification when a friend came online in a game. There is a documented endpoint that returns when an account was last online, and polling it every minute is the obvious design: no socket, no always-on process, a scheduled function and a few lines. I nearly built that.

Instead I spent seventy-eight minutes measuring it against two real accounts, and every number came back wrong in a different way.

What the measurement said

The field is activity-driven and irregular rather than continuous. It advanced once and then not again for fifty-four minutes, during which the account was demonstrably playing. Two accounts in the same state at the same instant read fifteen minutes apart, one of them stale and the other seventeen seconds fresh. At the moment the answer mattered most, the field was forty-three minutes behind reality.

It also never went absent for an online account, so the tempting shortcut of treating a missing value as presence is simply false. And the GraphQL query that older libraries use for this has been removed entirely, which is worth knowing before you build on a tutorial.

“Every cheap design here was ruled out by measurement, not by preference. That is the only way I trust the answer.”

So polling can answer neither of the two questions I actually had: is this person online now, and did they just arrive. That is not a tuning problem, and no polling interval fixes it. It is a socket or it is nothing, which means a process that stays connected, which means somewhere for it to run. The expensive answer was the only correct one, and I only know that because I measured instead of reasoning about it.

Every guard is a scar

The connection then produced its own set of problems, and the useful discipline was writing down what each guard was for. There are six, and not one is hypothetical.

The service replays presence for everyone already online at the moment you connect, so without a short grace period on boot, every restart re-announces half your friends mid-session. Presence changes churn constantly as somebody moves between menus, so notifications have to be deduplicated per session rather than per event. The upstream flaps: I measured offline-to-online round trips of 1.2 and 2.1 seconds, which read as a fresh arrival unless you debounce them. And the cooldown that suppresses repeats has to be durable, because an in-memory one is wiped by a restart and lets exactly the flap through that it existed to stop.

The heartbeat that lied

The worst failure was not a crash. The library does not reliably reconnect, and on one occasion the process sat alive and connected and completely blind for ten hours, while reporting itself healthy the entire time. On another it did the same for eight.

It reported healthy because the heartbeat wrote that it was connected unconditionally, and because the library's own connection check only asks whether the socket is open. A half-open socket is open. So the monitoring was not detecting the outage, it was manufacturing the appearance of health.

The obvious fix is to ask the server for heartbeats, so that silence becomes a protocol-level fact rather than an inference. I tried it. The server rejects the configuration outright: the handshake never completes, registration fails, and the service crash-loops. A baseline measurement confirmed zero inbound heartbeat frames across two windows, so the library's setting is not an oversight, it is the only thing the server accepts.

So liveness is enforced from outside instead: the process exits on disconnect rather than trying to heal, and the heartbeat only claims health when it can prove it. Two lessons worth carrying anywhere. A health check that cannot fail is worse than none, because it converts an outage into a silence nobody investigates. And when the elegant fix is rejected by something you do not control, the answer is to measure what it does accept and design against that, rather than to keep pushing the elegant one.

Ionuț Sandu — 22 Aug 2026Copy link

NEXT · 19 AUG 2026 · 9 MIN READ

Auditing a Supabase app with its own public key

The anon key ships inside every build. Before a release I take it, point it at the database, and go through every table and function asking what it will tell a stranger.

Taking on new projects

Tell me what you’re building.A written scope and a fixed quote before any money moves.

I reply to everything within one working day. If I’m not the right person for it, I’ll tell you straight away rather than three weeks in.