Nobody knew what one message cost, so nobody could rank the rest of the
scaling backlog. This walks a conversation, a group, a call and an attachment
through the real application and counts requests, payload bytes and database
round trips per flow, with the numbers and the ranking written up in
docs/COST.md. The budgets are ceilings, so a change that doubles the work
behind a send fails here with a number.
The headline: one message is 2 requests and 10 round trips — and seven of
those ten are authorisation and presence, three touch a message. Every idea
on the backlog about moving envelopes around is optimising the smaller half.
The measurement immediately found a duplicate read. authenticate loads
the device row to check the token's key binding, then poll loads the same
row again for the revocation check — one primary-key read done twice,
microseconds apart, on the busiest route in the system. Filed separately.
It also corrected relay#27's premise. That issue says a ten-person group
with two devices each is twenty uploads; the upload count is right and the
request count is not, because /e2e/messages takes one account and a LIST of
that account's devices. Ten people with two devices is ten requests, not
twenty. Fan-out is per person, only the blob is per device — a bandwidth
argument, not a request-count one.
And it downgraded relay#28. Round trips are flat against retained history —
the cursor query is id > after on an index and returns one page whatever is
behind it. What is not flat is bytes, and the client decides: a poll with no
cursor asks from zero and returns 21 KB of retained envelopes against 381
bytes for the one that is new. Cold storage is an argument about disk, not
about the hot path.
Two faults in the harness itself, both caught by disbelieving a number:
app.fluent.history records nothing a route does. Handlers use req.db,
which reads the history flag from the REQUEST's storage, fresh per request.
Every flow measured zero queries and every budget passed vacuously. A cost
harness that reports zero cost is worse than none — it answers with a wrong
number. Counted through a middleware that starts history per request now.
The history test compared a cold relay against a warm one and got ELEVEN
round trips cold against TEN warm. Storage growth cannot make polls cheaper.
The breakdown named it: the presence heartbeat writes once per account per
online window, so the first sample paid for a write the second had already
made. Both samples are now taken warm.
631 relay tests in 56 suites green, core paths 7/7.
Nobody knew what one message cost, so nobody could rank the rest of the
scaling backlog. This walks a conversation, a group, a call and an attachment
through the real application and counts requests, payload bytes and database
round trips per flow, with the numbers and the ranking written up in
docs/COST.md. The budgets are ceilings, so a change that doubles the work
behind a send fails here with a number.
The headline: one message is 2 requests and 10 round trips — and seven of
those ten are authorisation and presence, three touch a message. Every idea
on the backlog about moving envelopes around is optimising the smaller half.
The measurement immediately found a duplicate read. `authenticate` loads
the device row to check the token's key binding, then `poll` loads the same
row again for the revocation check — one primary-key read done twice,
microseconds apart, on the busiest route in the system. Filed separately.
It also corrected relay#27's premise. That issue says a ten-person group
with two devices each is twenty uploads; the upload count is right and the
request count is not, because /e2e/messages takes one account and a LIST of
that account's devices. Ten people with two devices is ten requests, not
twenty. Fan-out is per person, only the blob is per device — a bandwidth
argument, not a request-count one.
And it downgraded relay#28. Round trips are flat against retained history —
the cursor query is `id > after` on an index and returns one page whatever is
behind it. What is not flat is bytes, and the client decides: a poll with no
cursor asks from zero and returns 21 KB of retained envelopes against 381
bytes for the one that is new. Cold storage is an argument about disk, not
about the hot path.
Two faults in the harness itself, both caught by disbelieving a number:
- `app.fluent.history` records nothing a route does. Handlers use `req.db`,
which reads the history flag from the REQUEST's storage, fresh per request.
Every flow measured zero queries and every budget passed vacuously. A cost
harness that reports zero cost is worse than none — it answers with a wrong
number. Counted through a middleware that starts history per request now.
- The history test compared a cold relay against a warm one and got ELEVEN
round trips cold against TEN warm. Storage growth cannot make polls cheaper.
The breakdown named it: the presence heartbeat writes once per account per
online window, so the first sample paid for a write the second had already
made. Both samples are now taken warm.
631 relay tests in 56 suites green, core paths 7/7.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Nobody knew what one message cost, so nobody could rank the rest of the
scaling backlog. This walks a conversation, a group, a call and an attachment
through the real application and counts requests, payload bytes and database
round trips per flow, with the numbers and the ranking written up in
docs/COST.md. The budgets are ceilings, so a change that doubles the work
behind a send fails here with a number.
The headline: one message is 2 requests and 10 round trips — and seven of
those ten are authorisation and presence, three touch a message. Every idea
on the backlog about moving envelopes around is optimising the smaller half.
The measurement immediately found a duplicate read.
authenticateloadsthe device row to check the token's key binding, then
pollloads the samerow again for the revocation check — one primary-key read done twice,
microseconds apart, on the busiest route in the system. Filed separately.
It also corrected relay#27's premise. That issue says a ten-person group
with two devices each is twenty uploads; the upload count is right and the
request count is not, because /e2e/messages takes one account and a LIST of
that account's devices. Ten people with two devices is ten requests, not
twenty. Fan-out is per person, only the blob is per device — a bandwidth
argument, not a request-count one.
And it downgraded relay#28. Round trips are flat against retained history —
the cursor query is
id > afteron an index and returns one page whatever isbehind it. What is not flat is bytes, and the client decides: a poll with no
cursor asks from zero and returns 21 KB of retained envelopes against 381
bytes for the one that is new. Cold storage is an argument about disk, not
about the hot path.
Two faults in the harness itself, both caught by disbelieving a number:
app.fluent.historyrecords nothing a route does. Handlers usereq.db,which reads the history flag from the REQUEST's storage, fresh per request.
Every flow measured zero queries and every budget passed vacuously. A cost
harness that reports zero cost is worse than none — it answers with a wrong
number. Counted through a middleware that starts history per request now.
The history test compared a cold relay against a warm one and got ELEVEN
round trips cold against TEN warm. Storage growth cannot make polls cheaper.
The breakdown named it: the presence heartbeat writes once per account per
online window, so the first sample paid for a write the second had already
made. Both samples are now taken warm.
631 relay tests in 56 suites green, core paths 7/7.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com
assigned to @paulhitt
deleted the
feat/prove-two-relay-instancesbranch. This merge request now targets themainbranchmentioned in commit
51d386c3a8changed the description