Skip to content

fix(deploy): recover maintenance page on tab refocus & bfcache restore#167

Merged
stevenfackley merged 1 commit into
mainfrom
fix/maintenance-page-recovery
Jun 21, 2026
Merged

fix(deploy): recover maintenance page on tab refocus & bfcache restore#167
stevenfackley merged 1 commit into
mainfrom
fix/maintenance-page-recovery

Conversation

@stevenfackley

Copy link
Copy Markdown
Owner

Why

Prod-incident report: user stranded on the "Brewing a new version" maintenance page while the origin was fully healthy (verified / and /api/healthz → 200 end-to-end through CF→tunnel→nginx→sa-web; cf-cache-status: DYNAMIC, no stale edge copy, no service worker). The page was a stale tab, not a live outage.

Root cause

docker/maintenance.html only re-checked /api/healthz via a 5s setInterval and a 20s <meta refresh>. Both are timers — browsers throttle/suspend timers in backgrounded tabs and asleep devices (mobile Safari especially). A tab parked on the page during a deploy window can sit on "Brewing…" indefinitely after origin recovers, because the auto-reload timer never fires.

Fix

Also poll healthz on:

  • visibilitychange (tab brought back to foreground)
  • pageshow (restored from back/forward cache)

So the live app returns the instant the user looks at the tab, instead of waiting on a throttled timer. Dependency-free, no behavior change to the happy path; <meta refresh> remains the no-JS fallback.

Test

Static HTML page; no automated test harness for it. Manual: load page, background the tab, bring it back → fires an immediate healthz check.

The maintenance page only re-checked /api/healthz via a 5s setInterval and a
20s <meta refresh>. Both are timers, which browsers throttle or suspend in
backgrounded tabs and asleep devices. A tab parked on the page during a deploy
window could stay stranded on "Brewing a new version" indefinitely after origin
recovered.

Also poll healthz on visibilitychange (tab refocused) and pageshow (back/forward
cache restore) so the live app returns the instant the user looks at the tab,
not whenever a throttled timer happens to fire.
@stevenfackley stevenfackley merged commit fd1d424 into main Jun 21, 2026
12 of 14 checks passed
@stevenfackley stevenfackley deleted the fix/maintenance-page-recovery branch June 21, 2026 23:26
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