Subscription pricing isn't about picking a single number; it's a system where price, duration, and package are designed together. A poorly built trial length or an incomplete tier structure punishes even a great product with low conversion. This piece walks through how to design your subscription pricing strategy, your paywall trial decision, and the App Store/Play Store's official offer mechanisms (introductory, promotional, win-back, offer code) by app type.
💡 Pro Tip: Decide which offer type you'll use (introductory or offer code) before you set the price — because on Apple and Google, every offer type has different duration, repeatability, and target-audience constraints, and those constraints shape the price decision retroactively.
Table of Contents
- The Three Variables of Pricing: Price, Duration, Package
- Price Point
- Duration
- Package
- Monthly/Yearly/Lifetime Tier Design
- Trial Length Decision
- Offer Types: Introductory, Promotional, Win-Back, Offer Code
- Introductory Offer
- Promotional Offer
- Offer Code
- Win-Back Offer
- The Android Side: Play Billing Base Plan and Offer
- Regional Pricing and the Local-Currency Decision
- Price Changes and Increases: Impact on Existing Subscribers
- Price Decreases and Increases on Apple
- Price Changes on Google Play
- Metrics to Track: Trial→Paid, Churn, LTV
- Decision Guide: Starting Package by App Type
- FAQ
- How should I decide my subscription price?
- How many days should the free trial be?
- Where in onboarding should I place the paywall?
- How do you run a price test on the App Store?
- Can an introductory offer and an offer code be applied back-to-back to the same user?
- Conclusion
- Sources
The Three Variables of Pricing: Price, Duration, Package
The subscription pricing decision is the intersection of three independent variables: price point (the amount the user pays), duration (trial, billing period, offer length), and package (which features sit in which tier). These three aren't optimized separately — they're tested together.
Price Point
App Store Connect offers 800 price points across all currencies and price tiers, plus 100 additional high price points on request. So "$9.99 or $12.99" actually has hundreds of possible answers — the decision is narrowing a range based on competitor analysis and target LTV, not picking a random number.
Duration
The duration variable isn't just "monthly or yearly"; trial length, offer length, and billing period are all set independently. In Apple's pay-as-you-go discount type, for example, a subscription with a standard renewal price of $9.99/month could apply $1.99/month for 3 months, then revert to the standard price. Each of these three decisions — price, discount rate, duration — pulls paywall conversion in a different direction.
Package
The package decision determines which feature stays in the free tier and which stays in the paid tier. This piece focuses more on the price/duration axis than on in-package feature distribution; how the paywall screen itself is designed (button placement, social proof, comparison table) is a separate topic — I cover that in paywall design and subscription conversion.
Monthly/Yearly/Lifetime Tier Design
Most subscription apps offer two tiers, monthly and yearly; some add a lifetime (one-time) option. The commercial logic of these three models differs:
- Monthly: Low entry barrier, high churn risk. The user re-decides every month.
- Yearly: Upfront collection, brings LTV forward but grows the risk of post-cancellation refund expectations (App Store/Play refund policies).
- Lifetime: Doesn't create recurring revenue; it's used only to capture the user segment that prefers a one-time payment (users who don't trust subscriptions, who say "let me pay once and be done") — most subscription-first apps offer it as a side option, not the main offer.
The decision isn't binary here: the monthly/yearly price ratio (how many months the yearly price divided by the monthly price equals) determines which package looks "more advantageous" to the user. Putting a comparison line under the yearly package on the paywall screen, like "X months free compared to monthly," is a common practice, but its design is the subject of paywall design and subscription conversion.
Trial Length Decision
On Apple, free trial length can be set to 3 days, 1 week, 2 weeks, 1 month, 2 months, 3 months, 6 months, or 1 year — a fixed list; in-between values (e.g., 10 days) aren't supported. The purchase flow must clearly state the trial length and the price charged once it ends.
Three factors determine the trial length decision:
- Time to show value: The minimum time the user needs to experience the product's core benefit (e.g., a week of habit tracking, a month of language-learning progress).
- Alignment with the billing cycle: A 3-day trial for a weekly product, or a 1-week trial for a monthly product, builds a more consistent "trial → first charge" story.
- Cancellation friction: A longer trial increases the chance the user "forgets" and pays the first charge, but it can also raise the share of users who cancel within the first week, because the decision gets made before value is seen.
This decision sits only on the price/duration axis — how the trial is presented on the paywall screen (before or after, card-based or list-based) is left to paywall design and subscription conversion.
Offer Types: Introductory, Promotional, Win-Back, Offer Code
Apple's App Store Connect has four separate offer mechanisms; each targets a different user segment under different constraints. For how to handle these in code with StoreKit 2, see Modern In-App Purchase with StoreKit 2 and StoreKit 2 Production Guide; the App Store Connect-side setup is in App Store Connect Subscriptions: Offer Codes, Family Sharing, Winback. Here I focus only on their pricing-strategy differences.
Introductory Offer
Lets new subscribers experience the subscription before paying full price. The constraint is clear: a customer can use an introductory offer only once per subscription group — switching to a different plan in the same group doesn't grant a second intro price. So "re-offer the intro price at every new launch" won't work.
Promotional Offer
Offers current or former subscribers a free or discounted price for a limited time, according to business logic the developer defines. Up to 10 active promotional offers can be defined per subscription. Typical use cases: a special price on an upgraded subscription for a subscriber who canceled, a free month for a loyal subscriber who's been renewing for a long time, or a discounted month for a subscriber with irregular usage.
Offer Code
Offer codes are alphanumeric codes usable on the App Store or in-app, and come in two forms: one-time-use 18-digit codes, or custom codes like "SPRINGPROMO." Use cases include email campaigns, printed materials, business partnerships, customer-service remediation, and old-app-to-new-app migration campaigns. A code can also be distributed by linking it to a URL in the format https://apps.apple.com/redeem?id=AppAppleID&code=OfferCode.
Win-Back Offer
Makes it easier to reach former subscribers whose subscription has expired and who've turned off auto-renew. This offer can be discovered on the App Store product page, on an automatic in-app offer page, in the user's Apple account subscription settings, or via a direct link (e.g., email). When you set up a win-back offer in App Store Connect, you define the offer details and the offer priority (which one shows first if there are multiple win-back offers).
Offer Type | Target Audience | Core Limit | Constraint Source |
|---|---|---|---|
Introductory Offer | New subscriber (never tried) | Once per subscription group | Apple Developer — App Store Subscriptions |
Promotional Offer | Current or former subscriber | Up to 10 active offers per subscription | App Store Connect Help — Pricing and Availability |
Offer Code | New, current, or former subscriber | One-time-use 18-digit or custom code | Apple Developer — App Store Subscriptions |
Win-Back Offer | Former subscriber, expired + auto-renew off | Priority order defined in App Store Connect | Apple Developer — App Store Subscriptions |
1{2 "offerTypes": {3 "introductory": {4 "limit": "once per subscription group",5 "discountTypes": ["pay_as_you_go", "pay_up_front", "free"],6 "freeTrialDurations": ["3d", "1w", "2w", "1mo", "2mo", "3mo", "6mo", "1y"]7 },8 "promotional": {9 "limitPerSubscription": 10,10 "audience": "current or former subscriber"11 },12 "offerCode": {13 "codeTypes": ["one_time_use_18_digit", "custom_code"],14 "redeemUrl": "https://apps.apple.com/redeem?id={appleId}&code={offerCode}"15 },16 "winBack": {17 "audience": "expired + auto-renew off former subscriber",18 "config": "priority order set in App Store Connect"19 }20 }21}The Android Side: Play Billing Base Plan and Offer
On Google Play, the equivalent mechanism is the base plan + offer structure: multiple configurations are defined for the same subscription product — for example, an introductory offer for users who've never subscribed, and a separate upgrade offer for existing subscribers. How this is handled in code is covered in Google Play Billing Library v7: Android Subscription 2026; the cross-platform (single SDK for iOS+Android) approach is in RevenueCat Cross-Platform Subscription.
An important compliance note: as of August 31, 2026, all new apps and updates must use Play Billing Library v8 or higher; an extension can push the deadline to November 1, 2026. Since that extra window has also closed, building a pricing/offer architecture on a below-v8 version isn't recommended for new projects.
1// Play Billing: conceptual relationship between base plan + offer (read via queryProductDetails)2val subscriptionOfferDetails = productDetails.subscriptionOfferDetails3subscriptionOfferDetails?.forEach { offer ->4 val basePlanId = offer.basePlanId // e.g. "monthly-base"5 val offerId = offer.offerId // null means the base plan itself (no offer)6 val pricingPhases = offer.pricingPhases.pricingPhaseList7 // pricingPhases: introductory phase(s) + the standard renewal phase, in order8}Price-change management is also done programmatically via the API: a monetization.subscriptions.patch call sets the new price inside the RegionalBasePlanConfig object under the basePlans collection. Moving existing subscribers to the current price (they aren't moved by default — they stay in the "legacy price cohort") requires a separate call: monetization.subscriptions.basePlans.migratePrices. The practical outcome: updating the price with patch doesn't affect existing subscribers; moving them requires a separate, deliberate migratePrices call.
Regional Pricing and the Local-Currency Decision
App Store Connect's pricing tool helps you manage prices based on current exchange rates. When a region's tax or currency changes, the subscription price generally doesn't change automatically — reflecting that is the developer's decision. The critical point: don't change a price without knowing which markets are priced tax inclusive. Lower the price in Germany, for example, and the revenue you actually receive is calculated after deducting EU VAT and Apple's commission — so the on-screen price and what lands in your pocket don't move by the same ratio.
For a local-currency (e.g., Turkish Lira) pricing decision, the practical approach is these three steps:
- Pick a reference market — usually the US price is used as the base, and the local price is kept close to the tier App Store Connect's automatic currency matching suggests.
- Review purchasing-power parity — App Store Connect's pricing tool produces a recommendation based on current exchange rates ("The App Store Connect pricing tool can help you manage pricing based on current exchange rates"); you're not locked into that recommendation for your local price — you can manually pick the tier that fits the local market from the 800 price points.
- Confirm the tax regime — Schedule 2 of the Apple Developer Program License Agreement defines regions with different tax regimes; don't assume a percentage for the net-revenue calculation on your local price without checking that table.
1Local-currency price decision flow (price/duration axis — package content is outside this step)21. Pick a reference price point (e.g., US tier)3 → App Store Connect / Play Console suggests the automatic local-currency equivalent42. Decision on deviating from the ASC suggestion: lower the tier for local purchasing power? (yes/no)5 → if yes: step down from the suggested local price to the local tier63. Check the tax regime (is it tax inclusive?)7 → net revenue = on-screen price − local VAT − platform commission84. Publish the price, note the cohort impact (see next section: impact on existing subscribers)A similar logic applies on the Play side: regional price is defined separately via RegionalBasePlanConfig, and the price-change API call (monetization.subscriptions.patch) expects a top-level region code (e.g., "US") for the region parameter — a sub-region/territory code (e.g., "PR") causes an error.
Price Changes and Increases: Impact on Existing Subscribers
Raising a price can't be separated from how it lands on existing subscribers. Apple and Google define different but clear rules here.
Price Decreases and Increases on Apple
When a price is lowered, existing subscribers automatically renew at the new, lower price — there's no option to keep the higher price, no notification is sent to the subscriber, and no action is required.
When a price is raised, Apple automatically informs subscribers via push notification, email, and an in-app message. Some increases require the subscriber's opt-in consent (explicit acceptance); for small and infrequent increases, a notification alone is enough and no consent is requested. In cases where consent is required, if the subscriber doesn't accept, the subscription ends at the end of the current billing cycle.
The developer can keep an unlimited number of existing subscribers at their old price and apply the higher price only to new ones — Apple gives a direct example: 2024 subscribers keep paying $3.99, the 2023 cohort $2.99, the 2022 cohort $1.99. To consolidate multiple cohorts into one price, start from the cohort closest to the current price (e.g., $2.99→$3.99 first, then the next-closest) — Apple's rationale is clear: that way the same subscriber never experiences more than one price increase.
Price Changes on Google Play
The logic on Play is built a bit differently: the default behavior on a price increase is to leave existing subscribers in the "legacy price cohort" — even after you change the price, they stay at the old one unless you separately call migratePrices.
- Opt-in increase (default): The user must explicitly accept the new price. The notification process starts 37 days in advance, automatic notifications kick in 30 days before the first renewal; if the user doesn't accept, the subscription is automatically canceled.
- Opt-out increase: Offered only in certain countries and subject to amount/frequency limits; unless the user cancels, the new price is charged, with a notification period of 30 or 60 days depending on the country.
- Price decrease: Users are notified by email, and the new (lower) price applies at the next renewal.
1Play Developer API — a price change requires TWO SEPARATE calls (conceptual flow, real method names):2 31) monetization.subscriptions.patch4 → The new price is set inside RegionalBasePlanConfig under the "basePlans" collection.5 → Does NOT affect existing subscribers; only applies to the new purchase flow.6 72) monetization.subscriptions.basePlans.migratePrices8 → Moves existing subscribers to the current price; the region parameter must be a TOP-level9 region code (e.g., "US") — a sub-region/territory code (e.g., "PR") causes an error.10 → This call automatically triggers the user-facing price-change notifications.The practical outcome: updating the price with patch doesn't affect existing subscribers; moving them requires a separate, deliberate migratePrices call.
Metrics to Track: Trial→Paid, Churn, LTV
The work isn't done once you've made the price/duration/package decision — track a handful of metrics to confirm it was right. I'm not giving ready-made industry averages here; each team fills this in with its own data:
- Trial→paid conversion rate: What share of trial users pay the first charge — the most direct signal of whether the trial length was "enough to show value."
- Churn rate: Share of users leaving monthly/yearly. A low opt-in rate after a price increase (i.e., if few subscribers make it through Apple/Google's notification mechanism) flows directly into churn.
- LTV (lifetime value): Billing period × average subscription length × net price (after commission and tax). Watch which direction it moves when you change the yearly/monthly ratio — that's the core signal.
- Price cohort distribution: After an increase, how many stayed at the old (legacy/grandfathered) price, moved to the new one, or left. Apple's gradual-increase advice (start from the closest cohort) exists to manage this distribution.
None of these metrics decides anything on its own — if trial→paid is high but churn is also high, the problem may not be the trial; it may be the package content or the price/value perception.
Decision Guide: Starting Package by App Type
The table below summarizes which price/duration/offer combination is a more consistent starting point by app type — not a hard rule, just a framework for thinking through the three variables together.
App Type | Billing Priority | Trial Approach | Featured Offer Type |
|---|---|---|---|
Habit/productivity (daily use) | Yearly featured | Short trial (3-7 days) — value seen quickly | Introductory offer (lowers the first price barrier) |
Education/language learning | Monthly + yearly together | Medium trial (1-2 weeks) — progress must be seen | Promotional offer (discount at a progress milestone) |
Niche/professional tool | Yearly-weighted, lifetime optional | Feature-limited free tier instead of a trial | Offer code (affiliate sales, launch campaign) |
Social/community | Monthly-weighted | Short trial or trial-less freemium | Win-back offer (recovery after churn) |
This table is only a starting point — the final decision should be validated with your own trial→paid and churn data.
GOLDEN TIP
The most valuable insight in this article
This tip holds the article's most important takeaway.
Easter Egg
You found a hidden gem!
There's a hidden detail in this section. Want to uncover it?
Reader Reward
I put together a single-page checklist that pulls together the decisions covered in this article — use it when making a price/duration/package decision or before reviewing a price increase.
FAQ
How should I decide my subscription price?
Set the price as a trio, not a single number: reference market + price point + regional parity. On App Store Connect you choose from 800 price points (plus 100 on request); don't fix a local price with a raw currency conversion — check purchasing-power parity and the tax regime instead. Use competitor prices and target LTV to narrow a range, then test within it.
How many days should the free trial be?
The fixed durations you can pick on Apple are 3 days, 1 week, 2 weeks, 1 month, 2 months, 3 months, 6 months, and 1 year — you can't choose an in-between value (e.g., 10 days). Base the decision on the minimum time a user needs to experience the product's core benefit: a short trial (3-7 days) is more consistent for daily-habit products, a medium trial (1-2 weeks) for products that require progress (like language learning).
Where in onboarding should I place the paywall?
That's a separate design question from the price/duration decision — the paywall's placement, button layout, and flow decision are the subject of paywall design and subscription conversion. This article only covers which price/duration/offer to show on the paywall, not where the screen sits.
How do you run a price test on the App Store?
App Store Connect's official documentation doesn't define a native A/B price-testing tool — the pricing tool suggests a price based on the current exchange rate and lets you choose among price points, but it doesn't run automatic cohort tests. To test prices in-app, you typically build that manually through third-party subscription-management SDKs (e.g., RevenueCat's cross-platform setup) by showing different price points to different segments — Apple doesn't offer this natively.
Can an introductory offer and an offer code be applied back-to-back to the same user?
No — an introductory offer can be used only once per customer per subscription group; even switching to a different plan in the same group doesn't grant a second introductory price. An offer code is a separate mechanism with different constraints (one-time-use or custom code, validity defined in App Store Connect) — without mixing the two up, you need to clearly separate which offer targets which segment (new subscriber vs. a former subscriber you're trying to win back).
Conclusion
Subscription pricing is a system where price point, duration, and package are designed together — not a one-time exercise but one you keep revisiting. Apple's introductory/promotional/offer code/win-back quartet and Google's base plan + offer architecture are the official ways to implement these decisions technically — but your trial→paid and churn data determine which offer to use and when. Staged cohort transitions on price increases, checking the tax regime for regional pricing, and separating offers by segment: that's the core framework here.
To go deeper on the technical implementation side, see Modern In-App Purchase with StoreKit 2, StoreKit 2 Production Guide, App Store Connect Subscriptions: Offer Codes, Family Sharing, Winback, and Server-Side Receipt Validation; for the paywall screen's design, see paywall design and subscription conversion.
Sources
- Auto-Renewable Subscriptions — App Store, Apple Developer — introductory/promotional/offer code/win-back offer definitions, price points, price-change rules.
- In-App Purchase and Subscriptions Pricing and Availability — App Store Connect Help — number of price points, offer duration limits, trial duration list.
- Subscriptions Overview — Google Play Billing — base plan + offer architecture, Billing Library v8 requirement timeline.
- Change Subscription Prices — Google Play Billing — opt-in/opt-out increase rules, the migratePrices API, legacy price cohort behavior.
- Offer Codes Announcement — Apple Developer News — offer code redemption URL format and use cases.
Tags
iOS Development News
Weekly Swift tips, SwiftUI tricks and iOS best practices. No spam, only valuable content.
Your subscription starts when you open the link in the confirmation email and press “Confirm my subscription”. The newsletter keeps open/click statistics; you can unsubscribe anytime with one click. Privacy
