Every holder sets a limit
A message that cannot be delivered right away has to be stored somewhere: on the sending device, on a server, or on a relay in between. Each of those places has finite storage, and each has to decide when a message is no longer worth keeping. So there is rarely one answer to “how long can it wait”. There is a chain of limits, and the shortest one wins.
Limits come from two directions. The sender can say how long the content stays useful, and the holder can say how long it is willing to keep anything. Both are forms of a message TTL, measured in time rather than hops.
Limits the sender sets
Messaging protocols built for unreliable links usually let the sender attach a lifetime.
- MQTT 5.0 has a Message Expiry Interval, the lifetime of the message in seconds. If it passes before the server has started delivering the message to a subscriber, the server must delete that subscriber’s copy. If the property is absent, the message does not expire. When the server does deliver it, it sends the interval minus the time the message spent waiting, so the remaining lifetime travels on.
- The Bundle Protocol (RFC 9171), used in delay-tolerant networks, gives every bundle a lifetime in milliseconds after its creation time. When the bundle’s age exceeds it, nodes need no longer keep or forward it, and it should be deleted.
A holder can still cut a lifetime short. RFC 9171 lets a node impose a shorter overriding lifetime on a bundle whose lifetime is so long that keeping it might degrade the node. The bundle’s own lifetime is not changed, but at that node the shorter one applies, and if it runs out the bundle is deleted for the reason “Traffic pared”.
Limits the carrier sets
Services that store messages for many apps publish their own caps.
- Apple Push Notification service. Apple says that if APNs cannot deliver a notification immediately, it may store it for 30 days or less, depending on the date in the
apns-expirationheader. A value of 0 means APNs tries once and does not store it. Apple also says APNs stores only one notification per bundle ID for a device, so later notifications can replace earlier ones while the device is away. - Firebase Cloud Messaging. On Android and Web, the ttl can be from 0 to 2,419,200 seconds (28 days), and messages without it last up to four weeks. A ttl of 0 means a message that cannot be delivered at once is discarded. Firebase adds that if an Android device has not connected to FCM for more than one month, FCM still accepts messages for it but discards them immediately.
- Email. RFC 5321 says mail that cannot be sent immediately must be queued and retried. The retry interval should generally be at least 30 minutes, and the give-up time generally needs to be at least 4 to 5 days.
| System | Who sets the limit | What the source documents |
|---|---|---|
| MQTT 5.0 | Sender | Message Expiry Interval in seconds; none means no expiry |
| Bundle Protocol v7 | Sender, with node overrides | Lifetime in milliseconds after creation |
| APNs | Sender, capped by Apple | Stored for 30 days or less |
| FCM | Sender, capped by Google | 0 to 2,419,200 seconds, default four weeks |
| SMTP | Each mail server | Give-up time generally at least 4 to 5 days |
None of these is a promise of delivery. Apple calls APNs a best-effort service, and Firebase says a message ID from FCM means the message was accepted for delivery, not that it was delivered.
Limits on the devices themselves
When there is no server in the path, the message waits on a device: first in the sender’s outbox, and sometimes on relaying devices or at the receiver. These queues also need bounds, both on how many messages they hold and on how long each may stay. A message that is still in the outbox when its time runs out has failed, and the app should say so.
The MQTT standard makes the same point about servers: storage has capacity limits and may be subject to administrative policy, and stored state can be discarded by an administrator or lost through hardware or software failure. A lifetime is a ceiling, not a guarantee that the message survives until then.
As one documented example, the Offline Protocol mesh SDK v0.27.0 keeps up to 500 outbox entries with a 7-day lifetime. Its events reference adds a detail: a direct message parked for a recipient known to be offline is re-sent whenever that peer may be reachable again, and fails only at an absolute cap of four times the configured lifetime, about 28 days on the defaults. The SDK also holds messages it cannot yet decrypt in a pending decryption queue with a 24-hour process TTL. Its configuration docs note that retention bounds must cover the expected disconnection.
Choosing how long to wait
Start from the content and the gaps you expect, not from the largest value a system allows.
- How long is the message useful? A call invitation or a one-time code goes stale in minutes. A field report or a chat message may still matter days later.
- How long are devices out of contact? If a recipient can be offline for longer than your expiry, some messages will never be delivered.
- What is the shortest limit on the path? Your own expiry is irrelevant if a push service or relay drops the message sooner. Check each hop.
- What happens at expiry? Decide who is told and whether the message can be resent. A delivery that silently never happens is the hardest failure for users to notice.