A $1.20 question with no answer
A post hit the Hacker News front page yesterday asking whether a $1.20 model is good enough for code review. 114 comments, no consensus. The thread kept circling one trap: pricing pages quote dollars per million tokens, and nobody pays per million tokens. You pay per review.
So I measured a review. One 64-line Python file with bugs planted in it, seven Qwen tiers, identical prompts, a client-side stopwatch. The runner was Alibaba's open-source open-code-review (ocr), which shipped v1.12.1 the same week and sat at #2 on GitHub Trending with 26k stars. Token counts are the API's own usage block. Unit prices come from bl model list --model <name> --output json, which needs no account and no auth, so every price below is checkable.
Prices are in CNY because that is what the lookup command returns.
The file
A small order service. Four real defects:
- A
fetchone()result used without a null check. Crashes when the user does not exist. - An f-string interpolated straight into SQL. Textbook injection.
- A global counter incremented with
+=while the lock defined two lines above is never acquired. Two concurrent orders lose one update. - An
open()withoutwith. If parsing throws halfway through, the handle leaks.
Plus two decoys that look suspicious and are correct: an @lru_cache on a pure function, and a redundant except Exception: raise that preserves the traceback exactly as a bare raise should. Flagging either counts as a false positive, and false positives are what make a cheap tier look expensive.
The table
| Model | Thinking tokens | Found /4 | Missed | False + | Score | Wall time | In tok | Out tok | Cost per review |
|---|---|---|---|---|---|---|---|---|---|
| qwen-turbo | none | 2 | 2 | 4 | -2.0 | 7.4s | 468 | 1,005 | ¥0.0007 |
| qwen3-coder-plus | none | 3 | 1 | 1 | 2.0 | 10.1s | 464 | 712 | tiered pricing / see console |
| qwen-plus | none | 2 | 1 | 1 | 1.5 | 39.3s | 464 | 1,766 | ¥0.0039 |
| qwen3.7-plus | 1,182 | 4 | 0 | 0 | 4.0 | 23.4s | 502 | 2,052 | not published / see console |
| qwen3.6-flash | 4,258 | 4 | 0 | 1 | 3.0 | 42.6s | 502 | 5,075 | not published / see console |
| qwen3.8-flash | 9,517 | 4 | 0 | 0 | 4.0 | 241.0s | 540 | 12,909 | ¥0.0353 |
| qwen3.8-max | 9,770 | 4 | 0 | 0 | 4.0 | 293.1s | 540 | 11,064 | ¥0.4048 |
One run per configuration. Same system prompt, same user message, byte-identical payloads, max_tokens pinned to the CLI default of 4096, wall clock timed on the client including network round trips. Score is found bugs minus false positives, out of 4. The qwen3-coder family is officially tiered-priced, and qwen3.6-flash plus qwen3.7-plus return no unit price from the lookup command at all, so those cells point at the console instead of a guess.
Four things I did not expect
The flagship bought nothing on this file. qwen3.7-plus scored a perfect 4.0 in 23.4 seconds with 2,052 output tokens and correct line numbers. qwen3.8-max also scored 4.0, and it caught three real problems I had not planted, including that amount <= 0 does not reject float('nan') because nan <= 0 is False. It took 293.1 seconds and 9,770 thinking tokens to get there. The extra 8,588 thinking tokens bought time, nothing else.
The divider is thinking, not price. The three tiers that did not think scored -2.0, 2.0 and 1.5, and every one of them missed at least one planted bug. The five that thought scored 3.0 or better and missed nothing. Past roughly 1,200 thinking tokens the score stops moving. 1,182 tokens of thought is a perfect score here. So is 9,770.
Unit price and total bill are different animals. qwen-turbo costs ¥0.3 per million input tokens and qwen3.8-max costs ¥12, which is 40x. Per review, turbo spent ¥0.0007 and max spent ¥0.4048, which is 545x, because the expensive run also wrote eleven thousand output tokens and most of them were reasoning. Budget from the pricing page and you will be wrong by an order of magnitude.
Line numbers are only trustworthy on the thinking tiers. turbo placed the SQL injection on line 9 (it is line 18) and the null deref on line 10 (line 13). Descriptions right, coordinates wrong. qwen3.7-plus and above were accurate to within one line. Treat a cheap tier's output as a lead list and find the code yourself; treat a thinking tier's output as navigation.
One control run worth recording: qwen3.8-flash with --enable-thinking forced on. It thought harder (11,611 tokens), wrote more (14,954), cost 16% more, and scored the same 4.0 as its default run. On this task the switch only buys a bigger invoice.
Wiring ocr to DashScope in five commands
ocr ships a built-in provider named dashscope. Its base URL is DashScope's OpenAI-compatible endpoint and the Qwen models are preset, so there is no custom provider file to write.
npm install -g @alibaba-group/open-code-review
ocr config set provider dashscope
ocr config set model qwen3.7-plus
ocr config set providers.dashscope.api_key sk-your-key
ocr llm test
Then ocr review inside a repo, or ocr scan --path some/dir for a full-file pass with no git history. Create an API key in the Bailian console before the fourth command.
Two notes if you run outside China. DashScope also serves Virginia (https://dashscope-us.aliyuncs.com/compatible-mode/v1), Singapore and Tokyo, and API keys are region-bound: a key created in one region returns 401 against another region's endpoint. The new-user free quota is per model and independent (typically 1M tokens each), valid for 90 days, Beijing region only, with no reissue after expiry and no automatic failover to another model when it runs out. From Virginia or Singapore you are on pay-as-you-go from the first call, so budget for it.
What I would pick
| Scenario | Tier | Per review | Reviews per ¥1 | 10/day × 22 working days |
|---|---|---|---|---|
| Coarse sieve on every commit, you read the code anyway | qwen-turbo | ¥0.0007 | ≈1,345 | ¥0.16 |
| Cheap pass with a published price | qwen-plus | ¥0.0039 | ≈256 | ¥0.86 |
| Default PR gate, line numbers you can jump to | qwen3.7-plus | ≤¥0.0799 (upper bound; real price unpublished) | price unpublished | price unpublished |
| Hard diff, deep reasoning, still cheap | qwen3.8-flash | ¥0.0353 | ≈28 | ¥7.76 |
| Same, thinking forced on | qwen3.8-flash with --enable-thinking
|
¥0.0408 | ≈24 | ¥8.98 |
| The gnarliest file in the repo | qwen3.8-max | ¥0.4048 | ≈2 | ¥89.05 |
The ¥0.0799 is a bound, not an estimate: priced at the flagship's ¥12 and ¥36 rates, that run's 502 input and 2,052 output tokens come to ¥0.0799, one fifth of the flagship's ¥0.4048, and its real price cannot be higher. For the tiers with no published price, check the model pages in the console rather than any reposted number.
One observation, not a conclusion: the two cheap non-thinking tiers missed different bugs. qwen-plus missed the null deref, qwen3-coder-plus missed the race condition, and their misses did not overlap. Running both and cross-reading the reports covers that blind spot at the price of stacked false positives and a human in the loop. With seven configurations measured I would not call this a rule.
Recalculate it yourself
from decimal import Decimal, ROUND_HALF_UP
def cost(in_tok, out_tok, price_in, price_out):
"""prices in CNY per million tokens"""
c = (Decimal(in_tok) * Decimal(price_in) + Decimal(out_tok) * Decimal(price_out)) / Decimal(1000000)
return c.quantize(Decimal("0.0001"), rounding=ROUND_HALF_UP)
print(cost(502, 2052, "12", "36")) # 0.0799: what qwen3.7-plus would cost even at flagship prices
Use Decimal, not Python's round(), or your totals will disagree with the invoice and neither will explain why.
Where this falls down
A community member reported 1,400 PRs taking over ten hours, and even a few-line PR takes minutes. This is not a pre-commit tool, and the flagship tier definitely is not. It does not replace SAST: a rules engine reports deterministic pattern hits, while ocr reports what a model understood about your code. They complement each other. And if your team already pays for a hosted review product that works, this is not a pitch to switch.
Sample size is one file, four bugs, one run per configuration. I ran two of the models twice and their scores moved: qwen-plus went 2.0 then 1.5, and turbo missed the null deref once and caught it the next time. Read every number above as "this run", not as a benchmark.
Your turn
Install the Bailian CLI and run the price lookup on your own machine; that command needs no account. The same CLI carries bl advisor recommend --message "...", and when I asked it to pick a review model on a budget its first choice was a cheaper third-party model rather than the Qwen flagship. I kept that detail in because it is more useful than any claim of objectivity I could make.
What would you pay per PR review, and which tier would you trust on a merge gate? Tell me in the comments what your worst file costs.



Top comments (0)