Skip to content

Dashboard private reads fail on cold AccountEnrollment DO — readEnrollmentStatus audit starves parallel reads #360

Description

@0thernet

Summary

On a cold AccountEnrollment Durable Object, the /usage dashboard's parallel private reads (/api/usage/consent, /api/usage/stats, /api/usage/days, /api/usage/account) can all fail with unavailable: readEnrollmentStatus is a committing path that pays the one-time deferred history audit (~6.7 s on this account) inside transactionSync, and DO storage serializes — every concurrent read queues behind the audit and blows the transport's ~5 s stage / 15 s client budget.

Reproduced evidence (2026-09-21, production)

Fresh sign-in at 16:30:58, page auto-load at 16:31:00 fired account + consent + stats together on a DO idle ~13 min: stats returned unavailable and the consent panel stayed stuck on "Loading your publishing status." With the same account's DO pre-warmed/audited, the identical signed-in session's POST /internal/usage/stats + readUsageStats completed Ok at 17:00:04–05 (~sub-second).

So: cold load → failure; warm/audited → success. First page load after any idle eviction is the exposed case.

Impact

Every signed-in user's first dashboard visit after a DO idle eviction can render "Account usage could not be loaded" plus a stuck consent spinner — on an otherwise healthy system.

Possible directions

  • Make auditHistory interruptible/chunked across transactions so it cannot hold the storage gate for ~7 s; or
  • Run the deferred audit under blockConcurrencyWhile-free background control and let reads bypass it while mutations await it (reads already provably don't need it); or
  • Sequence the dashboard's calls client-side (consent first, then stats/days) — cheap but only narrows the race; or
  • Keep a per-account warm read replica path for pure reads.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions