The Subscription
The subscription is created on client side when the end-user allows your application to send push messages.
A subscription is a unique identifier that represents the user's device and browser. It contains:
An endpoint URL provided by the push service
Encryption keys for securing the message payload
Supported content encodings for payload encryption
Creating a Subscription
On client side (Javascript), you can simply send to your server the object you receive using JSON.stringify.
A subscription object will look like:
{
"endpoint":"https://updates.push.services.mozilla.com/wpush/v2/AAAAAAAA[…]AAAAAAAAA",
"keys":{
"auth":"XXXXXXXXXXXXXX",
"p256dh":"YYYYYYYY[…]YYYYYYYYYYYYY"
}
}Understanding the Subscription Components
endpoint: The unique URL where your server sends notifications. Each subscription has a different endpoint.
keys.auth: Authentication secret for message encryption
keys.p256dh: Public key for Elliptic Curve Diffie-Hellman key agreement
Server-Side Processing
On server side, you can get a WebPush\Subscription object from the JSON string using the dedicated method WebPush\Subscription::createFromString.
Supported Content Encodings
By default, the content encoding aesgcm will be used. This encoding indicates how the payload of the notification should be formatted. The PushManager object from the Push API may list all acceptable encodings. In this case, it could be interesting to set these encodings to the Subscription object.
The two standard encodings are:
aes128gcm (recommended): Newer, more efficient encoding defined in RFC 8291
aesgcm (legacy): Older encoding for backwards compatibility
This will result in something like the following:
The order of supportedContentEncodings is important. First supported item will be used. If possible, AES128GCM should be used as preferred content encoding.
Subscription Lifecycle
1. Creation
A subscription is created when the user grants notification permission and your service worker subscribes to push notifications.
2. Storage
Your application server must store the subscription to send notifications later. Store:
The complete subscription object
Associated user information
Creation timestamp (useful for cleanup)
3. Usage
Use the stored subscription to send notifications at any time, even when the user is not on your website.
4. Expiration
Subscriptions can expire for several reasons:
User revokes notification permission
User clears browser data
Push service expires old subscriptions
Subscription endpoint becomes invalid
5. Cleanup
Always handle expired subscriptions:
Remove them from your database when you receive a 404 or 410 error
Implement a strategy to detect and clean abandoned subscriptions
Best Practices
Store Essential Information
Handle Multiple Subscriptions per User
A single user may have multiple subscriptions (different devices/browsers). Store all of them:
Implement Subscription Refresh
If a subscription expires, prompt the user to resubscribe:
Security Considerations
Validate Endpoint URLs: Ensure endpoints are from known push services
Store Securely: Treat subscriptions as sensitive data
Rate Limiting: Implement rate limits to prevent abuse
User Association: Always associate subscriptions with authenticated users
Subscription Uniqueness
Each subscription is unique to:
A specific browser
A specific device
A specific user profile (if the browser has multiple profiles)
A specific origin (your website domain)
This means:
The same user on Chrome desktop and Firefox desktop will have 2 different subscriptions
The same user on desktop and mobile will have 2 different subscriptions
If a user clears their browser data, they will get a new subscription
Testing Subscriptions
Always test your subscription handling:
Performance Optimization
Caching Subscriptions
When sending notifications to multiple users or sending frequently, implement caching strategies to improve performance:
Application-Level Caching
Use your application's cache layer (Redis, Memcached, etc.) to cache subscription lookups:
Doctrine Query Result Cache
If using Doctrine, leverage query result caching:
Batch Loading
When sending to multiple users, load subscriptions in batches to reduce database queries:
Cache Invalidation Strategy
Always invalidate the cache when subscriptions change:
Best Practices for High-Volume Sending
When sending to thousands of users:
Use Background Jobs: Queue notifications for asynchronous processing
Batch Subscriptions: Load subscriptions in batches of 100-1000
Cache Aggressively: Cache subscription lookups for 1-4 hours
Monitor Cache Hit Rate: Aim for >80% hit rate
Clean Up Expired: Remove expired subscriptions immediately to reduce database size
Subscription Lifecycle and Expiration Management
Understanding Subscription Expiration
Web Push subscriptions do not have explicit expiration dates. The subscription JSON from the browser contains no temporal information:
The only way to know a subscription has expired is to attempt sending and receive a 404 or 410 error.
Why Subscriptions Expire
User Revocation - User denies notification permission
Browser Data Clearing - User clears browser data
App/Browser Uninstall - Complete removal
Push Service Policy - Services may expire inactive subscriptions (timeframes vary by provider)
VAPID Key Changes - Changing your VAPID keys invalidates old subscriptions
Tracking Subscription Health
Since subscriptions don't have built-in expiration dates, track metadata at the application level:
Identifying Likely Expired Subscriptions
Use heuristics to identify subscriptions that are probably expired:
Automated Cleanup Strategies
Strategy 1: Clean After Failed Sends
Update subscription status after each send attempt:
Strategy 2: Scheduled Cleanup Job
Run periodic cleanup to remove stale subscriptions:
Strategy 3: Proactive Health Check
Test subscriptions before important campaigns:
Push Service Expiration Policies
Different push services have different expiration policies:
FCM (Google)
60-90 days of inactivity
Mozilla Push
No automatic expiration, but may clean very old inactive subscriptions
Apple Push
~30 days of inactivity
Windows Push
Variable, typically 30-90 days
These are estimated timeframes based on observed behavior. Push services do not publicly document their exact expiration policies, and they may change at any time.
Best Practices
Track Metadata: Always store
createdAt,lastSuccessfulSendAt, andconsecutiveFailuresUpdate After Every Send: Mark success or failure after each notification attempt
Remove Immediately on 404/410: Don't retry expired subscriptions
Use Heuristics: Remove subscriptions with 3+ consecutive failures
Periodic Cleanup: Run a scheduled job weekly to remove stale subscriptions
Monitor Health: Track subscription health scores for analytics
Re-subscription Flow: Make it easy for users to re-subscribe if needed
Example: Complete Subscription Management
Key Takeaway: Web Push subscriptions don't have built-in expiration tracking. Your application must implement tracking and cleanup strategies to maintain a healthy subscription database.
Common Issues
Subscription Not Received
Check that the user granted permission
Verify HTTPS is enabled
Ensure service worker is properly registered
Subscription Immediately Expires
Check VAPID keys match between client and server
Verify the push service endpoint is accessible
Ensure proper payload encryption
Multiple Subscriptions for Same User
This is normal and expected. Users can have multiple devices and browsers.
Next Steps
Learn how to create Notifications to send to your subscriptions
Understand Status Reports to handle delivery results
Set up VAPID authentication for secure sending
Last updated
Was this helpful?