Tutti gli scritti
ScrittoScritto segnaposto

A small presence server on Durable Objects

Questo scritto è disponibile solo in inglese.

Placeholder post. A sketch of the architecture behind the live cards. English only, on purpose, to exercise the language fallback.

The cards on the home page are live: they show whether I am at my desk, which file I am editing, and how many people are reading right now. All of it runs on one Cloudflare Durable Object.

One object, many sockets

Every page opens a single WebSocket to the worker. The worker forwards it to a Durable Object named global, which accepts it with the hibernation API and tags it with the page path:

this.ctx.acceptWebSocket(server, [`page:${path}`]);
const onThisPage = this.ctx.getWebSockets(`page:${path}`).length;

Hibernation

Hibernation matters: while nobody connects or disconnects, the object sleeps and costs nothing, but the sockets stay open.

Tags per page

Each socket carries the path it was opened from, so “on this page” is a single lookup by tag, with no table to keep in sync.

Counting without tracking

Each new connection adds one view to an all-time counter and to a daily bucket, both in the object’s SQLite storage. Reconnects after a network blip are flagged by the client and not counted again. There are no cookies, no IP addresses and no user identifiers anywhere — the count is of connections, not of people.

Reconnects are not views

The client sends seen=1 when it reconnects after a blip, so a flaky train connection does not inflate the count.

Presence from the editor

“Now editing” comes from a tiny script that posts the current file and branch with a bearer token. If no heartbeat arrives for a while, an alarm flips the status to away, and later to offline.

Failing quietly

If the worker is unreachable the cards say so calmly and keep their size. A personal site should never show a stack trace because a counter is down.

To be continued