◉RORK LABJP
●EXPO — EAS Observe now records native crashes (Oct 7). On SDK 57, update to 57.0.21 or later●RORK — GPT-6.1 Sol (Sep 29) and Claude Sonnet 5.5 (Sep 28) are now in the model menu●RN 0.88 — The stable release was still unpublished on its Oct 12 target. rc.4 (Oct 7) is the newest; 0.87.1 is Latest●Q&A — Readers report expo-widgets showing a black widget in production builds only●WINDOWS — A walkthrough shows how to ship an iPhone app from Windows only, with no Mac●NEW — Three checks to run first when notifications stop arriving in Expo Go●EXPO — EAS Observe now records native crashes (Oct 7). On SDK 57, update to 57.0.21 or later●RORK — GPT-6.1 Sol (Sep 29) and Claude Sonnet 5.5 (Sep 28) are now in the model menu●RN 0.88 — The stable release was still unpublished on its Oct 12 target. rc.4 (Oct 7) is the newest; 0.87.1 is Latest●Q&A — Readers report expo-widgets showing a black widget in production builds only●WINDOWS — A walkthrough shows how to ship an iPhone app from Windows only, with no Mac●NEW — Three checks to run first when notifications stop arriving in Expo Go
Articles/Business
⟐ Business/2026-04-04Advanced

Rork App Revenue Design: Where Ads and Subscriptions Eat Each Other

How to layer AdMob, subscriptions, and one-time purchases in a Rork app without letting them cannibalize each other. Covers value-density placement, entitlement-first RevenueCat architecture, server-side receipt verification, and behavior-triggered paywalls.

Rork577Monetization38AdMob71Subscriptions16In-App PurchasesRevenueCat30Indie Developer11

✦ Premium Article

The week I increased ad frequency, ad revenue went up. Two weeks later, new subscription signups dropped noticeably.

Net effect: roughly nothing.

Laying the numbers side by side finally made it click. Ads and subscriptions aren't two separate revenue streams. They compete for the same moment in the same user's day. Push one, and the other quietly steps back.

Revenue design isn't about picking a model. It's about finding where the two collide, and drawing a line there before you ship.

Rork gives you an app skeleton in under an hour. That speed is exactly why the line matters — you'll be building on that skeleton for months.


You Don't Pick a Model. You Layer Them.

As long as you're thinking "ads or subscriptions," you're running on one lung. Apps that actually earn almost always layer multiple models.

To layer them well, you need to be clear about who each model takes from, and what they give up in return.

Model Who pays What they trade Works when Fails when
Ads (AdMob) The non-paying majority Attention and time High launch frequency, short sessions Focus-heavy productivity apps
Subscription A committed minority Ongoing value Content grows, sync exists One-and-done utilities
One-time purchase People with one specific gripe Removal of that gripe Ad removal or feature unlock is obvious You need recurring revenue

What the table reveals is that the three models address different people. Ads monetize those who will never pay. Subscriptions monetize those who stay. One-time purchases monetize those who want one annoyance gone, right now.

Layering, then, means never mixing those three groups.

What I keep confirming in my own indie work: aim two models at the same user simultaneously and both underperform. An app that shows you ads while also pressing you to subscribe loses on both counts.

Don't Let One-Time Purchases Collapse Into "Remove Ads"

"Remove ads — $1.99" sells. It's also your subscription's worst enemy.

Someone who pays $1.99 once will never enter your $1.99/month premium tier. The annoyance that would have driven them there no longer exists.

If you ship a one-time purchase, make it a different axis of value, not a cheaper subscription. Fold ad removal into the subscription's benefits, and reserve one-time purchases for things that don't compete with recurring value — buying a single content pack outright, for instance.

Rearranging this later is genuinely painful, because existing purchasers hold rights you can't revoke. Decide it while the skeleton is still warm.


Find the Collision With "Value Density"

So where does the line go?

I think about it as value density: how concentrated is the value the user is receiving on this screen, per unit of time?

  • Low value density (scrolling a list, browsing categories) → where ads belong
  • High value density (they found the wallpaper they wanted, they finished writing an entry) → where the paywall belongs

Swap those two and both break.

Interrupt a high-density moment with an ad and the user reads it as "you cut in right at the best part." That user is no longer a subscription candidate.

Show a paywall during a low-density moment and it reads as "you're asking for money before I've seen what this is worth." That doesn't convert either.

Put differently: ads can burn down your subscription pipeline. Miss that, crank up ad frequency, and you're trading LTV for short-term eCPM.

Implementing the Guard

In code, the ad decision needs to know what moment the user is in.

// Guard that keeps ads out of high value-density moments
type Moment =
  | "browsing"        // list / category selection (low)
  | "previewing"      // examining a detail view (medium)
  | "acquired"        // download or save just completed (high)
  | "returning";      // heading back to the list afterward (low)
 
const AD_ALLOWED: Record<Moment, boolean> = {
  browsing: false,    // don't interrupt exploration
  previewing: false,  // don't interrupt evaluation
  acquired: false,    // this seat is reserved for the paywall. Never an ad.
  returning: true,    // only once the payoff has been felt
};
 
function canShowInterstitial(moment: Moment, isPremium: boolean) {
  if (isPremium) return false;
  return AD_ALLOWED[moment];
}

Setting acquired to false is the whole point. Most apps fire their interstitial right after a download completes. On a revenue-per-impression basis it looks like the best slot available.

It's also the instant the user is most satisfied — which is to say, the instant a paywall would land. Put an ad there and the seat is taken.

Shift one step to returning and you keep the afterglow intact while still showing the ad. In my own apps, making that shift held ad revenue roughly flat while paywall conversion moved up.


✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦Identify the exact point where ads and subscriptions compete for the same user, and learn the value-density rule for drawing the line between them
✦Build RevenueCat entitlement-first with production-ready code, plus a webhook setup that moves receipt verification server-side
✦Understand why paywall conversion is driven by timing rather than copy, and implement behavior-signal gating that proves it
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $15 for lifetime access
View Membership →

Related Articles

⟐ Business2026-05-05
Rork Max × RevenueCat Paywalls SDK: Remote Paywalls, A/B Testing, and Conversion Gains
A complete guide to integrating RevenueCat Paywalls SDK with Rork Max apps — enabling remote paywall updates and A/B testing without App Store reviews, with production-ready code examples and conversion optimization strategies.
⟐ Business2026-04-26
Taking a Rork Max Native App Up the App Store Charts — The Order I Build Ads, StoreKit 2, and Subscriptions
The order I follow to grow a Rork Max SwiftUI app into one that stays near the top of its App Store category: a single AdGate that decides when ads may show, StoreKit 2 Transaction.updates monitoring, and where I draw the lines on ASO and retention — with working code.
⟐ Business2026-04-23
Your First Monetized App With Rork — From Idea to Store to First Revenue
An end-to-end playbook for an indie developer shipping their first revenue-earning app on Rork — covering idea validation, building, store submission, and the first $100.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links