How do you run 12 services for $20/month, and what happens if this thing actually grows?
Part of the ForkIt! Case Study. Read the full story →
"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.
Thirteen services. One variable cost. Everything else is free tier or a fixed annual fee.
| Google Places API | ~$0.032/search |
| Vercel (hosting + serverless) | Free tier |
| Vercel KV (Redis) | Free tier |
| Clerk (auth) | Free tier |
| Neon (Postgres) | Free tier |
| RevenueCat (IAP) | Free tier |
| Sentry (error tracking) | Free tier |
| ImprovMX (email forwarding) | Free tier |
| GitHub (source + CI) | Free tier |
| Expo / EAS | Free tier* |
| Apple Developer Program | $99/year |
| Google Play Console | $25 one-time |
| Domain (forkaround.io) | ~$12/year |
| Total fixed | ~$20/month amortized |
*EAS Starter ($19/month) used only during active build/submit cycles, then cancelled. Not a standing cost.
Every other cost on this list is fixed or zero. Google Places API is the only cost that scales with usage. Every architecture decision, every caching strategy, every "does this need an API call?" question exists because of this one line item.
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 4 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.
Beyond pool caching, six specific changes reduced per-search cost further.
Pro exists to offset API costs, not as a revenue model. The goal is sustainability, not growth-at-all-costs.
A "search" = a new API fetch. Re-rolls from the cached pool are free and unlimited.
Managed through RevenueCat. Both iOS and Android. Promo codes for early adopters grant 1 year of Pro.
Every user, including free users, gets cloud sync. That means every user hits Neon, Clerk, and the backend. A power Pro user who searches 50 times a month costs ~$1.60 to serve and pays $1.69 net. That is a $0.09 margin on the most engaged users.
The users who cost the most pay the same as the users who cost the least.
Free tier limits are tracked per-device, not per-account. A determined user could bypass them with a second device or a new Google account. At ~50 users and $1.99/month, the incentive to game it is near zero. But the architecture doesn't scale.
Server-side usage tracking per Clerk user ID 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.16 |
| Cost per active user (20 searches/month) | ~$0.64 |
| Cost per power user (50+ searches/month) | ~$1.60 |
| Revenue per Pro subscriber (after store cut) | ~$1.69 |
| Breakeven per Pro user | ~10 searches/month |
Revenue per subscriber assumes Apple/Google's 15% small business cut (under $1M annual revenue): $1.99 x 0.85 = $1.69. Pool caching makes the math work: without it, breakeven would be at 3 searches/month, and power users would cost more than they pay.
13 services. Most on free tiers. Google already killed its $200/month API credit without warning (March 2025). Clerk, Neon, Vercel, RevenueCat, Sentry — 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.
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.
The fix for the margin problem: align cost with revenue. The features that cost the most to run (database sync) go behind the tier that charges the most.
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 (~50 users) | ~$3/mo |
| Apple Developer Program (amortized) | ~$8/mo |
| Domain | ~$1/mo |
| Everything else | Free tier |
| Total to keep it running | ~$14/mo |
That is 8 Pro subscribers. Or 4 Pro+ subscribers. That is the real break-even target.
Not 200 users with optimistic conversion rates. Ten 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 Starter (build service, used intermittently) | $19/mo when active |
| 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 ~50 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.
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 $14/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 12 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.
Break even is the floor. The portfolio is the point.