The Free Tier Is Not the Cheap Lane: Pricing Your AI Coding Options per Merged PR
Thursday, 4:40pm. A platform lead drops a screenshot in our channel: free tokens, a free server option, and one line of text — "why are we paying for anything?" Fair question. Also the wrong unit. We were never paying for tokens. We were paying for the parts tokens do not include: the retry that at

Thursday, 4:40pm. A platform lead drops a screenshot in our channel: free tokens, a free server option, and one line of text — "why are we paying for anything?"
Fair question. Also the wrong unit. We were never paying for tokens. We were paying for the parts tokens do not include: the retry that ate forty minutes, the review that caught a plausible-but-wrong migration, the maintenance window on a box nobody wanted to own.
So let's answer it properly. Not with a feature grid, but with a number you can defend in a budget review.
Price every lane in cost per merged PR. Not cost per seat, not cost per token, not "free".
$$ C_{lane} = \frac{\text{model spend} + \text{retry minutes} \times H + \text{review minutes} \times H + \text{blocked wait} \times H + \text{amortized ops}}{\text{merged PRs}} $$
Where H is your loaded hourly engineer cost divided by 60. Yes, review minutes belong in the numerator. A free lane that doubles review time is not free; it moved the invoice to a person who does not see it.
A scorecard like this is a conversation tool, not objective truth. It exists so two people can disagree about the same numbers instead of different vibes.
You cannot compare lanes you did not measure. Append-only JSONL, committed to the repo, reviewed in a PR like any other artifact.
{ "date": "2026-10-15", "lane": "free", "task": "TICKET-412", "tokens_in": 8200, "tokens_out": 1900, "wait_s": 37, "retries": 1, "review_min": 22, "merged": true } Enter fullscreen mode Exit fullscreen mode Logging one task without a spreadsheet:
start = $( date +%s ) #... run your agent or assistant on the ticket... end = $( date +%s ) printf '{"date":"%s","lane":"%s","task":"%s","tokens_in":%s,"tokens_out":%s,"wait_s":%s,"retries":%s,"review_min":%s,"merged":%s}\n' \ " $( date -I ) " "free" "TICKET-412" 8200 1900 $(( end-start )) 1 22 true >> ledger.jsonl Enter fullscreen mode Exit fullscreen mode If your tool does not report token counts, write null and record the proxy you used. A labelled proxy beats a fabricated integer every time.
Because a dashboard someone else owns becomes a number nobody trusts. A file in the repo survives re-quotes, vendor changes, and the person who set it up leaving.
import json, collections H = 85 / 60 # loaded engineer cost per minute; replace with yours RETRY_MIN = 12 # your measured rework per failed attempt; replace def summarize ( path ): agg = collections. defaultdict ( lambda: dict ( prs = 0, tokens = 0, wait = 0.0, retries = 0, review = 0.0 )) with open ( path ) as f: for line in f: if not line. strip (): continue r = json. loads ( line ) a = agg [ r [ " lane " ]] a [ " prs " ] += 1 if r [ " merged " ] else 0 a [ " tokens " ] += ( r [ " tokens_in " ] or 0 ) + ( r [ " tokens_out " ] or 0 ) a [ " wait " ] += r [ " wait_s " ] / 60 a [ " retries " ] += r [ " retries " ] a [ " review " ] += r [ " review_min " ] out = {} for lane, a in agg. items (): if a [ " prs " ] == 0: continue minutes = a [ " review " ] + a [ " wait " ] + a [ " retries " ] * RETRY_MIN out [ lane ] = { " prs ": a [ " prs " ], " cost_per_pr ": round ( minutes * H / a [ " prs " ], 2 )} return out def break_even ( free_per_pr, hosted_var_per_pr, fixed_month, maint_hours, loaded_hourly ): monthly = fixed_month + maint_hours * loaded_hourly saving = free_per_pr - hosted_var_per_pr return None if saving <= 0 else round ( monthly / saving ) Enter fullscreen mode Exit fullscreen mode Run it weekly. If a lane has fewer than twenty merged PRs, stop and collect more data — small-n comparisons in this space are mostly noise wearing a decimal point.
A self-hosted or paid lane is worth it only above a volume threshold:
N* = (fixed monthly + maintenance hours × loaded hourly) / (free cost per PR − hosted variable cost per PR) Enter fullscreen mode Exit fullscreen mode Worked example. All figures below are illustrative inputs, not vendor quotes — plug in your own.
Monthly fixed-equivalent = 180 + (6 + 2.5) × 85 = $902.50. Saving per PR = $3.20. So N* = 282 merged PRs per month.
Sensitivity, same base except where noted:
Read the second row, then the fourth. The decision is far more sensitive to your free-lane cost and your maintenance hours than to list price. That is the whole point of measuring before switching.
An allowance is a pilot budget, not a P&L line. The project operator states a free allowance of 10 million tokens and a free server option; verify the current terms yourself before you commit, because allowances move and screenshots go stale.
months_of_runway = allowance / (median_tokens_per_task × tasks_per_month × people) Enter fullscreen mode Exit fullscreen mode Illustrative arithmetic with your own median, not a promise: 9,000 tokens per task, 25 tasks per developer per week, 4 developers → 430 tasks/month → 3.87M tokens/month → about 2.6 months. That is enough to fill a ledger. It is not enough to skip the ledger.
MonkeyCode is the open-source project in that screenshot. Disclosure: This article was prepared as part of MonkeyCode's product outreach. The free model access and free server option are what make it a usable zero-cost control arm in the experiment below — that is the honest role, and it is a real one.
Every pilot needs an end date or it becomes architecture by accident.
If you want a zero-cost control arm while you run this, the free tier and free server option are a reasonable place to start logging — check the repo README for current terms first, then let the ledger argue.
Teams that cannot commit to logging for two weeks. Teams whose work is confidential and whose free-lane data path is unverified. Teams under roughly 50 merged PRs a month where a single bad week swings the average. And anyone hoping the ledger will confirm a decision they already made.
Before you sign anything, write down which single variable would flip your choice: maintenance hours, review minutes, volume, or the allowance itself. Then go measure that one first.
Which number in your current setup have you never actually measured — and what would it cost you to find out this week?