← Case Study Home

The Business
Case
(12 Services, $20/Month)

How do you run 12 services for $20/month, and what happens if this thing actually grows?

$20
Monthly infrastructure
$1.99
Pro tier / month
$0
Ad revenue. Ever.
0
Services running

Part of the ForkIt! Case Study. Read the full story →

Scroll to explore

The Constraint: "As Free As Possible"

"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.

What It Sounds Like

  • Charity. Underpricing. A hobby project that doesn't take money seriously.
  • "You should charge more." "You need a revenue model." "Free doesn't scale."
  • Every advisor, every pitch deck template, every SaaS playbook says the same thing.

What It Actually Is

  • A forcing function. Every feature gets asked: "Does this need an API call?"
  • An architecture driver. Pool caching, client-side filtering, local re-rolls: all exist because of this constraint.
  • A trust signal. No ads, no tracking, no sponsored listings. The user is the user, not the product.
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.
The Numbers

Where the Money Goes

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 / EASFree 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.

The Only Line That Moves

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.

The Expensive Part

The API Problem

Google Places is the only real cost. And it cost more than expected.

The Pricing Discovery

Google Maps Platform offers a $200/month credit. The credit exists. What the documentation doesn't make obvious: Nearby Search and Text Search hit Enterprise SKU pricing, which consumes the credit far faster than Basic endpoints. The same credit that would cover thousands of simple geocoding calls covered only hundreds of restaurant searches.

The LLM said the credit would cover development costs easily. It did not account for the SKU tier. Pricing decisions were made on that assumption.

Lesson: never trust LLM pricing knowledge. Verify vendor pricing pages directly before making cost-driven architecture decisions.

The Fix: Pool Caching

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"
Cache Check Pool exists? Filters same?
🔒 Google Places API $0.032 per call
🍴 Local Pool 20+ restaurants cached
Random Pick $0.00 per re-roll

First Tap: API Call

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

Second Tap: Free

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

Third, Fourth, Fifth Tap: Still Free

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

Filter Change: New Call

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.

The Math

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.

Six More Optimizations

Beyond pool caching, six specific changes reduced per-search cost further.

Reduced API Calls

  • Parallel Nearby Search requests consolidated (6 calls became smarter batching)
  • Field masks on every request (only fetch name, address, rating, price; skip photos and reviews)
  • Details endpoint removed from the main flow (pool data is sufficient for the pick)

Client-Side Intelligence

  • Chain detection runs locally (no API call to check if a restaurant is a chain)
  • Exclude filter runs client-side against the cached pool
  • Re-rolls, favorites, and history all operate on local data
The Model

The Revenue Model

Pro exists to offset API costs, not as a revenue model. The goal is sustainability, not growth-at-all-costs.

What Shipped (Current)

Free Tier

  • 20 searches per month (resets on the 1st)
  • 1 Fork Around (group) session per month
  • Unlimited re-rolls from cached pool
  • Full filter access
  • History, favorites, custom spots, cloud sync
  • Soft nudge after 10 searches; hard paywall at 20

A "search" = a new API fetch. Re-rolls from the cached pool are free and unlimited.

Pro ($1.99/month)

  • Unlimited searches
  • Unlimited Fork Around sessions
  • Cloud sync (history, favorites, custom spots across devices)
  • Everything in the free tier

Managed through RevenueCat. Both iOS and Android. Promo codes for early adopters grant 1 year of Pro.

The Margin Problem

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.

What Will Never Exist

  • No advertising. Not banner ads. Not sponsored listings. Not "promoted" restaurants. Not ever.
  • No tracking. No analytics that follow users across apps. No selling user data. No ad networks.
  • No pay-to-rank. Restaurant owners cannot buy placement. The randomization is honest.

This is a hard rule, not a preference. It is documented in the project guide, enforced in code reviews, and has been tested by real offers from restaurant owners.

Code Protection

The codebase uses a Business Source License (BSL). The code is visible on GitHub for portfolio and transparency purposes, but commercial use requires a license. This protects the work without hiding it.

The Projections

What Breaks at Scale

Every free tier has a ceiling. Here is where each service hits its limit, and what it costs to cross.

Unit Economics

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.

The Real Math

The Path to Break Even

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.

Where It's Heading: Three Tiers

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.

Free

  • 10 searches/month
  • 1 group session/month
  • Unlimited re-rolls
  • Full filters
  • Favorites, history, spots (local only)

Cost to serve: ~$0.32/mo

No database load

Pro ($1.99/mo)

  • 30 searches/month
  • 5 group sessions/month
  • Unlimited re-rolls
  • Full filters
  • Favorites, history, spots (local only)

Cost to serve: ~$0.96/mo

Net: $1.69. Margin: $0.73

Pro+ ($4.99/mo)

  • Unlimited searches
  • Unlimited group sessions
  • Cloud sync across devices
  • Synced history, favorites, spots
  • Everything in Pro

Cost to serve: ~$2.00/mo

Net: $4.24. Margin: $2.24

The Simpler Truth

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 elseFree 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.

Will People Pay?

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.

The Honest Sunk Costs

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)73 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

The Monetization Test

The principle wasn't born in a strategy session. It was crystallized by two conversations that arrived uninvited.

The Restaurant Owners

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.

The Yelp 2.0 Prediction

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.

The Honest Business Case

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.