
How our stats work
Exactly where every number on this site comes from and how it's computed
Step 1 — Harvest
A harvester script pulls the top 200 players from 5 regional leaderboards (Global, US, GB, KR, BR) — about 984 unique players total. For each one, it fetches their last 25 battle logs from the Brawl Stars API and filters out anything that isn't real competitive play:
- ·Non-competitive modes (Showdown, 5v5 events, novelty modes)
- ·Friendly / practice games
- ·Battles with missing timestamps or no result field
Every valid battle writes a BattleRecord row for each of the 6 players in the game, with win/loss flipped per team. Then the harvester chains one hop deep — every unique player tag seen in those battles gets added to a secondary pool, and up to 400 of those get harvested too. So the dataset isn't just the top of the ladder, it's the competitive ecosystem around them.
Result: ~185,000+ BattleRecord rows, each tied to a specific brawler + map + result. Every row is raw and append-only — we never edit or delete this data.
Step 2 — Aggregate into two tables
The aggregator writes to two tables, and the split matters. An earlier version of this pipeline used a single table and was silently dropping ~18% of real battles because of a map-filter mismatch. Splitting fixes that.
One row per (map × brawler). Powers the /maps page. Only includes battles on maps we have in our Map table — 5v5 event maps and retired maps get dropped here intentionally.
One row per brawler. Computed directly from BattleRecord with no map filter applied. Every competitive-mode battle counts toward a brawler's overall stats. This powers the dashboard, counter picker, draft simulator, and analyzer.
Tracked competitive modes: Gem Grab, Brawl Ball, Bounty, Heist, Hot Zone, Knockout, Siege, Wipeout, Duels. Duels is 1v1, not 3v3, and included as a deliberate call — tank/sustain brawlers underperform there but it's still real competitive data.
Step 2.5 — Win rate shrinkage
Raw win rates lie when samples are small. A brawler with a 3-0 record has a 100% win rate but the signal is noise. Every displayed win rate gets pulled toward 50% using a Bayesian prior of 50 virtual 50/50 games:
shown_rate = (wins + 25) / (total + 50)
Effect at different sample sizes:
- ·3 wins / 3 games (100% raw) → 53.6% shown
- ·27 wins / 50 games (54% raw) → 52% shown
- ·270 wins / 500 games (54% raw) → 53.6% shown
- ·2700 wins / 5000 games (54% raw) → 53.9% shown
Big-sample brawlers barely move. Tiny-sample brawlers get pulled hard toward the middle so they can't top dashboards on noise alone. Pick rate isn't shrunk — it's a pure ratio and small samples don't produce misleading outliers there.
Step 2.6 — Tier assignment
Tiers are the loudest badge on the site, so they need to mean something:
- ·S = win rate 54%+ AND total battles 1000+
- ·A = win rate 51%+
- ·B = win rate 48%+
- ·C = below 48%
The 1000-battle floor for S is the guard. At 1000 games, a 54% observed rate has a 95% confidence interval of about ±3pp — true rate is very likely 51%+, which is genuinely strong. Without the floor, a 500-battle brawler on a hot streak would get the same S badge as one with years of proven data. The rule references no brawler by name — everyone auto-promotes or auto-demotes as their data moves.
Step 3 — Per-map ranking (Wilson score)
Per-map rankings don't sort by raw win rate — they sort by Wilson score lower bound at 95% confidence with a 50-game Bayesian prior. Wilson answers: "what's the lowest plausible true win rate given this sample?" It pulls uncertain samples down harder than certain ones, so 2-0 (100% raw) ranks below 44-33 (57% raw) because the first has too little data to trust. Same math Reddit uses to rank comments.
Step 3.5 — Map pick callouts
Three cards on every map detail page, picked live from the map's stats — not from a pre-computed field:
- ·Best first pick — top of the Wilson-sorted list, restricted to brawlers with a real sample
- ·Safest pick — win rate 51%+ AND pick rate 3%+. The consensus strong-and-popular choice
- ·High risk / high reward — win rate 53%+ AND pick rate under 3%. Niche picks punching above their weight
Any of the three can return empty, and the card simply doesn't render. We'd rather show two cards than fake a third.
Step 4 — Counter engine
Brawlers are typed: lane, tank, assassin, thrower, sniper. A counter matrix defines the competitive triangle (lane beats thrower, tank beats assassin, assassin beats lane, thrower beats tank, and so on).
When you select enemy brawlers, every available brawler scores:
- ·+2 for each enemy type it's strong against
- ·-1 for each enemy type it's weak against
- ·Small bonus from win rate as a tiebreaker
This is competitive theory, not empirical head-to-head data. BattleRecord only stores the harvested player's brawler per battle, not the full enemy roster, so we can't compute true matchup win rates yet. That's a planned upgrade once the schema captures all 6 participants per battle.
Step 5 — Draft engine
The draft simulator tracks ban/pick state for both teams, recommends highest-impact brawlers to ban (win rate × pick rate = danger score), runs the counter engine against enemy picks for top-3 suggestions with reasoning, and computes a live advantage score — your team's average win rate minus the enemy team's. Positive means you're favored.
What each dashboard panel means
Sorted by impact = (win rate × pick rate) / 100. Answers "which brawlers are actually shaping the meta?" A brawler ranks high because they're picked often AND winning — Mortis tops it even though his win rate isn't the highest on the site, because he's in so many games you can't ignore him.
Pure pick rate sort. Top 5.
Pure win rate sort, filtered to real-sample brawlers. Answers a different question than Top in meta — surfaces under-the-radar brawlers who are statistically strongest when they show up, even if they aren't yet defining the meta. Useful for draft decisions.
What we're honest about
The Brawl Stars API doesn't expose ranked-draft bans, so we stripped all ban-rate UI from the site. Empty columns are worse than no columns. Any meta site claiming precise ban rates without a Supercell data deal is making them up.
We only store the harvested player's brawler per battle, not the full 6-brawler lineup. "Pick rate" is really "share of harvested player-battles," not true game frequency. Counter recommendations are competitive theory plus meta strength, not real head-to-head matchup data. That's the big planned upgrade.
No private matches, no club leagues. Only what the Brawl Stars public API exposes.
Per-map rows with fewer than 50 battles are flagged as not-yet-real. We don't show them in pick callouts or use them for S-tier assignment.
How to verify any of this yourself
- ·/debug/stats — per-brawler comparison of raw BattleRecord win rates vs what's stored. They share the same SQL source, so they should match within ±0.5pp. Any drift is a real bug. Also shows what numbers would look like under the old map-filtered aggregation path, with deltas — visual proof of the bias we fixed.
- ·/debug/maps — which map names from BattleRecord matched our Map table and which got dropped.
- ·The Brawl Stars API is public. Pull any player's battle log and check our data against it — they should match exactly.
Why top players?
Leaderboard players play the actual competitive meta. They draft intentionally, play optimal modes, and their results reflect real brawler strength — not casual chaos. Chain harvesting one hop deep pulls in the opponents and teammates those top players fought, so the sample isn't just the top of the ladder — it's the competitive ecosystem around them.
