How do you go from 13 services at $49/month to 7 services at $0/month — and what happens if this thing actually grows?
Part of the ForkIt! Case Study. Back to the case study →
"As free as possible" is not a business model. It is a constraint that forces better architecture, better caching, and better decisions about what to build.
The constraint didn't make the app successful. It made the architecture honest. Every feature that exists earned its place by answering "does this need to cost money?" first.
V3: 13 services, ~$49/month
| Google Places API | ~$49/mo |
| Vercel (hosting + serverless) | Free tier |
| Vercel KV (Redis) | Free tier |
| Clerk (auth) | Free tier |
| Neon (Postgres) | Free tier |
| RevenueCat (IAP) | Free tier |
| Sentry, GitHub, ImprovMX, Expo | Free tier |
| Apple + Google + domain | ~$12/mo amortized |
| Total | ~$49/mo + fixed |
V4: 7 services, $0/month
| Google Places API | $0 (within free cap) |
| Vercel (hosting + serverless) | Free tier |
| Vercel KV (Redis) | Free tier |
| Sentry, GitHub, ImprovMX, Expo | Free tier |
| Apple + Google + domain | ~$12/mo amortized |
| Clerk, Neon, RevenueCat | Removed |
| Total | $0/mo variable |
V4 asked: "Does this service serve sustainability or conversion?" At fewer than 100 users, the answer for auth, database, and purchase middleware was: neither. Clerk was removed (no accounts needed). Neon was removed (local storage + export/import). RevenueCat was removed (react-native-iap talks to stores directly). The API cost dropped from $49/month to $0 by switching free users from Enterprise field masks to Pro field masks (same data the user sees, different billing tier).
V4 Phase 1 shipped in late March with a tier-split prediction: route free users to Pro field-mask billing, gate filters that require Enterprise fields behind a paid tier, and cut billable Enterprise calls by ~95%. The first full month post-V4 was April. The Google billing report makes the verdict simple.
| Q1 2026 vs April 2026 (Google Billing CSV) | |
| Q1 2026 (pre-V4) Nearby Search Enterprise | 7,374 calls |
| Q1 2026 net (after trial credit) | $176.75 |
| April 2026 Nearby Search Enterprise | 132 calls |
| April 2026 Nearby Search Pro | 623 calls |
| April 2026 net | $0.00 |
Free users now route to the cheaper Pro field mask. April fell entirely within Google's free monthly cap. The break-even target dropped from ~42 subscribers to effectively zero. Every paid subscriber is pure margin after API cost.
Google Places is the only real cost. And it cost more than expected.
The LLM stated that Google Maps Platform included a $200/month free credit. Architecture decisions, cost projections, and the free tier design were all built on this assumption. The credit had been eliminated over a year before the project started. The LLM's training data was stale. Every cost calculation based on that number was wrong.
On top of that, Nearby Search and Text Search hit Enterprise SKU pricing (higher per-call costs than the Basic endpoints used for simple geocoding). The app was hitting the most expensive tier of an API with no credit to offset it.
Lesson: never trust LLM pricing knowledge. Verify vendor pricing pages directly before making cost-driven architecture decisions.
The single biggest cost optimization in the entire app. One architectural decision that turns dozens of potential API calls into one.
User taps "Fork It" for the first time. No cache exists yet. The app calls Google Places API and fetches a full pool of 20+ restaurants matching the current filters.
Cost: ~$0.032
User doesn't like the suggestion. Taps again. The app picks a different restaurant from the same cached pool. No API call. No cost.
Cost: $0.00
Every re-roll picks from the local pool. A user could tap 50 times and it's still one API call. The pool doesn't expire for 8 hours.
Cost of 50 re-rolls: $0.032 total
User changes a filter (different cuisine, different radius, different price range). The cached pool no longer matches. A new API call fetches a fresh pool.
This is what counts as a "search" against the free tier limit.
Without pool caching, a user who taps 10 times costs $0.32. With it, they cost $0.032. That is a 10x cost reduction from one architectural decision.
A casual user who searches once and re-rolls a few times costs the same as a single API call. The caching makes the free tier viable.
Multiple layers of optimization reduce per-search cost further.
Cache TTL evolved from 1hr → 3hr → 8hr as usage patterns showed restaurant data doesn't change mid-meal-decision.
Pro exists to offset API costs, not as a revenue model. The goal is sustainability, not growth-at-all-costs.
v2 launched with two tiers. The margin problem became obvious immediately.
Free users got 20 searches and cloud sync. Pro ($1.99) got unlimited everything. The problem: every user (including free users) hit Neon, Clerk, and the backend for sync. A power Pro user who searched 50 times a month cost ~$1.60 to serve and paid $1.69 net. That is a $0.09 margin on the most engaged users.
The users who cost the most paid the same as the users who cost the least.
The fix: align cost with revenue. Cloud sync (the most expensive feature to serve) moved behind Pro+. Free tier limits tightened to reduce API spend per non-paying user.
A "search" = a new API fetch. Re-rolls from the cached pool are free and unlimited. Managed through react-native-iap, communicating directly with Apple and Google stores. No third-party purchase server.
Free tier limits are tracked per-device via AsyncStorage with monthly resets, not per-account (accounts were removed in V4). A determined user could bypass them by clearing app data or reinstalling. At ~100 users and $1.99/month, the incentive to game it is near zero. But the architecture doesn't scale.
Server-side usage tracking (keyed by device ID or fingerprint) is the obvious fix. The question is when the risk justifies the complexity. Right now, the answer is: not yet. The cost of a handful of users gaming the free tier is less than the cost of building and maintaining server-side enforcement.
Every free tier has a ceiling. Here is where each service hits its limit, and what it costs to cross.
Swipe or use arrows
| Cost per casual user (5 searches/month) | ~$0.05 |
| Cost per active user (20 searches/month) | ~$0.20 |
| Cost per power user (50+ searches/month) | ~$0.50 |
| Revenue per Pro subscriber (after store cut) | ~$1.69 |
| Breakeven per Pro user | ~3 searches/month |
Revenue per subscriber assumes Apple/Google's 15% small business cut (under $1M annual revenue): $1.99 x 0.85 = $1.69. Multi-layer caching (8-hour server Redis, 8-hour client pool, mode-aware location grid) drives per-user costs down ~3x compared to simple pool caching alone. Most searches in populated areas hit cache, making even power users profitable.
When Google API costs became the dominant variable, the obvious question was: can we use something cheaper? The answer required evaluating every alternative against the features users actually depend on.
Foursquare: Has ratings, but they're algorithmic (based on check-in traffic), not user reviews. Many restaurants (especially outside major metros) have no rating at all. The fields ForkIt needs (rating, price, hours) are all "Premium" tier: $18.75/1,000 calls with zero free tier. Their V3 API is also being deprecated May 2026. OSM/Overpass: Free and unlimited, but no ratings, no price level, no real-time "open now." HERE: Generous free tier (250K calls/month) but also lacks ratings. Apple MapKit: Free, but no ratings, and would require managing separate iOS/Android search paths. The Group Fork feature merges filters server-side, making a platform split impractical.
The conclusion: when a user sets "4 stars and up," that filter has to work. Only Google provides reliable restaurant ratings at scale. The cost strategy is "fewer Google calls," not "different provider." Every cache optimization exists because of this constraint.
7 services. Most on free tiers. Google already killed its $200/month API credit without warning (March 2025). The remaining dependencies: Vercel, Google Places API, Sentry, Redis (Vercel KV). Any of them could change pricing or terms.
How does a solo dev build resilience against platform risk when every alternative means rebuilding? The answer, right now, is: you don't. You monitor, you keep alternatives in mind, and you accept that the free tier is rented ground. The 31-review suite includes Review 25 (Dependency Health) for exactly this reason, but a review can flag the risk. It can't eliminate it.
Update (March 2026): A full evaluation of Foursquare, OSM, HERE, and Apple MapKit confirmed that Google lock-in for restaurant data is real; no alternative provides the ratings and price data that ForkIt's filters require. The mitigation isn't to switch providers but to minimize call volume through aggressive, mode-aware caching. The research is documented in the project's issue tracker for future revisiting as the market evolves.
The goal is not profit. The goal is: this app should not cost money out of pocket to keep running. Break even is the floor. Everything above that is a bonus.
Each tier is designed so the features that cost the most to serve are behind the tier that charges the most. Here is what each tier costs to operate.
Cost to serve: ~$0.32/mo
No database load
Cost to serve: ~$0.96/mo
Net: $1.69. Margin: $0.73
Cost to serve: ~$2.00/mo
Net: $4.24. Margin: $2.24
Forget conversion rate projections and user-count modeling. The actual question: what does it cost to keep this app alive, and can a handful of people cover it?
| Google Places API (~100 users) | $0/mo (within 5K Pro free cap; costs start at ~1,250 active users) |
| Apple Developer Program (amortized) | ~$8/mo |
| Domain | ~$1/mo |
| Everything else | Free tier |
| Total to keep it running | ~$9/mo |
That is 6 Pro subscribers. Or 4 Pro+ subscribers. That is the real break-even target.
Not 200 users with optimistic conversion rates. A handful of people who use the app enough to pay for it.
Probably not many. The problem ("where should we eat?") is real but feels trivial. People don't pay to solve problems they think they can push through. Similar apps have struggled; UrbanSpoon got acquired and dissolved. Most "random restaurant" apps have under 1,000 downloads.
The differentiator (no ads, honest randomization) is appreciated, but principles are not features people open their wallets for.
Where the money is, if anywhere: Group Fork. It has a "right now" moment (group dinner, everyone arguing). People pay at the point of pain, not in advance. The tiered model puts that behind Pro+, which is where it should be.
Infrastructure is not the real expense. This project also consumed:
| Claude subscription (AI development partner) | $100/mo ongoing |
| MacBook (development hardware) | One-time purchase |
| Apple Developer Program | $99/year |
| Google Play Developer | $25 one-time |
| EAS builds (local via --local flag) | $0 (cloud builds eliminated) |
| Development time (nights, weekends, breaks) | 75 days and counting |
The Claude subscription alone costs 7x what the infrastructure does. But Claude is not a ForkIt cost; it is a personal development tool used across all projects. ForkIt is one beneficiary of a tool that would exist anyway.
The sunk costs will never be recouped by a $1.99 app with ~100 users. That is fine. This is a portfolio piece that demonstrates capability. The only financial requirement: the app should not cost money out of pocket to keep running.
Break even is the floor. Everything above that is a bonus.
Three months. Three pricing models. Each one taught something the previous one couldn't.
Every user got the same API calls. Every search hit Google's Enterprise tier because the field mask included rating, priceLevel, and currentOpeningHours. Free and paid users were identical from Google's billing perspective.
The assumption: a $200/month Google Maps credit would cover it. That credit had been eliminated a year before the project started. The LLM's training data was stale. By the time real billing data arrived, the architecture was locked in.
Result: ~$43/month API cost (Feb 2026 actual: $42.77) for ~100 users, 100% of it from Nearby Search Enterprise. Everything else (Place Details, Text Search, Autocomplete) fit within free caps. V4 eliminated this cost entirely.
Free (10 searches/month), Pro ($1.99, 20 searches), Pro+ ($4.99, unlimited + cloud sync). The three-tier model aligned cost with revenue: cloud sync (the most expensive feature) moved behind Pro+.
But an uncomfortable truth emerged: who pays $5/month for a food picker app? The problem ForkIt solves feels trivial. Competitors are free. The value proposition for Pro+ (cloud sync + unlimited) is real but not compelling enough to justify 2.5x the Pro price.
And the deeper problem: all three tiers still hit the same Enterprise API tier. Free users cost the same to serve as Pro+ users. The pricing tiers existed for revenue, but the architecture didn't match.
A full audit of Google's field-to-tier mapping, actual billing data, and unit economics exposed the real cost structure.
Google doesn't bill by endpoint. It bills by the highest-tier field in your request. Four fields lock Nearby Search into Enterprise billing ($35/1K, 1,000 free/month): rating, priceLevel, currentOpeningHours, userRatingCount.
Remove those fields, and the same call bills at Pro ($32/1K, 5,000 free/month). Current volume of ~2,400 calls/month fits entirely within the Pro free cap.
One field mask change: $49/month to $0/month.
The Enterprise fields that cost more to request are the same fields that power the premium features (rating filter, price filter, open-now filter). Free users don't need those fields if they don't have access to those filters.
This creates a natural alignment: features that cost more to serve are gated behind tiers that generate revenue. Free users get the core experience (random pick with name and location) at zero API cost. Paid users get filters and richer data, paid for by their subscription.
| API Tier Alignment | |
| Free user search | Pro fields (within 5,000 free cap) = $0/month |
| Pro/Pro+ user search | Enterprise fields = ~$0.97/user/month |
| Detail tap (all users) | Enterprise (within 1,000 free cap) = $0/month |
| Autocomplete (all users) | Session-based = $0/month |
Apple's Small Business Program reduces the App Store commission from 30% to 15% for developers under $1M in annual revenue. Google Play's 15% on the first $1M is automatic. This nearly doubles the per-user margin.
At 15% cut, a Pro subscriber at $1.99 keeps $1.69 (not $1.39). A Pro+ subscriber at $2.99 keeps $2.54 (not $2.09). The difference between "barely profitable" and "solid margin" was a form submission.
Lesson: check your store commission rate before building a revenue model. The default assumption of 30% may be leaving 15% on the table.
Pro+ lowered from $4.99 to $2.99. The $1 jump from Pro ($1.99) to Pro+ ($2.99) is psychologically easy. "Just a dollar more for unlimited." Cloud sync removed; replaced with export/import. Clerk, Neon, and RevenueCat all removed.
API: Pro tier = $0
API: Enterprise = ~$0.97/user
API: Enterprise = ~$1.61/user
| Free user | API: $0.00 | Revenue: $0.00 | Net: $0.00 |
| Pro user ($1.99) | API: $0.97 | Revenue: $1.69 | Net: +$0.72 |
| Pro+ user ($2.99) | API: $1.61 | Revenue: $2.54 | Net: +$0.93 |
Every tier is net positive. Free users cost nothing. Paid users more than cover themselves. The break-even target at current scale is effectively zero subscribers.
Even in the most optimistic viral scenario (100K installs, App Store feature), ForkIt nets ~$500-1,000/month by month 12 at $1.99/$2.99 pricing. This is a niche utility app, not a social platform. ~80% of installs churn in week 1. ~3-4% of active users convert to paid. Paid subscribers cancel at ~8-10%/month.
This is not "quit your job" money. The ceiling is a meaningful side income, not a startup outcome. The things that move the needle more than virality: retention past week 1, conversion rate improvements, and reducing subscriber churn.
The architecture ensures the app doesn't lose money at any scale. That's the win. Everything above $0 net is a bonus.
Subscription billing has its own engineering pitfalls (group level inversion on iOS, replacement params on Android, paywall tier-awareness, sales-report lag) that aren't pricing decisions; they're platform contract decisions. They live on the Platform Engineering page.
The principle wasn't born in a strategy session. It was crystallized by two conversations that arrived uninvited.
Two restaurant owners, separately, asked the same question: "Can we pay to show up more often?"
The answer was immediate and easy. No. The app picks randomly. If you can buy placement, the randomization is dishonest, and the entire value proposition collapses. Users trust the pick because nothing influences it except their own filters.
The moment someone can buy a better result, the app becomes an ad platform. That is a different product.
A friend, watching the app grow, predicted: "You're going to end up building Yelp 2.0. Reviews, business pages, sponsored content. That's where the money is."
He was describing the standard playbook. Build the audience, monetize the attention. Every food app eventually becomes an advertising platform for restaurants.
That prediction became the clearest articulation of what not to build. The constraint isn't "we can't afford ads." It is "ads would destroy the thing that makes this useful."
The friend who predicted Yelp 2.0 wasn't wrong about the industry. He was wrong about this project. "As free as possible" is not naive idealism. It is the only business model where the product stays honest.
This app will probably not make money. The problem it solves feels trivial. The market is small. Similar apps have failed.
But it costs ~$9/month to keep alive. It takes $0 from advertisers. And it demonstrates that a solo builder with no dev background can ship a real product, operate 7 services, and make deliberate cost decisions at every layer of the stack.
The business case is not the revenue. The business case is the capability.
Part of that capability: an explicit choice about what to open and what to protect. The client code is public at forkit-open under PolyForm Noncommercial, so readers can study a shipped indie React Native codebase. The backend — API key, caching strategy, curated chain list, paywall enforcement — stays closed. Open enough to be a case study; closed enough to keep future options available.
Break even is the floor. The portfolio is the point.