iOS subscription grace periods and billing retry: how Apple handles failed renewals
Involuntary churn from failed payments accounts for a substantial share of iOS subscription losses. Here’s how Apple’s billing retry and grace period systems work — and what developers need to implement correctly to recover subscribers without disrupting their experience.
Most subscription app developers focus on voluntary churn — users who deliberately cancel because they no longer want the product. But there's a quieter category that often accounts for a substantial share of lost subscribers: involuntary churn, where subscribers fail to renew not because they want to leave, but because their payment method failed.
Apple provides two mechanisms to address this: a Billing Retry Period that automatically retries failed payments for up to 60 days, and an optional Billing Grace Period that keeps subscribers active while retries happen. Understanding both — and configuring them correctly — is one of the highest-leverage operational improvements a subscription app can make.
What causes involuntary churn on iOS?
When a subscription renewal fails, the most common culprits are expired credit cards, insufficient funds on debit or prepaid accounts, temporary bank-side blocks on recurring international charges, and hard declines in markets where cross-border payment friction is high. These are transient failures in many cases. The subscriber's underlying intent to pay is still there — they just need Apple to retry at the right moment.
Involuntary churn is structurally different from deliberate cancellations, and treating them the same in your metrics produces misleading retention curves. A subscriber who churned because their card expired is much more recoverable than one who cancelled after a negative experience.
The proportion is higher in markets with prevalent prepaid cards or where international card acceptance rates are lower. RevenueCat's research has consistently flagged payment failure as an overlooked driver of subscriber loss — particularly for apps that have invested in localized pricing for lower-purchasing-power markets (a dynamic explored in depth in our post on iOS subscription churn in low-PPP markets).
The Billing Retry Period: Apple's automatic recovery layer
Regardless of anything you configure in App Store Connect, Apple automatically enters a 60-day billing retry period whenever a subscription renewal fails. Apple retries the subscriber's payment method multiple times during this window using an internal schedule that Apple has not publicly documented in detail.
If a retry succeeds at any point within the 60-day window, the subscription renews. The new billing period begins from the date of successful payment — not from the original renewal date. This means a subscriber who failed to renew on day 1 but whose payment was recovered on day 12 has a 12-day gap in their paid period.
Key implementation detail: Don't treat a billing retry recovery event as a new subscriber for introductory offer eligibility purposes. Apple preserves the original transaction ID throughout the retry window — the subscription history is continuous, not reset.
You can observe billing retry lifecycle events via App Store Server Notifications:
DID_FAIL_TO_RENEW— fires when the initial renewal attempt fails, signalling the start of the retry windowDID_RENEW— fires if payment is recovered at any point during the retry periodEXPIREDwithexpirationReason = BILLING_RETRY— fires after 60 days if no retry succeeded
Without server notifications, your app only learns the subscriber's status when they open the app. For retry events that resolve quietly in the background, server-side webhooks let you update your entitlement database in real time. The authentication setup for App Store Server Notifications uses the same JWT flow as the broader API — see our App Store Connect API JWT walkthrough for the foundation.
The Billing Grace Period: keeping subscribers active during retry
Billing retry handles the payment collection side. But by default, without a grace period configured, subscribers lose access the moment the initial renewal fails — even though Apple is actively retrying. The subscriber opens your app the next morning, gets locked out, and may cancel explicitly or leave a negative review, not realising the issue is temporary. A transient payment failure becomes a permanent churn event.
Apple's Billing Grace Period closes this gap. It's an opt-in feature, enabled per subscription group in App Store Connect, that keeps subscribers active during the retry window up to a fixed maximum duration.
| Subscription Duration | Grace Period | Notes |
|---|---|---|
| Weekly | 6 days | Covers approximately one full billing cycle |
| Monthly | 16 days | Roughly half the billing cycle |
| 2-month | 28 days | Capped at 28 days for all longer durations |
| 3-month | 28 days | |
| 6-month | 28 days | |
| Annual | 28 days | Significant recovery runway for the highest-value subscribers |
During the grace period, the subscriber's transaction data includes a gracePeriodExpiresDate field. Your entitlement check must treat any subscription with a valid gracePeriodExpiresDate in the future as active — even if expiresDate has already passed.
Enabling and implementing the grace period
To enable the grace period, navigate to App Store Connect → Your App → Subscriptions → [Subscription Group] → App Store Billing Grace Period and toggle it on. There are no pricing requirements or eligibility restrictions; any paid subscription group can use it.
On the implementation side, the key signals differ slightly by which StoreKit API you're using:
- StoreKit 2 (recommended): Check
Product.SubscriptionInfo.Status. TherenewalInfoincludesgracePeriodExpiresDate. TheRenewalStateenum value.inBillingRetryPeriodindicates active retry;.inGracePeriodis a distinct state when grace period is active. - Original StoreKit / receipt validation: Inspect
is_in_billing_retry_period(boolean string) andgrace_period_expires_date_msin the latest receipt info JSON returned by the App Store receipt verification endpoint. - App Store Server Notifications v2: The
GRACE_PERIOD_EXPIREDnotification type fires when the grace window closes without payment recovery — at that point, revoke access immediately.
| Scenario | Without Grace Period | With Grace Period |
|---|---|---|
| Payment fails on renewal date | Access revoked immediately | Access continues for grace period duration |
| Subscriber opens app next day | Sees paywall or locked content | Full access, may see soft payment reminder |
| Payment recovered on day 8 (monthly) | Subscriber may have already cancelled | Seamless continuation, no disruption to experience |
| Payment never recovered | Churned on day 1 | Churned at grace period end — same final outcome |
The asymmetry in the table is the core argument for enabling grace periods: the worst case is identical (subscriber churns), while the best case — payment recovered without any disruption — is substantially better.
Avoid aggressive paywalls during grace periods. Showing a hard paywall on every app launch while a subscriber is in grace period — even as a "gentle reminder" — often prompts them to cancel deliberately, converting an involuntary churn event into a voluntary one. A single, dismissible banner or a notification is sufficient. The subscriber's card will be retried regardless of in-app messaging.
Connecting grace periods to your broader retention workflow
Billing retry and grace periods operate upstream of your deliberate winback mechanics. The sequencing matters for deciding when to deploy each retention tool:
- Grace period active: Keep the user in-product with a soft in-app payment update prompt. Don't deploy a promotional offer yet — the subscription may recover at full price.
- Grace period expired, billing retry still running (up to day 60): The subscriber has lost access but Apple is still attempting recovery. This is the right window for a push or email campaign prompting them to update their payment method. A discounted promotional offer can incentivise re-engagement before the retry window closes.
- Billing retry exhausted at day 60: Full involuntary churn. Treat identically to a voluntary cancellation for winback campaign purposes.
For teams tracking subscription health across markets — especially those using AppsOps pricing dashboards to monitor territory-level performance — separating involuntary churn from voluntary churn in your analytics is important for diagnosing the right problem. High involuntary churn in a specific territory often points to payment infrastructure friction, not product dissatisfaction. Phiture and other mobile growth consultancies have noted that markets with high prepaid card penetration in Southeast Asia and Latin America tend to see disproportionately high involuntary churn rates, making grace period configuration especially impactful in those regions.
Common implementation mistakes
Checking only expiresDate for entitlement decisions. This is the most common error. If your access check simply compares expiresDate to the current timestamp, you'll revoke access on payment failure even when the grace period is active. Always check gracePeriodExpiresDate as a secondary condition.
Not subscribing to App Store Server Notifications. Without server-side webhooks, your entitlement database only updates when the user opens the app. A subscriber whose payment recovers at 3am won't see their access restored until their next session — and may have cancelled in the interim. Server notifications make recovery nearly real-time.
Resetting introductory offer eligibility on retry recovery. When Apple recovers a payment during billing retry, it does not create a new original transaction. The subscriber's history is continuous. Resetting intro offer eligibility based on a recovery event would incorrectly offer discounted re-entry to an existing paying subscriber.
Forgetting to enable the grace period per subscription group. The grace period is toggled at the subscription group level in App Store Connect, not globally. If your app has multiple subscription groups (e.g., separate groups for monthly and annual tiers), you need to enable it in each group individually.
Sources and further reading
- Apple Developer: App Store subscriptions overview
- Apple Developer Documentation: StoreKit framework
- Apple Developer Documentation: App Store Server Notifications
- App Store Connect Help: managing subscriptions and billing
- RevenueCat Blog: iOS subscription growth and retention research
Share this post
Ready to put this into practice?
AppsOps is the first App Store ops dashboard — PPP-fair pricing for 175 App Store territories, AI metadata localization in 39 languages, AI screenshot localization for 14 Apple device classes, and one-click App Store Connect API push — all from one dashboard, all for $19/month.
Try AppsOps free — no card →