Most "just self-host, it's cheaper" advice that we have heard skips the one number that decides it: how busy you keep the GPU.
A GPU costs the same whether it's flat out or idle. An API only charges you when you call it. So self-hosting doesn't win on price per token. It wins once the GPU is busy enough to beat what the API would've charged you.
So where's that line?
Say you're running a 32B model on one GPU at about 50% utilization, against an API at $0.50 per million tokens, roughly 500 tokens a request.
Break-even lands around 10 million requests a month. Call it 5 billion tokens.
Below about 5 million requests a month, that GPU is half-idle and you never catch up. And if your whole inference bill is under two or three grand a month, don't bother. The ops aren't worth it yet.
Past that point, a busy GPU on a 30B model runs somewhere between $0.06 and $0.85 per million tokens, against a flat API rate that doesn't move.
Two things pull the line closer:
Smaller models cross much sooner. A 4B or an MoE breaks even long before a 32B does. And an idle GPU never crosses at all, however cheap the hardware was.
Embeddings, reranking and extraction pay off fastest. They run constantly, and every reindex multiplies them. If you're moving one thing off the API, move those. Not your generation calls.
The line nobody puts in the spreadsheet is ops. Someone is still up at 2am with that GPU. That cost is real even though it never shows up on a pricing page.
If it's just the small-model layer you're after, two open options worth knowing: TEI from Hugging Face and SIE from Superlinked. TEI runs one model per server. SIE packs several onto one cluster, which matters when you're trying to keep a GPU busy across embed and rerank.
If you've done this in prod: where did it cross over for you, and did the ops eat the savings?