Skip to content
Engine

Systems

LeaderboardSystem

Global leaderboards with daily, weekly and monthly resets, live in-server boards, and leaderstats for the player list, all replicated to clients.

SystemServerClient

Getting it

local LeaderboardSystem = Engine:GetSystem("LeaderboardSystem")

Overview

LeaderboardSystem covers the three kinds of rankings games usually need:

KindStoredUse it for
LeaderboardOrderedDataStore, across all servers"Top 100 all time", "Most wins this week".
LiveBoardIn memory, this server onlyKills this round, laps in this race.
StatThe player's leaderstats folderThe values shown in Roblox's player list.

Leaderboards and live boards replicate their top entries to every client, so building a board in the world or a UI is a matter of listening to one signal.

Server
local LeaderboardSystem = Engine:GetSystem("LeaderboardSystem")

local weeklyWins = LeaderboardSystem:CreateLeaderboard("Wins", { Period = "Weekly", Size = 50 })
local kills = LeaderboardSystem:CreateLiveBoard("RoundKills")
local coins = LeaderboardSystem:CreateStat("Coins", { Kind = "Int" })

local function onWin(player: Player)
	weeklyWins:IncrementScoreAsync(player, 1)
end

local function onKill(killer: Player)
	kills:Increment(killer)
	coins:Increment(killer, 10)
end
Client
local LeaderboardSystem = Engine:GetSystem("LeaderboardSystem")

LeaderboardSystem:WaitForLeaderboardAsync("Wins"):andThen(function(board)
	local function render(entries)
		for _, entry in entries do
			print(entry.Rank, entry.Name or entry.Key, entry.Value)
		end
	end
	render(board.Entries)
	board.Updated:Connect(render)
end)

Global leaderboards

CreateLeaderboard

LeaderboardSystem:CreateLeaderboard(name: string, options: LeaderboardOptions?): Leaderboard
OptionDescription
SizeEntries kept in the cached top list.
AscendingLowest first (for fastest times).
RefreshIntervalSeconds between automatic refreshes of the top list.
Period"AllTime" (default), "Daily", "Weekly" or "Monthly". Periodic boards start fresh at midnight UTC each day, each Monday, or the first of each month.
ScopeDataStore scope.
MinValue, MaxValueOnly include scores in this range.
ReplicateSend the top list to clients (default from ReplicateByDefault).
ResolveNamesLook up usernames for player keys, so entries carry Name.

:GetLeaderboard(name), :FindLeaderboard(name) and :GetLeaderboards() look boards up.

Leaderboard

MemberDescription
:SetScoreAsync(key, value)Sets a score. key is a Player (stored by UserId) or any string.
:IncrementScoreAsync(key, delta)Adds to a score.
:RemoveScoreAsync(key)
:RefreshAsync()Reloads the top list now.
:GetRank(key), :GetEntry(key)From the cached top list; nil when the key is not in it.
:SecondsUntilReset()For periodic boards.
:Destroy()
EntriesThe cached top list: { Rank, Key, Value, UserId?, Name? }.
Updated: Signal<entries>After every refresh.
PeriodChanged: Signal<(newKey?, oldKey?)>When a new day, week or month starts.
Name, Size, Ascending, Period, PeriodKey, Replicate, LastRefresh, RefreshInterval

Each period writes to its own ordered store (<name>/<periodKey>), so old periods stay available in the DataStore.

Live boards

CreateLiveBoard

LeaderboardSystem:CreateLiveBoard(name: string, options: { Size?, Ascending?, Replicate?, RemoveOnLeave? }?): LiveBoard

A sorted board kept in memory on this server. Entries of players who leave are removed by default (RemoveOnLeave).

MemberDescription
:Set(key, value), :Increment(key, delta?), :Get(key), :Remove(key), :Clear()
:GetRank(key), :GetEntry(key)
Entries, Updated: Signal<entries>
:Destroy()

:GetLiveBoard(name) and :FindLiveBoard(name) look them up.

Leaderstats

CreateStat

LeaderboardSystem:CreateStat(name: string, options: { Kind: "Int" | "Number" | "String"?, Default? }?): Stat

Adds a value to every player's leaderstats folder (including players who join later), which Roblox shows in the player list.

MemberDescription
:Get(player), :Set(player, value), :Increment(player, delta?), :Reset(player)
Changed: Signal<(player, value)>
:Destroy()Removes the stat from every player.

:GetStat(name) and :FindStat(name) look stats up. Stats are display values: save what matters in a DataService profile and mirror it into the stat.

Helpers

MethodDescription
:GetPeriodKey(period)The key of the current period in UTC: "2026-10-01" for a day, the Monday's date for a week, "2026-10" for a month, nil for all time.
:GetSecondsUntilReset(period)Seconds until the next day, week or month.
:ResolveNameAsync(userId)A cached username lookup.
LeaderboardUpdated: Signal<(board, entries)>, LiveBoardUpdated: Signal<(board, entries)>Any board updated.
LeaderboardCount, LiveBoardCount, StatCountRead-only.

Client

MemberDescription
:GetLeaderboard(name), :FindLeaderboard(name), :GetLeaderboards()Replicated boards (global and live).
:WaitForLeaderboardAsync(name, timeout?)Resolves once the board has arrived.
:RefreshAsync()Asks the server for every board again.
BoardAdded: Signal<Board>, BoardUpdated: Signal<(board, entries)>
IsReady, BoardCount

A client Board has Name, Kind ("Global" or "Live"), PeriodKey, Entries, LastUpdate, Updated, and :GetRank(key?) / :GetEntry(key?), which default to the local player.

Configuration

Defaults from DefaultConfiguration/Systems/LeaderboardSystem10 settings
SettingDefaultWhat it does
RefreshInterval60Seconds between automatic top-list refreshes of a Leaderboard.
Size100Entries a Leaderboard keeps in its cached top list when Size is omitted.
ResolveNamestrueLook up the username behind numeric keys so entries carry Name.
ReplicateByDefaulttrueSend every Leaderboard / LiveBoard top list to clients unless Replicate = false is passed.
ClientRequestRatePerSec1Per-player rate limit on the client's initial "send me every board" request.
ClientRequestBurst3Burst that request limiter allows.
LeaderstatsFolder"leaderstats"Name of the per-player folder the Roblox player list reads stats from.
LiveBoardSize100Entries a LiveBoard keeps in its sorted list when Size is omitted.
LiveBoardRemoveOnLeavetrueDrop a player's LiveBoard entry when they leave the server, unless RemoveOnLeave is passed.
ClientTimeout10Seconds the client's :WaitForLeaderboardAsync waits for a board before rejecting.

Types

export type Leaderboard
export type LeaderboardOptions
export type Entry = { Rank: number, Key: string, Value: number, UserId: number?, Name: string? }
export type Period = "AllTime" | "Daily" | "Weekly" | "Monthly"
export type LiveBoard
export type LiveBoardOptions
export type Stat
export type StatOptions
export type StatKind = "Int" | "Number" | "String"
export type BoardKind = "Global" | "Live"