An empirical study ·

What is a Lichess rating
worth on Chess.com?

A conversion fitted on rating pairs from players with established ratings on both sites, through a model that tells a player who uses the same username on both sites from a stranger who happens to share it.

Lichess speed
Lichess rating
Chess.com rating

1The short answer

Below about 2000, the same player is rated lower on Chess.com than on Lichess, by several hundred points for beginners. The gap narrows as players get stronger, and in blitz it closes, then reverses at the top. A Lichess rating is a Chess.com rating plus a gap that depends on the speed and the level: there is no single offset.

Chess.com rating for each Lichess rating

The gap: Chess.com minus Lichess

Each curve is drawn where at least 25 players stand within 100 points of it. Lichess's classical is compared with Chess.com's rapid, where those games are played. The faint band around each curve is the 95% bootstrap interval of the curve itself.

The conversion table

The Chess.com rating of a Lichess rating, and ± the half range in which the middle half of players stand. Also as CSV and JSON.

2The data

Neither site says who has an account on the other, so the pairs have to be found. The collection started from Lichess's open database and asked both sites' public APIs about each player, at a polite pace. It ran for about nine hours on 20 and 21 October 2026.

  1. Players with a settled rating. A slice of September 2026's dump of rated games (the first 800 MB of the compressed file) names players. A player is kept in a speed when they played at least three games in it and their rating moved by 20 points or less in the median game: a provisional rating moves by 30 or more.
  2. The same username on Chess.com. Each was looked up on Chess.com's published-data API, in a random order, until every one had been. An account counts as active with at least 20 games in a speed, the last one in the past 180 days.
  3. Their Lichess profile. For each active match, Lichess's user API gave the current ratings (only those that aren't provisional, with an RD under 110), the flag, and a link to a Chess.com account if the profile has one. Closed accounts and those marked for a terms-of-service violation are left out.
  4. The pairs. A pair is one speed in which both ratings rest on at least 100 games, with a Chess.com RD of at most 90 and a last Chess.com game in the 90 days before the collection ended. Players with hundreds of games on one site and a few dozen on the other aren't at their level on both yet, so the floor is on both sides.

From the dump to the pairs

A player can make up to four pairs, one per speed. The Lichess profiles that link to a Chess.com account were matched to that account rather than to the same name. correspondence pairs (Chess.com's daily) were too few to fit.

The speeds don't quite match. Both sites class a game by its estimated length, the base time plus 40 times the increment, but they cut at different lengths: Lichess's blitz ends at 8 minutes, and Chess.com's at 10. So a 10+0 game is rapid on Lichess and on Chess.com, but an 8+0 game is rapid on Lichess and blitz on Chess.com.

3The namesake problem

Most pairs are found through a shared username, and a username isn't a person: alex on Lichess and alex on Chess.com are often two different people. Their two ratings then have nothing to do with each other, and they pull any plain average toward the middle of the Chess.com ratings. That's what a straight least-squares line, or the median Chess.com rating at each Lichess rating, does here: both flatten the curve at both ends.

Dropping the pairs that look wrong would bias the answer toward what we expect. Keeping only pairs whose profile links to the other account would leave too few of them, as only profiles do. So the model below keeps every pair, and lets each one be, with some probability, a stranger.

Blitz: three ways to read the same pairs

Each dot is a pair (a random sample of 3,000), its opacity the probability, under the model, that both accounts are the same player. The pale cloud spread over the whole square is the namesakes.

How sure the model is of each pair, per speed: most pairs are clearly one player (right) or clearly two (left), with few in between.

4The model

Each speed is fitted on its own. Its pairs are \((x_i, y_i, g_i)\) for \(i = 1, \dots, n\): the Lichess rating \(x_i\), the Chess.com rating \(y_i\), and the kind of pair \(g_i\), which is one of these:

link
the Lichess profile links to the Chess.com account;
same-country
the same username, and both profiles name the same country;
other-country
the same username, and the two profiles name different countries;
no-country
the same username, and at least one profile names no country.

A mixture of the same player and a stranger

Let \(z_i = 1\) when both accounts belong to the same player. The chance of that depends only on the kind of pair, \(\Pr(z_i = 1) = \pi_{g_i}\). The same player's Chess.com rating is spread normally around a curve \(f\) of their Lichess rating, with a spread \(\sigma\) that may change along it. A stranger's Chess.com rating has nothing to do with \(x_i\): it is drawn from \(b\), the distribution of Chess.com ratings among the accounts found.

$$ y_i \mid z_i = 1 \;\sim\; \mathcal N\!\bigl(f(x_i),\, \sigma(x_i)^2\bigr), \qquad y_i \mid z_i = 0 \;\sim\; b . $$

Not knowing \(z_i\), each pair's likelihood is the mixture of the two,

$$ p(y_i \mid x_i, g_i) \;=\; \pi_{g_i}\,\frac{1}{\sigma(x_i)}\,\varphi\!\left(\frac{y_i - f(x_i)}{\sigma(x_i)}\right) \;+\; \bigl(1 - \pi_{g_i}\bigr)\, b(y_i), $$

where \(\varphi\) is the standard normal density. The shares \(\pi_g\) can be told apart from the curve because strangers don't follow it: pairs far from the curve, at any Lichess rating, say how many strangers there are.

A curve that can only rise

A stronger player on Lichess is not expected to be weaker on Chess.com, so \(f\) is kept non-decreasing. It is piecewise linear on knots \(t_k = t_0 + kh\), every \(h = 100\) points, from \(t_0\), the 0.5th percentile of the \(x_i\) rounded down to a hundred, to \(t_K\), the 99.5th rounded up. Its values at the knots are built from free parameters \(\alpha, \beta_1, \dots, \beta_K\) as

$$ c_0 = \alpha, \qquad c_k = c_{k-1} + h\,\operatorname{softplus}(\beta_k), \qquad \operatorname{softplus}(u) = \log\bigl(1 + e^{u}\bigr), $$

so its slope on each piece, \(\operatorname{softplus}(\beta_k)\), is always positive, with no constraint on the optimizer. Outside \([t_0, t_K]\) the curve stays flat, and the table leaves those ratings out anyway.

The spread is piecewise linear too, on coarser knots \(s_j\) every 400 points, through \(\sigma(s_j) = e^{\gamma_j}\), which keeps it positive. The shares go through a logistic, \(\pi_g = 1 / (1 + e^{-\delta_g})\).

The strangers' distribution

\(b\) is the speed's Chess.com ratings \(y_1, \dots, y_n\), binned in 25-point bins over \([0, 3600)\), with half a count added to each bin, smoothed by a Gaussian kernel with a standard deviation of 4 bins (100 points) truncated at 8, and normalized so that \(\int b = 1\). This assumes a namesake is like any account found by a name. Strictly, the \(y_i\) also hold the true pairs' ratings, but smoothing their marginal changes little to a density as broad as \(b\).

The fit

All parameters \(\theta = (\alpha, \beta, \gamma, \delta)\) minimize the negative log-likelihood, plus a penalty on the curve's second differences that lets it bend only where the data asks:

$$ \hat\theta \;=\; \arg\min_\theta \; -\sum_{i=1}^{n} \log p(y_i \mid x_i, g_i) \;+\; \lambda \sum_{k=1}^{K-1} \left(\frac{c_{k+1} - 2c_k + c_{k-1}}{h}\right)^{\!2}, \qquad \lambda = 2 . $$

The minimum is found by L-BFGS-B, started from the least-squares line \(y = a x + c\): \(\alpha = a t_0 + c\), every \(\beta_k = \operatorname{softplus}^{-1}(\max(a, 0.2))\), \(\sigma = 150\) and \(\pi_g = \tfrac12\).

Which pairs are the same player

Once fitted, Bayes's rule gives each pair's probability of being the same player,

$$ w_i \;=\; \Pr(z_i = 1 \mid x_i, y_i, g_i) \;=\; \frac{\pi_{g_i}\, \sigma(x_i)^{-1} \varphi\bigl((y_i - f(x_i)) / \sigma(x_i)\bigr)}{p(y_i \mid x_i, g_i)}, $$

and \(\sum_i w_i\) is the expected number of true pairs. This \(w_i\) is the same_player_probability column of the published data.

From the curve to the table

The table gives, every 50 points, \(f(r)\) and a spread read off the players themselves rather than off \(\sigma\). Let \(N(r) = \{ i : |x_i - r| \le 100 \}\) and \(e_i = y_i - f(x_i)\). A row is kept only if \(\sum_{i \in N(r)} w_i \ge 25\), and its spread is half the interquartile range of the \(e_i\) in \(N(r)\), each weighted by \(w_i\):

$$ s(r) \;=\; \tfrac12\Bigl(Q^{w}_{0.75}\bigl(\{e_i\}_{i \in N(r)}\bigr) - Q^{w}_{0.25}\bigl(\{e_i\}_{i \in N(r)}\bigr)\Bigr). $$

So half the players of a Lichess rating \(r\) stand between \(f(r) - s(r)\) and \(f(r) + s(r)\) on Chess.com. For a normal spread \(s = 0.674\,\sigma\), but \(s\) doesn't rely on the normal shape.

How sure the curve is

The curve's uncertainty comes from a nonparametric bootstrap: times, \(n\) pairs are drawn with replacement from the speed's \(n\), and the model is fitted again, on the same knots, from \(\hat\theta\). The 2.5th and 97.5th percentiles of the refitted curves, at each rating, bound the 95% band drawn around the curves. That band measures the noise of the sample only. It doesn't cover a bias in who is in it (see the limits).

The curve estimates \(\mathbb E[y \mid x]\): the Chess.com rating of a player of a given Lichess rating. Read backward, it does not give the Lichess rating of a player of a given Chess.com rating. With spreads of 100 to 200 points, the two regressions differ, most at the ends, where the curve's inverse overshoots. A Chess.com-to-Lichess table needs its own fit, the roles of \(x\) and \(y\) swapped.

5Speed by speed

The fitted curve over each speed's pairs. The band around it holds the middle half of the players, and the ringed dots are the pairs whose Lichess profile links to the Chess.com account: the only ones known to be one player. Hover a chart to read it.

The share of same players, by kind of pair

\(\hat\pi_g\) and its 95% bootstrap interval. The country is a strong clue: two accounts with the same name and the same flag are almost always one player, two accounts with different flags often aren't.

6Checks

The pairs known to be one player

The model never sees which pairs are links, except through \(\pi_{\text{link}}\). If its curve held for every player, the linked pairs would sit around it: a median gap near zero, and about half of them within \(\pm s\). They don't quite. In bullet and blitz, they sit about 30 points above the curve, more than chance gives, while the other kinds of pairs sit on it.

The median gap of the linked pairs to the curve, with its 95% bootstrap interval, and the share of them within the table's \(\pm s\). The other kinds of pairs are shown for comparison, each pair weighted by \(w_i\).

Players rate higher where they play more

Across all pairs, the gap to the curve follows the number of games played on Chess.com. Two players with the same Lichess rating don't have the same Chess.com rating if one has played 200 games there and the other 5,000: the second is rated higher, by 75 to 115 points. Games played on Lichess matter much less: players with few of them stand 15 to 20 points above the curve, and the others on it.

That fits what one would expect. A rating rises as a player gets used to a site's pool, its clocks and its opponents, and a player still climbing hasn't caught up with their level yet. The curve is an average over the sample's mix of players: one who plays mostly on Lichess can expect a Chess.com rating below the table's, and one who plays mostly on Chess.com, above it.

That doesn't explain the linked pairs, though: they have about the same mix of games as the others, which predicts a gap of a few points, not 30. Their gap grows with the rating instead (in blitz, +6 below 1500, +25 from 1500 to 2000, +54 above). It may come from who links their accounts: at the top, often streamers and titled players, whose main site is Chess.com. With fewer than 200 linked pairs per speed, that's a lead rather than a finding.

Gap to the curve, by games on Chess.com

Gap to the curve, by games on Lichess

Each dot is the median gap \(y_i - f(x_i)\) of a speed's pairs in a range of games played, each pair weighted by \(w_i\), with its 95% bootstrap interval. Ranges with fewer than 30 pairs are left out.

More games, same curve

The floor of 100 games on each site is a choice. Fitting again on the pairs with at least 250 games on both sites, then 1,000, keeps fewer and more seasoned players. If the curve moved much, the floor would be shaping the answer. From 250 games, it hardly moves: a few points in blitz, at most 16 elsewhere. From 1,000, it rises by 10 to 20 points over most of the range, as the players' experience on Chess.com, shown above, predicts.

The refitted curve minus the main one, for each Lichess rating. The shaded band is the main curve's 95% bootstrap interval, centered on zero.

Is the spread normal?

The model assumes a player's Chess.com rating is spread normally around the curve. The standardized gaps \((y_i - f(x_i)) / \sigma(x_i)\), each pair weighted by \(w_i\), should then follow the standard normal. They do, closely: 69.5% of the weight is within one \(\sigma\) (68.3% for the normal), and the tails are a little heavier, 0.35% beyond three \(\sigma\) against 0.27%.

Bars: the weighted standardized gaps. Line: the standard normal density.

7Limits

8Data and code

Everything is on GitHub, and each release attaches the data as files.

To fit everything again from the published pairs (Python 3 with numpy and scipy, a few minutes):

git clone https://github.com/theophile-wallez/lichess-chesscom-ratings
cd lichess-chesscom-ratings
pip install -r analysis/requirements.txt
python3 analysis/analyze.py

The code is under the MIT license, the data under CC BY 4.0. This study was made for Lichess Neo, a browser extension that can show a Lichess rating's Chess.com equivalent. It is not affiliated with Lichess or Chess.com.