Was your League of Legends game actually winnable — or were you dropped into a losing queue?
Enter a Riot ID, pick a game (or your current live game), and get a fairness verdict — FAIR / NOT FAIR / FAVORED — with a one-line reason and a lane-by-lane matchup table for all 10 players, computed from pre-game data only (what everyone looked like before the match started, not after).
Free & open source (MIT).
A real analyzed game — matchmaking-side verdict (lane GA + duo synergy) split from the draft-side read (counter picks), win probability bar, and per-player chips for autofill/OTP/smurf/duo/streaks.
- 🎯 Ranked Solo/Duo only (queue 420) — ARAM and flex never pollute the data
- ⏪ Pre-game form for every player: W-L of their 5 ranked games before the analyzed match — current form lies, pre-game form doesn't
- ⚖️ Symmetric lane-by-lane matchup table: champion · player · GA per side,
EVEN/BLUE +n/RED +nverdicts with role icons, favored-side tinting, and a TEAM footer with the overall call - 🎲 Matchmaking vs. draft, split apart: the
FAIR / NOT FAIR / FAVOREDverdict is the lobby the matchmaker handed you (lane strength, autofill, duo synergy); a separateDRAFTline calls out counter-picks and bot-lane synergy that are on you, not the queue - 📊 Win probability bar: a poker-style blue/red % split on the same GA gap the verdict itself uses — never disagrees with the rest of the page
- 🤝 Duo detection: proven by shared pre-game match IDs (not guessed from names), with joint W-L record and a separate bot-lane (ADC+SUPPORT) synergy read from a static per-patch snapshot
- 🏷️ At-a-glance chips per player:
⚠️ autofill,OTP/OTP denied,🔗 duo,SMURF?,🔥/❄️streaks, mastery %, rank·winrate tags, color-coded CS/min - 👑 MVP / ACE + 1st–10th in-game performance ranking (KDA, kill participation, damage dealt share, objective damage, damage taken with an over-death guard, CS, vision — support- and tank-friendly)
- 🚩 "LOSING QUEUE?" streak badge when a player's last 3+ analyzed games were all stacked against them, win or lose — the matchmaker pattern, not any one result
- 🔴 Live game analysis (spectator-v5): analyze your current lobby during loading screen — know by minute 2 which lanes are favored and where to play (roles inferred from each player's history)
- 🌆 Dynamic background: the searched player's most-played champion splash, low-opacity behind the whole page
- 📤 Share cards: a "Share" button captures the actual rendered matchup card (not a redrawn graphic) into a downloadable/clipboard-ready PNG, plus a one-click profile link and a per-game deep link that loads keylessly for anyone
- ⭐ Bookmarked profiles in the search field's dropdown; with sign-in (Clerk) they sync across devices
- 📜 Analyzed history per player with pagination beyond the last 10 games
- 🔓 Keyless browsing: any game analyzed once is cached (Turso) and viewable by anyone with zero Riot key, forever — deep links and profile links both resolve straight from that shared cache
- 🔑 Bring-your-own-key: paste your free Riot API key for unlimited analyses; keyless visitors get 3 free deep analyses/day (5 when signed in) on the shared key with a fair-use lock
Vercel (free tier)
├── Vite static frontend
└── /api serverless functions (Node; only deps: @libsql/client, jose)
├── /api/matches — recent ranked games + cached flags (~2s)
├── /api/analyze — deep analysis of ONE game (~80 Riot calls) (~20–60s, cached forever)
├── /api/live — spectator-v5 lobby of the current game (~20–60s, cached per game)
├── /api/history — paged archive of analyzed games (instant)
└── /api/bookmarks — per-account bookmarks (Clerk JWT verified via JWKS)
Turso (free tier, SQLite over HTTP)
├── matches_raw raw Riot match JSON (shared across all users)
├── analyses verdicts + full player breakdowns
├── rate_lock serializes shared-key usage across serverless instances
├── quota per-IP / per-user daily limits
└── bookmarks starred profiles per signed-in user
All data comes from the official Riot Games API — no scraping.
- Riot dev keys allow ~100 requests / 2 min. One uncached deep analysis ≈ 80 calls; back-to-back analyses on one key pause between games (the UI retries automatically).
- Spectator data has no assigned roles — live-game positions are inferred from each player's recent history and labeled as such.
- The GA score and verdicts are heuristics: a "NOT OK" lobby can still be won; the point is knowing when the queue — not you — decided the game.
- Tighten CORS / quotas before heavy public use, and mind Riot's API policies beyond personal use.
- Champion-meta and bot-lane-synergy data (
lib/champstats.mjs,lib/duosynergy.mjs) are static op.gg snapshots — refresh them once per patch withnode scripts/refresh-snapshots.mjs.
MIT — do whatever you want, attribution appreciated.
Losing Queue isn't endorsed by Riot Games and doesn't reflect the views or opinions of Riot Games or anyone officially involved in producing or managing Riot Games properties. Riot Games and all associated properties are trademarks or registered trademarks of Riot Games, Inc.
