How we deliver order notifications in under 2 seconds
The full stack: VAPID-signed Web Push, service worker arpeggio sound, and why we don't use Supabase.
By Osama Khan
The problem
A customer hits "Place Order" at 8:47 PM. The owner needs to know about it now — not when they refresh the page, not in 30 seconds. Now.
The stack
1. Customer's browser POSTs the order to our API 2. Order is created in MongoDB 3. Backend looks up the owner's stored `PushSubscription` records 4. Sends a Web Push notification (VAPID-signed) to each subscription 5. Owner's service worker (running in the background, even if tab is closed) receives the push 6. SW shows a system notification + plays a synthesized arpeggio sound 7. Console tab (if open) also gets a real-time event via a separate channel
Total time: ~1.8 seconds median, P99 < 4 seconds.
Why not Supabase Realtime
We considered it. Decided against it. Reasons:
- Adds a second database (Postgres) just for pub/sub — our data is in MongoDB
- Doesn't solve the "phone locked / tab closed" problem (only Web Push does)
- Adds external SaaS dependency + cost
- Requires authenticated subscription per user, non-trivial bolt-on
Web Push is the actual answer when you want a phone to wake up. Polling + websockets only work when the user is actively looking at the screen.
The arpeggio
The default OS notification sound gets ignored. We synthesize a 5-note arpeggio via the Web Audio API inside the service worker. It's distinctive enough that owners learn to recognize it within a day.
Failure modes
- Push subscription expires (rare, but happens) — we re-subscribe on next page load
- Browser doesn't support Web Push (Safari < 16.4) — we fall back to polling every 10 seconds while the tab is open
- Phone in airplane mode — push lands when they reconnect; no orders lost
What it costs us
Web Push is free. VAPID keys are generated once. No per-message charge. This is one of the few things in our stack that scales linearly to free.