Skip to content

One hive RPC per MCP handshake; backoff on the SPA /ws reconnect - #24

Open
tieguy wants to merge 1 commit into
daniloc:mainfrom
tieguy:fix/handshake-cost
Open

One hive RPC per MCP handshake; backoff on the SPA /ws reconnect#24
tieguy wants to merge 1 commit into
daniloc:mainfrom
tieguy:fix/handshake-cost

Conversation

@tieguy

@tieguy tieguy commented Aug 14, 2026

Copy link
Copy Markdown

The problem

Companion to #23 (independent — either lands alone). With per-wake cost fixed, the wake rate is the other half: per-minute Cloudflare analytics show HiveDO waking in a quantum of exactly three requests every 60–90 seconds, around the clock. That's one full MCP handshake per reconnecting client — the claude.ai connector and every open Claude Code session re-handshake on their own schedule, and each handshake lands a fresh SessionDO whose init() made three separate hive RPCs (registerSession, getRecentActivity, getMaintenanceStatus), the first of which was an unconditional storage.put.

The reconnect cadence belongs to the clients; the per-handshake cost is the only lever the server owns.

The fix

  • getSessionBriefing(sessionId): session registration (scratchpad fanout) + working-memory + maintenance briefing in one RPC. registerSession becomes a no-op read when the session is already current, so a re-handshake of a known session writes nothing; a genuinely new session still writes once. (A SessionDO-side cache was considered and rejected: each re-handshake lands a fresh SessionDO with a new id, so a per-DO cache can never hit.)

  • SPA /ws reconnect backoff: the retry was a flat 3s with no backoff — a parked tab hammers a down worker 1,200×/hr, and every /ws attempt wakes the hive DO. Now 3s doubling to 60s with jitter, reset on successful open: a dead tab costs ~60 attempts/hr, a live one still recovers in seconds. (During a quota outage this matters doubly: the flat retry burns the freshly-reset budget the moment the cap clears.)

Tests

session-briefing.test.ts: briefing shape + registration in one call; a repeat briefing for an already-registered session performs zero storage.put calls (spied), while a new session still registers. Existing mcp-contract / scratchpad / memory suites pass unchanged.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Rf5RTB7iigiMpoArYzdUKN

Per-minute analytics identified the cold-start driver behind the quota
burn: HiveDO wakes in a quantum of exactly THREE requests every 60-90
seconds, around the clock — one full MCP handshake per reconnecting
client (the claude.ai connector plus each open Claude Code session, two
distinct signatures overlapping in the same minutes). Every handshake
lands a fresh SessionDO whose init() made three separate hive RPCs
(registerSession, getRecentActivity, getMaintenanceStatus), the first an
unconditional storage.put.

The reconnect cadence belongs to the clients; the per-handshake cost is
the only lever the server owns. So:

- getSessionBriefing(sessionId): registration + working-memory +
  maintenance briefing in ONE RPC. registerSession becomes a no-op read
  when the session is already current, so a re-handshake of a known
  session writes nothing. (A SessionDO-side cache was rejected: each
  re-handshake lands a fresh SessionDO with a new id, so a per-DO cache
  can never hit.)

- SPA /ws reconnect: 3s doubling to 60s with jitter, reset on open. The
  flat 3s retry meant a parked tab hammered a down worker 1,200x/hr, and
  every /ws attempt wakes the hive. A dead tab now costs ~60/hr; a live
  one still recovers in seconds.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rf5RTB7iigiMpoArYzdUKN
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant