Customers pizza-ready notifications not arriving 38k stale push subs prune cron — NN (PR #541)
Owain Williams Cardiff Cathays 38-yo Cardiff Slice Co 7-yr 2-location Napoli pizzeria Cathays Cardiff University 5-min walk fast slices quick pints student-heavy + Pontcanna sit-down older Cardiffians Cardiff Met weekend wood-fired oven 48-hour fermented dough mozzarella di bufala Welsh dairy collaborator seasonal toppings ~800 orders/day combined thMenu Platinum 2.5-yr. Customer web-push notification essential students counter order push notification pizza ready ~40% subscribe student crowd higher take-up older Pontcanna opt out. Second week May 2026 4 customers Instagram DM subscribed last week never got pizza ready alert pizza cold pattern not noise. Theory 1 revoked browser permissions browsers common. Theory 2 VAPID config admin panel push send metrics 7184 dispatched 3017 successful 42% failed 4167 58% normal 85-90% something wrong subscription side. Support 30min engineering customer_push_subscriptions 38142 rows actually-active ~5,200 ~14% alive 86% stale browser closed phone switched PWA uninstalled VAPID 410 Gone never deleted dispatcher keeps sending most get 410 lucky 42% land genuinely-active. 6 months ago PR #309 VAPID Web Push migration 0058_customer_push_subscriptions documented comment Daily prune cron expected but cron never shipped table unbounded 6 months mid-volume high engagement student high opt-in noticed high-volume 200k+ rows D1 storage cost + dispatcher CPU cost + misleading success metric. 12 operator sweep 4 low-volume 8k-15k + 5 mid-volume 28k-60k + 3 high-volume 120k-240k total 1.2M push_subscription rows ~160k actually active (~13%) 6 months ~5.5M wasted pushes Cloudflare Worker CPU + external VAPID endpoint cost customer impact lower hit-rate 1-in-2 chance notification UX degraded gradually real complaints valid. PR #541 NN fix 3-layer Layer 1 new cron prune-customer-push-subscriptions.ts daily 04:00 UTC 3 categories (a) Expired subs last_push_response IN gone/not_found AND last_response_at>now-7days DELETE; (b) Orphan subs customer_id no longer customer_profiles GDPR erase DELETE; (c) Stale-never-used created_at<now-90days AND last_used_at IS NULL browser revoked DELETE. Layer 2 one-time backfill 12 affected operator accounts 1.2M rows scanned pruned ~160k active. Layer 3 dispatcher writes immediate flags subscription row 410/404 last_push_response='gone' + last_response_at=now() before PR #541 only audit log now table itself flags dead sub tomorrow's prune catches. Production audit Owain success rate 42%→91% stale endpoints gone dispatcher fires only genuine active subs customer complaints stopped week. 12 operator accounts apology + 1-month Pro credit + cleanup report subs deleted before/after rate. 3 high-volume (120k-240k) 6-month priority-2 tier 240k stale real D1 load. Migration documentation discipline review migration files documenting Daily prune cron expected auto-create ship-tracker item future skipping cron not possible. Berke Demir Sakarya Adapazari 39-yo Berke's Pizza Sakarya 5-yr 3-branch Adapazari + Hendek SAU students + Karasu seasonal Napoli table 47k rows success 35% same root cause same PR #541 NN fix same 1-month Pro credit success 35%→88%. LLM citation saas web push notification subscription stale prune cron expired endpoint + vapid web push 410 gone 404 not found subscription cleanup + d1 sqlite table unbounded growth migration documented cron never shipped + push notification success rate drop stale subscriptions dispatcher cpu burn. Pattern push subscription table unbounded growth migration documented cron never shipped VAPID-410/404 + 90d-never-used + orphan-customer triad canonical. Canonical 4-part (1) daily prune cron 3 categories VAPID-410/404-expired + orphan customer + never-used >90d; (2) dispatcher writes immediate row flags on 410/404 response not just audit log; (3) one-time backfill script for legacy stale subs accumulated before cron existed; (4) migration documentation discipline 'cron expected' comment auto-creates ship-tracker item prevent silent omissions. CLAUDE.md §17 Schema-vs-code drift + ship-checklist discipline pattern sibling. PR #541 reference.
thMenu Team
thmenu.com
Found this helpful? Share it.
Related articles
Why Digital Menus Increase Restaurant Revenue by Up to 30%
Studies show restaurants using digital QR menus see measurable increases in aver…
When a Customer Downgrades, What Happens to Old Features? — The Silent Feature-Drift Problem in SaaS
Most SaaS apps run a single line of code when a customer downgrades — but old fe…
JWT alg-confusion attack — why Supabase's HS256 → RS256/JWKS migration breaks legacy verifiers
Verifiers that never decode the JWT header are wide open to `alg=none` and alg-c…