Methodology

How the ELO ratings are computed

← Rankings

How the rankings work, in plain English

Every team starts the season with the same score: 1500 points. Win a match and your score goes up; lose and it goes down. Beat a team that's better than you and you gain a lot; beat a team you were expected to beat and you gain a little. Over a season, teams settle at a number that reflects how they've actually performed on the court — no committee, no reputation, no politics.

This is the same family of math used to rank chess players worldwide and inside college football analytics. Every number on this site can be traced: click any team and you'll see every match behind their rating.

1 Upsets count more

Before every match, the system estimates who should win based on both teams' current ratings. The result is then compared to that expectation.

  • Beat a team rated far above you → big gain for you, big drop for them.
  • Beat a team rated far below you → small gain. You were supposed to win.
  • Lose a close one to a much better team → you barely drop at all.

This is why running up wins against weak schedules doesn't inflate a rating. The only way to climb high is to beat good teams.

2 It's not just the win — it's how you won

Two teams can both "win," but 25–10, 25–12 and 25–23, 24–26, 15–13 are very different statements. So the rating looks at three things in every match:

  • Points (40%): the margin in every set. Dominant scorelines move the rating more than nail-biters — but blowout margins level off, so beating an overmatched team 25–5 doesn't break the math.
  • Sets (25%): sweeping 2–0 says more than squeaking by 2–1.
  • The win itself (35%): winning always helps, no matter the score.
Why bother? A team that loses every set 25–23 is clearly better than one that loses every set 25–8 — a pure win/loss system can't see that difference. This one can.

3 New teams move fast, proven teams move slow

A brand-new team's rating jumps around a lot at first — that's on purpose, so a genuinely strong team doesn't spend half a season stuck at the starting number. After about 10 matches, the system has a read on them and the rating settles down, so one bad morning at one tournament can't wreck a season of results.

4 Not every match counts the same

  • Division matters: matches in Open (the top division) count full value. USA and Club division matches count half — winning there says less about how a team stacks up against the best.
  • Everyone starts at 1500: every team opens its season in regional and league play, so no team gets a head start from the division it enters. Division strength shows up in how much each match counts, not in where a team starts.
  • Playing up counts in full: when a Club team enters an Open division at an event, those matches carry full Open weight. Crossing over is how a team proves its rating right.
  • Rematches are dampened: if the same two teams meet twice or three times at one tournament, the repeats count less, so a single weekend can't dominate a rating.
  • Big events matter more: each tournament carries a weight based on the strength of its field. A national championship counts full value; a smaller regional counts less.

5 Why a hot new team isn't instantly ranked #1

Three great matches don't prove a team is elite — maybe they caught weak opponents, or everything just clicked that day. Until a team has played about 15 rated matches, the ranking shows a "reined-in" version of their score, pulled part-way back toward their division's starting number. The fewer matches, the stronger the pull.

Teams with fewer than 20 matches also get a P (provisional) tag in the rankings, so you know their number is still settling.

And a top seed must be earned against the best: the top 48 spots in each age group — the size of the Open field — are reserved for teams that have played in the Open division of a qualifying event. Go 30–0 in Club and your rating will be strong — but the seed line waits until you've played Open at one of them. Teams held out of the band carry a No Open tag, and their rating itself is never touched.

6 Built-in protections

  • Matches are processed in order. An October win over a team is judged by how good they were in October — not by what they became in April.
  • Forfeits don't count. A 25–0 scoreline is a paperwork result, not a volleyball result, so it's thrown out.
  • No team falls off a cliff. Ratings can't drop below a floor, so a rough stretch never buries a team beyond recovery.
  • One team, one rating. If a team plays Open at one event and Club at another in the same age group, their results are combined into a single team, not split in two.
  • Age groups don't mix. When a 16s team plays up against an 18s team, neither side is rewarded or punished for that match. Each age group (for boys, each pair of ages) is rated on its own scale, so a result across those scales isn't a fair comparison. The match still shows in both teams' records, tagged "not rated". A team is listed in the age group of its USA Volleyball team code (a B15 team is a 15s team even in a "16/15" division); teams without a code are listed in the group they play most. Boys 15s and 16s (and 17s and 18s, 13s and 14s, 11s and 12s) share one rating scale, because boys events mix those ages all the time.

7 What the rankings can't see

We'd rather be upfront about the limits than pretend there aren't any:

  • Only published results count. If a tournament doesn't post scores (or we haven't loaded it yet), those matches are invisible to the system.
  • Roster changes are invisible. If a team loses three starters mid-season, the rating only finds out through their results.
  • Regions connect through play. Teams from different parts of the country only get comparable ratings when their regions actually play each other — which is exactly what big cross-country events provide.
  • Islands have it harder. Programs from Puerto Rico and Hawaii can't get to several mainland tournaments a season, so their samples stay small. Their ratings stay conservative — anchored and tagged — until they meet the field, and their home events are priority additions.
  • It's a report card, not a crystal ball. The rating summarizes what has happened, not what a team might become.

8 The tournament strength score

On the Tournaments page, every event gets a 0–100 score answering one question: how strong was this field, really? It rewards events that draw top-rated teams, deep fields, and — most heavily — teams from many different states. A stacked local invitational is still a local event; the score is built so only true national draws rank as national.

That score is informational only — it doesn't change any team's rating.

9 Check our math

Nothing here is a black box. Click any team on the rankings and you'll see every match, every score, and exactly how much each result moved their rating. Run the season again from the same match data and you get the same numbers every time. If a coach or director disagrees with a seed, the receipts are one click away — and if you find a mistake in the data, the Contribute page is the fastest way to flag it.

Want the exact formulas, weights, and multipliers? Flip the toggle at the top of this page to the Technical view.

The short version

Every team starts at 1500. After each match, both teams' ratings move up or down based on the result, adjusted by how they won (point margin, set margin, match outcome), who they played (stronger opponents = bigger reward for a win), where they played (bracket matches count more than pool play), and how much we trust the signal (more matches = more confidence).

The engine processes every match chronologically from the current season (Aug 2025 – Jul 2026). If you re-run the pipeline, the numbers are fully reproducible from the raw match CSV.

1 Expected Score

Before a match, the engine asks: given the two teams' current ratings, what's the expected win probability for each side? This is the classic ELO formula — a team rated 200 points higher has roughly a 76% expected win rate.

E_A = 1 / (1 + 10^((ELO_B − ELO_A) / 400))

After the match, the engine compares the actual result to this expected result. Beating a team you were supposed to beat gains you a little. Beating a team you weren't supposed to beat gains you a lot. The gap between expected and actual is the engine of the rating change.

2 Three Layers of Result

A volleyball match isn't just a win or loss — it's a sequence of points inside sets inside a match. The ranking uses all three:

Points
40%
Sets
25%
Match
35%

Point layer (40%)

The most granular signal. A 25–10 set transfers more rating than 25–23. Margin is scaled logarithmically so 40-point blowouts don't dominate — beyond a certain margin, extra points give diminishing returns. This protects ratings from being skewed by mercy-rule wins against vastly weaker opponents.

Set layer (25%)

Winning 2–0 is a stronger signal than 2–1. The set layer rewards sweeps. A sweep multiplier of roughly 1.15–1.3× applies based on the set differential.

Match layer (35%)

The binary outcome. You won or you didn't. This is the classic ELO component and guarantees that winning always moves you up, regardless of margin.

Why three layers? Relying only on match outcome throws away information — a team that loses 25–23, 26–24 is clearly closer to its opponent than one that loses 25–5, 25–8. Splitting the signal across points, sets, and matches gives a more accurate picture, especially early in a season when sample sizes are small.

3 K-Factor (How Much Ratings Move)

K controls the magnitude of the rating change. The bigger K, the faster ratings move. The engine uses an adaptive K:

StageDescriptionK
New teamFewer than 10 matches processed48
Established10+ matches processed32

Newer teams calibrate faster — if a true top-tier team starts at 1500, higher K lets them climb to their real rating quickly. Once we have enough data on them, K drops so ratings stabilize and don't swing wildly after a single bad match.

4 Context Multipliers

Not every match carries equal weight. The engine applies several multipliers on top of the base rating change:

Division tier

Event levelOpen (O)USA (U)Club (C)
Basemost events (leagues always rate as USA)1.0×0.5×0.5×
Super-Regional eventbase + 0.1, by Competitive Index1.1×0.6×0.6×
National eventbase + 0.2, by Competitive Index1.2×0.7×0.7×

Open-division matches carry full weight — that's the strongest competition and the most reliable signal of team quality. USA and Club matches count for half. A win in Club doesn't tell us as much about a team's ceiling as a win in Open, so it moves the rating less.

Divisions with no tier in their name are rated as USA. Local events — leagues, play dates, warmups and mini-club days — usually name divisions by age only ("16 Boys"), and the rule of thumb is that local play is USA tier. Qualifiers and national events name their tiers; if one doesn't, it is flagged for review rather than assumed.

Leagues are rated as USA. A regional power league — the same teams coming back round after round on separate weekends — is rated as USA throughout, whatever its divisions are called: 0.5×, the USA entry rating, and no Open matches. Higher tiers are earned at tournament-format events (a 1–4 day block of play: nationals, qualifiers, invitationals). An event counts as a league when at least half its teams play a second round more than four days after their first; known leagues are also listed by name so they are treated as leagues from their first weekend. By committee decision a few regional tournaments are also weighted 0.5× in every division, Open included, to match regional play elsewhere in the country; unlike a league, their divisions keep their own entry ratings. In 2026-27 those are the UBVA Seeding Tournament and UBVA Kings Peak Seeding. In the other direction, SoCal Cup: The Open Championship and the Nike Steel City Boys Championship never weigh less than 1.0×; a high Competitive Index tier can still raise them above that.

Stronger events weigh more. At a tournament-format event the multiplier rises with the event's Competitive Index (§8): +0.1 for a Super-Regional event, +0.2 for a National one, as in the table. The index is on fixed scales (states represented and team count), so an event's bonus is settled by its own field and never shifts as other events are added.

Division entry anchors

TierEntry rating
Open1500
USA / Premier1500
Club1500

Every team enters the pool at 1500, whatever division its first match is in. Every team opens its season in regional and league play, so no division earns a head start; strength between divisions comes only from the division multipliers above (Open 1.0×, USA and Club 0.5×) and from teams crossing over. The anchor is also the confidence-blend target in §5. In force from the 2026-27 season, replacing tiered anchors (Open 1550 / USA 1500 / Club 1450) used earlier in the season; the anchors remain committee-tunable settings per tier.

Crossover matches carry the division they're played in. When a Club-rostered team enters an Open division at an event, those matches count at the full Open 1.0× — crossover play is the calibration bridge between tiers, and the system rewards it.

Bracket vs pool

Pool-play and bracket matches currently carry the same weight (1.0×). The engine supports a bracket bonus, but it's disabled in the current settings because the sample of scouted matches already skews toward competitive pools.

Head-to-head dampening (same tournament)

If two teams meet multiple times in the same tournament (e.g., pool then gold bracket), the engine progressively dampens the rating change so a single event doesn't dominate:

MeetingMultiplier
1st1.0×
2nd0.75×
3rd+0.5×

Tournament quality weight

Some tournaments draw stronger fields than others. Individual events can be weighted up or down by an admin-configurable multiplier (typically between 0.5× and 1.0×) to reflect field strength. The biggest events currently carry the full 1.0× weight; regional and mid-tier events are weighted lower.

5 Confidence & Display Rating

A team that's played 40 matches has a rating we can trust. A team that's played 3 matches does not — those three results might be wildly atypical. Instead of showing raw ELO to everyone, the dashboard shows a confidence-blended display rating:

display_ELO = raw_ELO × confidence + entry_anchor × (1 − confidence)

Confidence ramps linearly from 0 to 1 over the first 15 matches. A team with only 5 matches gets confidence = 5/15 ≈ 0.33, so its display rating is pulled about two-thirds of the way back toward its entry rating (1500 for every team — see §4). This prevents fresh teams with a lucky weekend from leapfrogging established programs on the leaderboard, and keeps a low-sample Club team anchored to where its division enters the pool rather than a flat 1500.

Teams with fewer than 20 matches are flagged as provisional in the rankings — their rating is shown but tagged as preliminary.

6 Safeguards

Chronological processing

Matches are sorted by date before processing. This matters: an October win against a team that later develops into a powerhouse should use that team's October rating, not their April rating. Out-of-order processing would inflate or deflate the signal.

Forfeit filtering

Sets with a 25–0 or 0–25 scoreline are treated as forfeits and excluded from ELO processing entirely. Forfeit scores would corrupt the point-differential layer.

ELO floor

Ratings can't drop below 800. This prevents teams from being driven into statistical oblivion after a rough stretch — they stay in the system so future results can still pull them back toward their true level.

Open-résumé seeding gate

The top 48 places of each age group's rankings — the size of the Open field — are reserved for teams that played in the Open division of one of this season's Open qualifiers: JVA The Reckoning, Boys Winter Invitational, SoCal Cup: The Open Championship, JVA Brew City Battle, Nike Steel City Boys Championship or SoCal Cup: The Winter Formal. This matches the rule for Open: a team must play in one of those Open divisions to be considered. Any match counts, rated or not; it is entering the division that qualifies. Each event is confirmed by the committee once its results are in, so a similarly named event can't qualify teams by accident. A team without one is capped just below the band — flagged No Open in the rankings — no matter how high its rating climbs. The rating itself is never altered; only the seeding order. In force from the 2026-27 season; the band size and the qualifier list are committee-tunable settings.

The gate only applies once some team in the age group has played a qualifier's Open division. Until then (early in the season, before the first qualifier) there is nobody to reserve the band for, so the rankings stay in rating order and no team is tagged. The gate also stands aside on any age group with fewer than 48 ranked teams, since early in the season not every team has played yet. A division whose name carries no tier (a plain "16 Boys") is treated as USA.

Cross-division merging

A team that plays in both 16 Open and 16 Club (or similar) is merged into a single entry in the universal rankings. Their ELO history across the tiers of one age group is stitched together chronologically and their match totals are summed. The merge happens only within an age group — the rule below is its complement.

Playing up: the age offset

Every match is rated, including matches between teams of different ages — a 15s team playing in an 18U league, a 12s team in a 14s division. To keep a team that plays up from being penalised for taking on older opponents, the rating formula gives the older team a head start of 20 rating points per year of age difference (capped at 4 years) when it works out the expected result. The ratings themselves are not changed; the offset only sets the expectation, the way home-court advantage works in other rating systems. So a 15s team losing to an 18s team at equal ratings was expected to lose (about a 59% chance for the 18s team), and gives up fewer points than it would to a 15s team; beating that 18s team earns more.

The offset is deliberately small. Fitted on the 2026-27 matches to date, about 20–40 points per year predicts results between adjacent ages best (a 15s team against a 16s team, a 17s team against an 18s). Teams that play two or more years up do better than their age alone predicts — the strong teams are the ones that choose to play up — so a larger offset would over-reward them. Before October 2026, matches across rating pools were recorded but not rated.

Strength of schedule

The rankings show each team's strength of schedule (SOS): the average rating of every opponent it has played, counting an older opponent higher by the same age offset — a 1500-rated 18s team counts as 1560 for a 15s team. It is there so a team that seeks out the strongest competition gets credit for it in plain view. SOS is context only and never changes the rating or the rank.

A team's age group — the rankings it is listed in — is the age in its USA Volleyball team code: the two digits after the gender letter, so b15sclege1sc is a 15s team. Division labels can't be trusted for this: mixed-age divisions are common (SoCal Cup "16/15" and "18/17", league "16 Boys" divisions that hold 15s) and are labelled by either the older or the younger age, so the division says where a team played, not what age it is. A team without a USAV code (AAU-only events, some tournaments) is listed by the age in its name ("Salt City Boys 17 Salty Reed" is a 17s team; "17/18" lists under the older age), which agrees with the code for 99% of teams that carry one; a name with no age falls back to the age group the team played most of its matches in. Only a real USAV code counts as one: some result systems let organisers type free text into the code field (partial codes, AAU ids, a club name shared by several teams), and that text is ignored so it can never merge two different teams.

A team's home pool — the scale its rating lives on — follows from its age group. Boys are pooled in two-year bands: 11s with 12s, 13s with 14s, 15s with 16s, 17s with 18s; girls by single age. Since every match is rated, the pools are linked through the matches between them, and the age offset applies to any match between different ages, whether or not the pools differ.

7 Honest Limitations

Data coverage is incomplete. The rankings only include matches from tournaments that published results on AES or SportWrench and that have been ingested. Regional events, pre-season scrimmages, and events that don't publish scores are invisible to the model. A team that only plays unscored events will have no rating.
Roster changes aren't modeled. ELO assumes the "team" is the stable unit. If a 17s squad loses three starters mid-season, their rating doesn't know that. Treat early-season ratings with more skepticism than late-season ones.
Regional isolation. ELO only propagates strength through actual matchups. If the Pacific region and the Northeast region rarely play each other, their ratings aren't directly comparable — they're two weakly-connected graphs. Inter-regional events (SoCal Cup, Badger, SacTown) are the bridges that calibrate across regions, which is why those tournaments get full weight. Geographically isolated programs — Puerto Rico and Hawaii above all — can rarely reach multiple mainland events in a season, so their samples stay small: confidence anchoring and provisional tags keep their ratings conservative until they meet the field, and their home events are priority additions to the data set.
Ratings reflect results, not potential. This isn't a projection model. It's a summary of what's happened on the court with the data we have. A team with a tough early schedule and some narrow losses may be underrated relative to their ceiling.

8 Tournament Competitive Index

The Tournaments page ranks every event in the database with a 0–100 Competitive Index that answers the question: how strong was the field at this tournament?

The score is built on fixed scales: an event's score depends only on who came to it. Adding another event to the database never moves it, and it means the same in October as in June. (Before the 2026-27 season the index ranked events against each other, so the biggest of a handful of early-season events scored "National" by default.)

The two factors

FactorWhat it measuresFull marks atWeight
Geographic ReachNumber of distinct states represented20 states60%
Field SizeNumber of teams, log-scaled500 teams40%
index = 100 × ( 0.6 × min(1, states / 20) + 0.4 × min(1, log(1 + teams) / log(501)) )

Geography carries the heaviest weight because it's what most separates a genuine national event from a loaded regional. A stacked invitational can have elite top-end teams, but if every team is from the same area it's a regional battle, not a national one. The log scale on size means a 100-team event already earns about 74% of the size marks, so a big field helps but can't stand in for reach.

Why no ratings in the index. The index sets a rating bonus, so it can't be built from the ratings it helps set. And ratings early in a season sit close to the 1500 start, so an Elo-based score would mark every autumn event down whatever its field. Top-10 strength and field depth are still shown on the Tournaments page for reference, but they are not scored.

How reach is measured. Each team is placed in a state from, in order: a curated lookup table (club_states.js, by team or club name; researched entries cite their source in club_states_sources.json), the state a result system reports for the team, and the team's USA Volleyball region when that region lies inside one state (Northern and Southern California, Arizona, Florida, Great Lakes, Palmetto). Club names repeat across states, so a name match is thrown out when the team's region code rules that state out — a Rocky Mountain team is never counted as the Indiana club that shares its name. The reach factor counts the distinct states represented at the event. A team with no state adds nothing to reach, so keeping the table complete matters; it currently places 92% of this season's teams.

Tier labels

TierScore threshold
National75+
Super-Regional55 – 74
Regional30 – 54
Local< 30
The index sets a rating bonus. From the 2026-27 season a tournament-format event's index tier raises its division multipliers (§4: Super-Regional +0.1, National +0.2); league-format events get no bonus. Manual per-event weights in tournament_weights.json still apply on top.

9 Reproducibility

The pipeline is deterministic. Given the same input CSV and the same settings file, running the rebuild script produces the same ratings every time. The inputs are:

  • combined_all_tournaments.csv — raw match results (teams, sets, division, date, source)
  • elo_settings.json — layer weights, K-factors, tier multipliers, thresholds
  • tournament_weights.json — per-event quality multipliers
  • club_aliases.json — name normalization for clubs with duplicate spellings

Found a bug or have a suggestion? Use the Contribute page to submit an event, flag a duplicate, or share feedback.

Last updated: July 2026