Skip to content
Developers · 9 min read

The Web Push protocol, explained

Web push is three IETF standards working together: one for delivery, one for encryption and one for sender identity. Understanding them makes debugging and design decisions much easier.

Updated By the Pusharoo team
In short
  • RFC 8030 defines delivery: an HTTP POST to the subscription endpoint with TTL, Urgency and Topic headers.
  • RFC 8291 encrypts every payload end to end, so push services can’t read your messages.
  • RFC 8292 (VAPID) authenticates your server to the push service.
  • A 201 means queued; 404/410 mean the subscription is gone and must be deleted.

Three standards, one flow

StandardDefinesIn practice
RFC 8030Generic Event Delivery Using HTTP PushPOST to the endpoint; TTL, Urgency, Topic headers
RFC 8291Message Encryption for Web PushECDH P-256 + HKDF using the subscription’s p256dh and auth keys
RFC 8188Encrypted content codingContent-Encoding: aes128gcm
RFC 8292VAPIDAuthorization: vapid t=…, k=…

The browser side — Push API, service workers, Notifications API — is specified by the W3C and WHATWG. See the Push API in JavaScript.

Anatomy of a send request

POST /wp/abc123... HTTP/1.1 Host: fcm.googleapis.com TTL: 86400 Urgency: normal Topic: spring-sale Content-Encoding: aes128gcm Content-Type: application/octet-stream Authorization: vapid t=eyJ0eXAiOiJKV1Qi..., k=BOr6... <encrypted payload bytes>

The delivery headers

HeaderMeaningTip
TTLSeconds the push service keeps trying if the device is offline (0 = deliver now or drop)Short for time-limited offers, longer for evergreen content
Urgencyvery-low, low, normal, highHigh only for genuinely urgent messages; it affects battery
TopicReplaces an undelivered message with the same topicUse for “latest score” style updates

Encryption in brief

When a browser subscribes it generates an ECDH key pair (the public half is p256dh) and a random 16-byte auth secret. To send, your server creates its own ephemeral key pair, derives a shared secret with the browser’s public key, mixes in the auth secret through HKDF, and encrypts with AES-128-GCM. Only that browser can decrypt. The push service just stores and forwards opaque bytes. That’s why reputable libraries are essential: the details are easy to get subtly wrong.

Response codes

CodeMeaningAction
201 CreatedAccepted and queuedCount as sent
400Malformed request or headersFix your sender
403VAPID/authorisation failedCheck keys match the subscription
404 / 410Subscription expired or unsubscribedDelete it permanently
413Payload too largeShrink the payload
429Too many requestsBack off and retry

Push services must accept payloads of at least 4,096 bytes; design for that limit (copy length).

Push service hosts by browser

BrowserEndpoint host (typical)
Chrome, Opera, Samsung Internet, Bravefcm.googleapis.com
Firefoxupdates.push.services.mozilla.com
Safari (macOS, iOS/iPadOS)web.push.apple.com
Edge*.notify.windows.com (Windows Push Notification Services)

You never pick the host: the browser gives you the full endpoint URL. Logging the host per send makes browser-specific problems obvious. Don’t allowlist hosts too strictly in outbound firewalls — they can change.

Rate limits and fairness

Push services don’t publish fixed per-sender quotas, but they do throttle: a burst can return 429 Too Many Requests with a Retry-After header. Spread large sends over minutes, reuse HTTP connections, and use a bounded number of concurrent requests per host. For non-urgent content, Urgency: low lets devices batch delivery and save battery, which is also kinder to your subscribers.

One request per subscription

Unlike some native push APIs, standard Web Push has no multicast: every subscription has its own endpoint and encryption keys, so each message is encrypted and sent individually. That’s why sending to 100,000 subscribers means 100,000 HTTPS requests — and why efficient senders queue, batch and parallelise carefully.

How Pusharoo uses the protocol

Pusharoo’s sender implements these standards directly with an open-source library — no Firebase project in the middle — batches sends, honours 404/410 by removing subscriptions immediately, and purges dead ones automatically (deliverability).

Questions

Is web push encrypted end to end?

Yes. RFC 8291 encrypts payloads with keys only the subscribing browser holds; the push service can’t read the content.

What is the maximum web push payload size?

Push services are required to accept at least 4,096 bytes, and that is the practical limit to design for.

Do Chrome, Firefox, Safari and Edge all use the same protocol?

Yes. Endpoints differ by vendor, but the request format, encryption and VAPID are the same standards.

What HTTP status codes do push services return?

201 means accepted; 404 or 410 means the subscription is gone; 413 is too large; 429 is rate limited; 400 or 403 usually mean bad headers or VAPID.

Can I send push over HTTP/2?

Yes, push services support HTTP/2, which helps when sending many requests.

More in Developers: Service worker push events, done right · Web push notifications with Node.js · Web push notifications in PHP · Laravel browser push notifications (no Firebase) · Web push notifications in React and Next.js · Declarative Web Push, explained · Firebase web push vs. standard web push · Web push in Python with pywebpush · Django push notifications to the browser · Web push notifications in Ruby on Rails · Web push in Go with webpush-go · Angular push notifications with SwPush · Push notifications in Vue 3 and Nuxt · Push notifications in SvelteKit · All guides

Free for life. No limits.

Unlimited subscribers, campaigns and automations. No badges. About five minutes to install.