Compare 650+ LLMs side by side — real pricing, real capabilities.
modelprice.boxtech.icu · built for devs who read configs more than marketing pages
Every LLM vendor publishes their own pricing table in their own format, with their own units, their own cache semantics, and their own marketing copy. The moment you try to answer "should I use Sonnet 4.5 or DeepSeek V3 for this feature" you end up with six open tabs and a spreadsheet.
Model Price collapses that into one keyboard-first page that:
- Knows about 650+ models across Anthropic, OpenAI, Google, xAI, Meta, DeepSeek, Moonshot AI, Alibaba, Z.AI, MiniMax, Mistral, Cohere and 40+ other labs
- Normalizes everything to per 1M tokens so side-by-side numbers are actually comparable
- Sources data from the community-maintained LiteLLM registry + direct provider scrapes — so new models land within days of release without manual curation
- Deduplicates across providers: "Claude Sonnet 4.5" is one entity with multiple offerings (Anthropic / Bedrock / OpenRouter), not three confusing rows
- Is shareable: every model has
/m/:slug, every comparison has/compare/:ids, both are proper URLs you can paste in a tweet
![]() |
![]() |
- Keyboard first —
⌘Kopens a fuzzy search palette,↑↓to navigate,Enterto open,⌘Cto copy themodel_id,⌘Dto add to compare. Runs entirely client-side. - Cold-start resilient — every visit renders instantly from a bundled
v2-fallback.jsonsnapshot (≈90 KB gzipped); the live backend refreshes in the background and silently swaps in once ready. No blank page, ever — even if the Render free-tier backend is cold-starting. - "Same tier, cheaper" recommendations — every detail view surfaces 3 alternatives ranked by
capability_overlap × savings(Jaccard over capability sets, weighted by input-price delta). The algorithm lives inbackend/services/alternatives.pyand is mirrored in the build-time fallback generator. - Drift report — every refresh emits a
drift.jsonlisting unmatched provider models, price deltas > 5%, new/removed entities. Self-healing data quality. - Official source links — every detail page links out to the maker's official pricing and docs. We provide the index, vendors provide the truth.
- Dark / light / system theme, EN / 中文 localization, both persist to localStorage.
- Open Graph + Twitter Card meta tags with a custom OG image — shareable on X, Slack, WeChat (copy link), Discord, Feishu with a real preview card.
┌────────────────────────────────────────────────┐
│ LiteLLM registry │
│ github.com/BerriAI/litellm (single SoT) │
└────────────────┬───────────────────────────────┘
│ fetched raw JSON on every refresh
▼
┌────────────────────────────────────────────────┐
│ Canonical Entity Layer │
│ slug, family, maker, context, capabilities, │
│ modalities, primary_offering_provider │
└────────────────┬───────────────────────────────┘
│ provider aliases via reverse index
▼
┌──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐
│ Anthropic│ Bedrock │ Azure │ OpenAI │OpenRouter│ xAI/etc. │
│ fetch() │ fetch() │ fetch() │ fetch() │ fetch() │ fetch() │
└────┬─────┴────┬─────┴────┬─────┴────┬─────┴────┬─────┴────┬─────┘
└──────────┴──────────┴────┬─────┴──────────┴──────────┘
▼
┌──────────────────────────────────┐
│ Offering Merger │
│ Each provider record resolves │
│ to a canonical_id via strict │
│ slug+prefix+version stripping │
└──────────────┬───────────────────┘
▼
┌──────────────────────────────────┐
│ entities.json + offerings.json │
│ + drift.json (data quality) │
└──────────────┬───────────────────┘
▼
┌──────────────────────────────────┐
│ /api/v2/* endpoints │
│ + v2-fallback.json snapshot │
│ shipped inside the Vite bundle│
└──────────────────────────────────┘
Two-layer data model: Entity (logical model like claude-sonnet-4-5) + Offering (one specific (entity, provider) pair with its own price and last-updated timestamp). One canonical claude-sonnet-4-5 entity with three offerings (Anthropic, Bedrock, OpenRouter) — not three separate rows with the same name.
| Layer | Tech |
|---|---|
| Backend | Python 3.12, FastAPI, Pydantic v2, httpx, Playwright (for provider scrapes), Pillow (OG image generation), pytest |
| Frontend | React 19, TypeScript 5.9, Vite 7, React Router 7, vitest + @testing-library/react + happy-dom |
| Data | LiteLLM model_prices_and_context_window.json + direct provider APIs / scrapes, merged into entity/offering JSON files, shipped as a static snapshot alongside the SPA |
| Hosting | Vercel (frontend, auto-deploy on release push) · Render free tier (backend, Docker) · GitHub Actions keepalive cron |
cd backend
uv sync
uv run playwright install chromium # first time only
uv run main.py # http://localhost:8000
uv run pytest # 86 backend testscd frontend
npm install
npm run dev # http://localhost:5173
npm test # 32 frontend tests
npm run build # prod bundle into dist/The frontend proxies /api/* → http://localhost:8000 in dev. Use VITE_PUBLIC_BASE_URL to override the canonical public origin used by Copy Link / Share on X (defaults to https://modelprice.boxtech.icu).
curl -X POST http://localhost:8000/api/v2/refreshThis re-fetches LiteLLM, re-runs all provider scrapes, writes fresh entities.json / offerings.json / drift.json. Check GET /api/v2/drift for unmatched models and price-drift items.
cd backend
uv run --active python scripts/sanity_check.pyPrints a hit-rate matrix of ~80 popular first-party models against the v2 entity set. Currently at 79% — the misses are long-tail edge cases logged in drift.json.
cd backend
uv run --active python scripts/generate_og_cover.pyWrites frontend/public/og-cover.png (1200×630). Regenerate after copy or palette changes.
cd backend
uv run --active python scripts/take_screenshots.pyUses the Playwright Chromium to capture the production site into docs/screenshots/ — home / drawer / entity page / compare / ⌘K palette in both dark and light themes.
118 tests total, all hermetic, ~3 seconds to run the whole suite:
- Backend (pytest, 86) —
slugify/strip_version_suffix, family-detection ordering (guards the "Codex before GPT" and "Cogito before Llama" regressions), canonical resolver cascade, offering merger helpers,compute_alternativesranking math,/api/v2/*contract tests via FastAPITestClient. - Frontend (vitest + @testing-library/react + happy-dom, 32) —
formatPrice/formatContext/formatPct,CompareBasketProvider(capacity cap, sessionStorage persistence, provider-scoping error),ThemeProvider(dark/light/system cycle,matchMedialistener,<html data-theme>reflection),LocaleProvider(default EN,{name}interpolation,<html lang>sync).
Run them:
cd backend && uv run pytest
cd frontend && npm testThe release branch is the production branch.
- Vercel auto-builds and deploys the frontend on every
releasepush. Config lives infrontend/vercel.json: it proxies/api/*→ Render and has a catch-all rewrite toindex.htmlso React Router deep links work. - Render rebuilds the backend Docker image on every
releasepush. Config inbackend/render.yaml. Free plan sleeps after 15 min of inactivity — the SWR fallback snapshot in the frontend makes this invisible to users. - GitHub Actions keepalive in
.github/workflows/keepalive.ymlpings/api/healthevery 10 min as a second line of defense against sleep.
Previous v1 production is tagged release-v1-backup for rollback. The v1 routes (/api/models, /api/providers, /api/families, /api/stats, /api/refresh/metadata) were removed on 2026-04-15. POST /api/refresh remains as a compatibility alias that delegates to the v2 refresh pipeline.
Read the v2 rebuild design document at docs/plans/2026-04-14-v2-redesign-design.md — it documents the product positioning (D quick lookup + A comparison as foundation, C "same-tier cheaper" as killer differentiator), the target audience (independent developers + agent/toolchain devs), the single-point breakthrough (Cmd+K + shareable URLs), the two-layer data model, the cold-start strategy, and every non-goal we intentionally didn't ship.
The v2 API contract is frozen at docs/plans/v2-api-contract.md.
MIT — see LICENSE.
Data sourced from BerriAI/litellm (MIT). Thanks to the LiteLLM community for maintaining the registry that makes this site possible.





