← All posts
Engineering10 min readApril 12, 2026

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.

Enjoyed this?

More writing from inside our build.