Set the lifespan of a message

FCM typically delivers messages immediately after they are sent. However, this might not always be possible. For example, the device could be unavailable orFCM might intentionally delay messages to prevent an app from consuming excessive resources and negatively affecting battery life.

In these cases,FCM stores the message and delivers it as soon as possible. While this is fine in most cases, there are some apps that require notifications to be sent without delay. For example, a notification for an incoming call or an invitation to an event.

On Android and Web, you can specify the maximum lifespan of a message. The value must be a duration from 0 to 2,419,200 seconds (28 days), and it corresponds to the maximum period of time thatFCM stores and attempts to deliver the message. By default, requests that don't contain this field, last for a maximum period of four weeks.

On iOS, you can set theapns-expiration header in theApnsConfigobject. For more details, refer to Apple's documentation onSendingnotification requests toAPNs.

Here are some possible uses for this feature:

  • Video chat incoming calls
  • Expiring invitation events
  • Calendar events

Another advantage of specifying the lifespan of a message is thatFCM doesn't apply collapsible message throttling to messages with a time to live value of 0 seconds. Keep in mind that attl value of 0 means messages that can't be delivered immediately are discarded. However, because such messages are never stored, this provides the best latency for sending notification messages.

Here is an example of a request that includes ttl:

{"message":{"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...","data":{"Nick":"Mario","body":"great match!","Room":"PortugalVSDenmark"},"apns":{"headers":{"apns-expiration":"1604750400"}},"android":{"ttl":"4500s"},"webpush":{"headers":{"TTL":"4500"}}}}

Lifetime of a message

When an app server posts a message toFCM and receives a message IDback, it doesn't mean that the message was already delivered to the device.Instead, it means that it was accepted for delivery. When the message isdelivered depends on many factors.

If the device is connected but in Doze, a low priority message is stored byFCM until the device is out of Doze. If thecollapse_key is set, andthere's an existing message with the samecollapsekey andregistration token waiting for delivery, the old message is discarded and thennew message takes its place. However, if the collapse key is not set, both thenew and old messages are stored for future delivery.

If the device isn't connected toFCM, the message is stored until aconnection is established. When a connection is established,FCMdelivers all pending messages to the device. If the device never gets connectedagain, the message eventually times out and is discarded fromFCMstorage. The default timeout is four weeks, unless thettl flag is set. If theapp has been uninstalled whenFCM attempts to deliver a message to thedevice,FCM discards that message right away and invalidates theregistration token. Future attempts to send a message to that device results inaNotRegistered error.

For Android devices, if the device hasn't connected toFCM for morethan one month,FCM still accepts the message but immediately discardsit. If the device connects within four weeks of the last data message you sentto it, your client app receives theonDeletedMessages()callback.

To get more insight into the delivery of messages on Android or Apple platforms,you can use theFCM reportingdashboard,which records the number of messages sent and opened on Apple and Androiddevices, along with data for impressions for Android apps.

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025-12-11 UTC.