The short version

  • Everyone starts at 1500. Every confirmed match moves it.
  • Beating a stronger player earns more than beating a weaker one.
  • A clear win counts a bit more than a close one.
  • New players move fast. The number settles as you play more people.
  • Your opponent confirms each score, so you can't rate yourself.

Every match is evidence.

Most sports make you choose: enter a sanctioned tournament to get a real number, or play for fun and stay invisible. UTR locks its full picture behind paywalled tiers and weighs its rating toward tournament play. National federations move slower and rarely show their work. If you're not competing at that level, you don't get a rating — you get a guess.

RankedCourtsrates every confirmed match — league night, a hit with a friend, a club ladder — and it's free. The math on this page is the same math running behind your rating right now, not a simplified version for public consumption.

We also don't believe one algorithm fits every sport. Tennis gets the model on this page. Padel has its own, built for doubles: how padel levels work.

How it works in 60 seconds

Your rating is an estimate, not a fact.

Every rating ships with a confidence band that narrows the more you play.

Beat someone better, jump further.

Upsets move your rating more than expected wins — the reverse is true for losses.

Domination counts.

A 6-0, 6-0 win moves your rating more than a 7-6, 7-6 win over the same opponent.

Confidence fades if you disappear.

Sit out 60+ days and your rating's uncertainty widens back out.

For the nerds and the critics

This is the exact math running in production — every constant below is read live from packages/algorithms/src/tennis.ts, not restated by hand.

RankedCourts runs Glicko-2 underneath every rating. μ is your rating and φ is your rating deviation (RD), both converted onto Glicko-2's internal scale before any update runs.

Step 1 — scale conversion

μ = (r − 1500) / 173.7178 φ = RD / 173.7178

Step 2 — opponent impact g(φⱼ)

g(φ) = 1 / √(1 + 3φ² / π²)

An opponent you're less sure about (higher φⱼ) counts for less.

Step 3 — expected score

E(μ, μⱼ, φⱼ) = 1 / (1 + e^(−g(φⱼ)·(μ − μⱼ)))

The probability you were expected to win, before the match.

Step 4 — estimated variance

v = 1 / Σⱼ [ g(φⱼ)² · E · (1 − E) ]

Step 5 — Δ — your surprise

Δ = v · Σⱼ [ g(φⱼ) · (sⱼ − E) ]

sⱼ is the real outcome — but not a flat 1 or 0. RankedCourts folds margin of victory in here (below).

Step 6 — new volatility σ′

An iterative root-finder (the Illinois algorithm) solves for σ′ — how erratic your recent results have been — bounded by the system constant τ = 0.5, which controls how fast volatility is allowed to move.

Step 7 — new RD and rating

φ* = √(φ² + σ′²) φ′ = 1 / √(1/φ*² + 1/v) μ′ = μ + φ′² · Σⱼ [ g(φⱼ)·(sⱼ − E) ]

Converted back: r′ = 173.7178 · μ′ + 1500, clamped to 0–3000. RD is clamped to 30–350.

RankedCourts's additions

Margin of victory

A win doesn't score a flat 1.0. The margin dampener (0.8) folds in how lopsided the match was:

dominance = (winner's games − loser's games) / total games winnerScore = 0.5 + 0.5 · dominance · 0.8

6–0, 6–0 → dominance 1.00 → winner scores 0.90. 7–6, 7–6 → dominance 0.08 → winner scores only 0.53. Same result, same opponent — a very different sⱼ feeding Step 5. That's why a bagel moves your rating more than a squeaker.

Casual matches have their own separate rating. Mark a match Casual at logging and it moves your casual rating only. Matches with a guest count toward neither.

Inactivity decay

Ratings don't rot, but confidence does. After 60 days without a match, RankedCourts widens your RD before the next update runs:

φ_decayed = min(φ_max, √(φ² + c² · periods)) periods = days idle / 30, c = 34.64 / 173.7178

Provisional ratings

Under 10 matches, your rating is marked Provisional — the math works from match one, but a small sample deserves a caveat.

Reliability score

A separate 0–100 trust signal shown next to your rating: effective matches played (up to 80 points) plus a recency bonus (+20 within 30 days, +10 within 90), minus 20 while provisional. Effective, not raw, because repeat opponents count for less.

Who you played

Beating the same person repeatedly is weaker evidence than beating a field. Each rematch with an opponent you have already played counts for 0.6 of the one before it, so no single opponent is ever worth more than 2.5 effective matches. A narrow pool also puts a floor under your rating deviation: the ladder will not claim to be certain about a player it has only seen against one or two people.

FeatureRankedCourtsUTRELODUPR
Free✓✗—✓
Every match counts✓✗—✓
Uncertainty modeled✓✗✗✗
Margin of victory✓✓✗✓
Open math✓✗✓✗
Per-sport design✓✗✗✗

Based on each system's public documentation, not reverse-engineered. ELO is a formula, not a product — rows without a clear analog are marked with a dash.

The ranked ladder

A LoL-style tier skin painted over the rating above — not a second progression system.

Your ranked tier is rankedTier(rating, matchCount, globalRank) — a pure function. No LP to grind, no decay games to protect a rank, nothing stored anywhere except the rating itself. Cross a boundary and the badge updates on your next page load, because there's nothing else to update. That's the whole design: your rating is your rank.

Provisional

With no matches you are unranked. From your first match you get a real tier, tagged Provisional until you reach 10 matches, because a tier assigned off a handful of matches can still move a lot. The top-10 override below only applies once your rank is confirmed.

Divisions

Wood through Diamond each split into thirds — III (bottom) to I (top). Master, Grandmaster, and Pro don't divide further; by then the rating gaps between players are wide enough on their own.

Elite Ladder + the top-10 override

Master and above is "the ladder" — past Diamond I, every point still matters. One exception: if you're inside the global top 10, you show as Pro regardless of your band. A top-10 finish is proof enough on its own, even mid-season before your rating has caught all the way up.

TierDivisionsRating range
Wood
III · II · I0–900
Bronze
III · II · I900–1100
Silver
III · II · I1100–1300
Gold
III · II · I1300–1500
Emerald
III · II · I1500–1700
Platinum
III · II · I1700–1900
Diamond
III · II · I1900–2100
Master
—2100–2300
Grandmaster
—2300–2500
Pro
—2500–3000+

Ranges shown are inclusive of the lower bound. Divisions split each range into equal thirds.

See the math move

Win probability vs. rating gap

A +200-point favorite wins ~76% of the time.

Rating change vs. match margin

Same two 1500-rated players, same win — only the scoreline changes.

Rating deviation vs. days idle

Starting from RD 50 (an established player). Flat until day 60, then it widens back toward 350.

Try it yourself

This calls the same computeRatingUpdate function that runs in production — nothing here is simulated separately.

You

Opponent

Match result

6-0, 6-0

Rating change

+130

New rating

1630

New RD

±290

Win probability beforehand

50%
Provisional

Even matchup — winning with a wide margin earned you +130.

Free forever.

No paywalled tiers, no tournament requirement. Every match you log makes your rating a little more accurate.