App-owned messaging workshop / 6 MIN READ
Release the push campaign without turning retries into a second burst
Create a bounded send ledger and retry policy that preserves message validity and prevents avoidable repeat submissions.
AI-assisted research and analysis for the SNS Creative Fieldbook
Sources checked 2026-11-07
A retry is another attempt to submit a request, not evidence that the first attempt failed to reach the user. Campaign operations must separate accepted requests, uncertain outcomes and explicit rejections before scheduling more traffic.
What you will leave with: Create a bounded send ledger and retry policy that preserves message validity and prevents avoidable repeat submissions.
Use this when
- A push campaign is sent through a provider API at scale.
- The sender experiences throttling, timeouts or partial batch failures.
Not an exactly-once delivery guarantee or permission to bypass user controls with another channel or priority.
Classify the outcome before choosing the next action
Firebase recommends paced sending and bounded retry behavior, including honoring Retry-After where applicable and using exponential backoff with jitter. Its error documentation distinguishes invalid requests, unregistered targets, quota failures and temporary server failures. The exact response and details matter; one generic failed status is not enough to choose a safe action.
Keep separate states for confirmed provider acceptance, explicit retryable rejection, terminal rejection and uncertain outcome. A timeout can mean the client never learned the result; it does not prove nonexecution. Have engineering document what evidence can resolve uncertainty and what duplicate risk remains if another request is sent. Never promise that a campaign identifier alone causes the provider to deliver exactly once.
Define the ledger before the launch
For each intended send, record a synthetic or appropriately protected internal target reference, campaign version, submission attempt, timestamp, response classification and next permitted action. Keep registration tokens and credentials out of public worksheets and logs intended for creative review. The ledger's purpose is to prevent the orchestration layer from treating every unfinished row as a fresh audience member.
Agree how a partially completed batch resumes. Confirmed accepted rows should not be blindly resubmitted because another row failed. Terminal errors need correction or removal from the applicable send set, not an infinite retry loop. A corrected payload is a new controlled attempt with a recorded reason; it should not erase the history that explains why the first request was rejected. Assign one owner to approve recovery when the outcome is uncertain.
Bound retries by both load and meaning
Ask the implementation owner to apply the current provider-specific retry guidance to each response class. Firebase documents waiting for throttling instructions and backoff for temporary failures rather than immediate repeated requests. Set an overall stop condition so retries cannot continue after the message is no longer useful. The shortest relevant commercial deadline may be much earlier than a technical retry maximum.
Recheck current eligibility before a permitted retry. The user may have opted out, the offer may have ended or the desired action may already be complete. Do not switch channel, increase priority or create a new route to overcome these controls. Spread recovery traffic rather than releasing every queued retry at once. Existing SDK retries and application-level retries must be understood together so they do not multiply each other unexpectedly.
Rehearse partial failure and a controlled stop
Use a simulated response set containing acceptance, an explicit temporary rejection, an invalid request and a timeout with unknown outcome. Walk the ledger through its next decisions without sending to real customers. Check that stopping the campaign prevents new attempts and that resuming it does not restart the entire audience. Also test a retry whose scheduled time crosses the offer expiry.
For a live approved release, use the staged rollout and pacing plan agreed with engineering, observing technical health before expanding. A stop prevents future submissions; it is not a guarantee that accepted messages can be recalled. Report accepted, rejected, uncertain and abandoned attempts separately. The operational success is a controlled recovery with explainable decisions, not a claim that all intended recipients saw one and only one notification.
Make the reasoning concrete.
A fictional bookstore sender submits a small promotional batch. Some requests are accepted, some receive throttling responses, one contains an invalid field and several time out before a response is recorded.
Resend the entire batch
Opening: Treat every incomplete job as failed and start again immediately.
Hypothesis: The queue may appear to clear faster.
Risk: Already accepted requests can be repeated and recovery traffic can worsen throttling.
Recover by outcome class
Opening: Preserve accepted rows, correct terminal defects, pace permitted retries and isolate uncertain outcomes.
Hypothesis: Every further attempt has an explicit reason and validity check.
Risk: Some uncertain requests may remain unresolved rather than being blindly repeated.
The bookstore uses the outcome ledger and a stop deadline. It accepts that uncertainty cannot be converted into an exactly-once promise and does not retry after the promotion ceases to be valid.
Take the questions into your next brief.
Use these prompts in your own notes. Nothing is submitted from this page.
Classification
Is the result accepted, retryable, terminal or uncertain?
Evidence
What proves the previous request outcome, if anything?
Pacing
Which provider instructions and SDK retries govern the next attempt?
Validity
Is the message still useful and the target still eligible?
Stop
How does the sender halt new attempts without restarting accepted rows?
Watch for the wrong conclusion.
- Treating a timeout as proof of nonexecution.
- Retrying accepted and terminally rejected rows with transient failures.
- Ignoring SDK retries or retrying after the offer expires.
Your next action
Rehearse a four-outcome synthetic batch and document the next permitted action for every row.
Sources & scope
Workflows, worksheets and fictional examples are original editorial analysis, not supplier implementation instructions or measured business results. Sources support only the specifically attributed platform facts. Supplier controls, contracts and local requirements can change; verify the actual placement and current provider guidance before implementation.
- Firebase: Best practices when sending FCM messages at scale →Primary platform documentation · Supports: Supports paced rollout, retry amplification, backoff/jitter, Retry-After and bounded retries; outcome ledger and uncertainty decisions are editorial.
- Firebase: FCM error codes →Primary platform documentation · Supports: Supports HTTP v1 response-detail interpretation and retryable versus terminal error distinctions, not exactly-once delivery.