How Web Push Notifications Work Internally
You see notifications for new messages, order updates, or payment reminders.
It looks simple. Your backend sends a message and the user receives it.
In reality, the process involves many moving parts. Your backend never talks directly to the browser. Instead, it uses a Push Service.
Google Chrome uses Firebase Cloud Messaging. Firefox uses the Mozilla Push Service.
The workflow works like this:
Backend → Push Service → Browser → Service Worker → User
Here is how you build this system using React and Golang.
The Components
- Frontend (React): Requests permission and registers a Service Worker.
- Service Worker: A background script that lives in the browser. It handles events even when your website is closed.
- Backend (Golang): Stores subscriptions and sends encrypted messages.
- Push Service: The middleman that delivers the message to the browser.
The Subscription Flow
To send a message, you need a subscription.
- The user grants permission.
- The browser generates a subscription object containing an endpoint and security keys.
- Your React app sends this object to your Golang backend.
- Your backend saves it in a database.
You must use VAPID keys to identify your server. Use a public key for the frontend and a private key for the backend. Never share your private key.
The Implementation
In React, you register a Service Worker to listen for push events. This worker runs in the background. It receives the data and shows the notification to the user.
In Golang, you use a library to handle encryption and VAPID authentication. Your server reads the subscription from your database, encrypts the payload, and sends it to the browser push service.
Scaling for Production
A simple setup works for small projects. A large system needs more.
- Handle multiple devices: One user might have a phone and a laptop. Store multiple subscriptions per user.
- Clean up data: Subscriptions expire. If you get a 404 or 410 error, delete that subscription from your database.
- Use Queues: For millions of users, use Kafka or a similar tool. This allows your system to process notifications asynchronously.
- Implement retries: Use exponential backoff to handle network failures.
WebSockets are good for live chats when the user is active. Web Push is better for reaching users when the tab is closed.
