Skip to content
FeaturesPricingAffiliateBlogHelpAboutContact
Get StartedSign In
Back to Blog
industry2026-05-2312 min read

I upgraded to Diamond but Room Service never unlocked — Stripe webhook cache-purge fetch was missing a timeout

Iain (39) runs Royal Mile Bistro + 6-room guest house in Edinburgh Old Town. Friday 09:14 upgrades Platinum to Diamond via Stripe Customer Portal for the Hotel Room Service feature, payment confirmed, but admin panel sidebar shows Platinum for 2 hours. Support: Stripe Events tab shows webhook delivery 504 Gateway Timeout across all 5 retry attempts. Trace: webhook handler chain step 6 = cache-purge fetch to Cloudflare worker via POST /api/cache-purge; that morning Cloudflare KV in London edge had a regional outage stalling KV operations to 12-25 seconds; cache-purge worker did not return; webhook handler await fetch had NO AbortSignal.timeout wrap → blocks indefinitely → 30s budget exhausted → edge cuts at 504. Stripe retries hit the same wedge. Supabase + D1 had already committed tier=diamond in steps 3+5, but isolate-local cache TTL 60s held the stale Platinum entry for ~2 hours. **PR #661 batch XI F5** fix: one line — `signal: AbortSignal.timeout(5_000)` added to fetch options. AbortError swallowed by existing `.catch(() => {})`. Cache-purge stays best-effort; webhook handler completes audit log + 200 return within Stripe budget. Pattern: every await fetch on a webhook handler's critical path must be bound by AbortSignal.timeout (Stripe, Wise, Square, GitHub, custom inbound). 5 seconds is usually the right value — short enough to leave budget for the rest of the chain, long enough to absorb legitimate sub-RPC latency.

th

thMenu Team

thmenu.com

Found this helpful? Share it.