Ties

The requirements say ties go to whoever reached the rating first. Players 5512 and 90311 both have a blitz rating of 2140:

  • Player 5512 reached 2140 on Oct 28, 2026, at 20:15:00 UTC.
  • Player 90311 reached 2140 on Nov 3, 2026, at 15:02:44 UTC.

So player 5512 must be ranked higher.

A sorted set orders members with equal scores by the member itself, compared as text. Our members are player IDs, so equal ratings are ordered by player ID, not by time. With REV, “90311” comes before “5512”, because 9 comes after 5. So player 90311 would be ranked higher. That breaks the requirement.

Putting the time in the score

The fix is to put the time into the score, after the rating. I use this score:

score = rating × 10¹⁰ + (9,999,999,999 − the Unix time in seconds)

A Unix time is the number of seconds since the start of Jan 1, 1970, UTC. In 2026, a Unix time has 10 digits.

  • The rating is in the digits above the lowest 10. So the rating decides the order first.
  • The lowest 10 digits hold 9,999,999,999 minus the time. An earlier time gives a larger number there. So for equal ratings, the player who reached the rating earlier has the larger score. That player is ranked higher.

For the two players:

  • Player 5512 reached 2140 at Unix time 1,793,218,500. . So the score is 21,408,206,781,499.
  • Player 90311 reached 2140 at Unix time 1,793,718,164. . So the score is 21,408,206,281,835.

Player 5512’s score is larger, so player 5512 is ranked higher.

If two players reach the same rating in the same second, their scores are equal. Then the sorted set falls back to ordering them by player ID. That case is rare, so I accept it.

The leaderboard still shows the rating, not the score. The leaderboard service gets the rating back by dividing the score by and dropping the remainder.

The size of the score

Redis keeps a score as a 64-bit floating-point number. A 64-bit floating-point number holds every whole number up to about exactly. Chess ratings stay well below 3,500, so the largest score is below , which is . That is far below , so every score is exact.

Ties in the player database

The player database could break ties the same way with its index. An index on (time_control, rating, reached_at) puts equal ratings in order of reached_at. A player’s rank would then count the higher ratings, plus the equal ratings reached earlier.

Sharing a rank

Another choice is to let players with equal ratings share a rank. That is simpler, but it changes the requirement. In an interview, you would agree on it with the interviewer first.