Dev.to AI 🤖 Ai 👁 0 📖 2 min read

One cheap-model router on a $5 VPS: use this week's price drops without rewriting your app

Disclosure: this post contains affiliate links; I may earn a commission at no cost to you. TL;DR: Prices moved a lot this week (Nov 2-6, 2026). Instead of hard-coding one model, put a tiny OpenAI-compatible router in fr

Disclosure: this post contains affiliate links; I may earn a commission at no cost to you.

TL;DR: Prices moved a lot this week (Nov 2-6, 2026). Instead of hard-coding one model, put a tiny OpenAI-compatible router in front of your app, send easy requests to a cheap model and hard ones to a frontier model, and change the mapping in one file when prices move again.

What moved this week

Model Provider/route Price per 1M tokens (in / out) Source
gpt-oss-120b OpenRouter $0.023 / $0.083 (was $0.15 / $0.60) overfeed.news OpenRouter snapshot, Nov 5
Llama 3.3 70B Instruct OpenRouter $0.10 / $0.32 same
GLM 5.3 OpenRouter $0.0699 / $1.40 same
Kimi K3.1 Pro Together AI $2.00 / $10.00 Together changelog, Nov 5
Claude Sonnet 5.5 Anthropic $2 / $10 promptunit.ai pricing table

Prices are list prices quoted by those trackers; check the provider page before you commit. They change daily.

The router (copy-paste)

# router.py  -- pip install fastapi uvicorn httpx
import os, httpx
from fastapi import FastAPI, Request

app = FastAPI()
ROUTES = {
    "cheap": {"url": "https://openrouter.ai/api/v1/chat/completions",
              "model": "openai/gpt-oss-120b", "key": "OPENROUTER_KEY"},
    "smart": {"url": "https://api.together.xyz/v1/chat/completions",
              "model": "moonshotai/Kimi-K3.1-Pro", "key": "TOGETHER_KEY"},
}
def pick(body):
    text = " ".join(m.get("content", "") for m in body["messages"] if isinstance(m.get("content"), str))
    hard = len(text) > 6000 or any(w in text.lower() for w in ("prove", "refactor", "debug", "plan"))
    return ROUTES["smart" if hard else "cheap"]
@app.post("/v1/chat/completions")
async def chat(req: Request):
    body = await req.json()
    r = pick(body)
    body["model"] = r["model"]
    async with httpx.AsyncClient(timeout=120) as c:
        resp = await c.post(r["url"], json=body,
                            headers={"Authorization": f"Bearer {os.environ[r['key']]}"})
    return resp.json()

Run it: uvicorn router:app --host 0.0.0.0 --port 8000, then point your app's OpenAI base URL at http://your-host:8000/v1. Streaming is not handled here; add it if you need it.

Worked cost example (assumptions stated)

100,000 requests a month, 1,500 input and 400 output tokens each = 150M input, 40M output tokens.

  • All on Kimi K3.1 Pro: 150 x $2 + 40 x $10 = $700
  • 80% cheap (gpt-oss-120b) / 20% smart: cheap = 120 x $0.023 + 32 x $0.083 = $5.42; smart = 30 x $2 + 8 x $10 = $140; total about $145

Quality depends on how well your "hard" rule matches reality; log both routes for a week and compare.

Where to host it

The router is a tiny always-on process, so a small VPS is enough. I'd use Hostinger VPS for this: put it behind Caddy for HTTPS, keep keys in environment variables, and restrict access with a shared token.

Decision table

Situation Do this
Prices change weekly Router with a ROUTES dict
Need data to stay in one region Check provider residency terms first
Sensitive prompts Self-host open weights instead

Sources

  • overfeed.news OpenRouter pricing snapshot (2026-11-05)
  • thismonthinai.com November 2026 (Together AI Kimi K3.1 Pro pricing)
  • promptunit.ai AI API pricing (Nov 2026)

Full disclosure: TokenLean uses affiliate links, including the Hostinger link above. If you buy through them I may earn a commission at no extra cost to you. I only recommend tools I'd consider for the job described. Prices are third-party reported and may be out of date.

📰 Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.