Leaderboard Overview
This guide explains how Phoenix leaderboards are modeled so you can design meaningful competitions before touching the Admin API. It focuses on the configuration shape you submit when creating or updating a leaderboard.
1. Mental Model
- Leaderboard – a named competition scoped to a tenant. Each leaderboard owns a configuration document that defines who can enter, which events award points, and how standings are ranked.
- Time window – the period during which scores accumulate (e.g., hourly, weekly, custom). Each window produces a unique
window_keythat the Query Gateway uses to fetch live or completed results. - Entry – a user’s cumulative score inside a single window. Entries exist as long as the window is active or until archived in historical storage.
Once a configuration is active, every ingested event is evaluated against its rules. Matching events modify the user’s entry for the current window; non-matching events are ignored for that leaderboard.
2. Lifecycle & Status
| Status | Meaning | Typical Use |
|---|---|---|
active | Leaderboard is currently receiving events and available via Query/WebSocket endpoints. | Default after creation. |
inactive | Configuration remains stored but events are ignored. | Pause seasonal content without losing history. |
archived | Fully retired; no new events, primarily kept for auditing or snapshots only. | Sunset legacy competitions. |
Switching back to active re-enables scoring immediately for future events.
3. Configuration Snapshot
Every leaderboard config follows this top-level structure:
{
"scope": {
"filters": {
"actor.metadata.region": { "eq": "na-east" },
"attrs.mode": { "in": ["ranked", "tournament"] }
}
},
"timeframe": {
"type": "weekly",
"timezone": "UTC",
"reset_day": "monday",
"reset_time": "00:00"
},
"scoring": {
"rules": [
{
"event_type": "match.completed",
"points_expression": "attrs.score",
"conditions": {
"attrs.victory": { "eq": true }
}
},
{
"event_type": "match.completed",
"points_expression": "attrs.score * 0.5"
}
],
"aggregation": "sum"
},
"ranking": {
"method": "score_desc",
"size": 1000,
"min_score": 0
}
}Each section is detailed below.
4. Scope Filters
- Optional
scope.filtersobject lets you restrict participation by evaluating JSON paths against each event. - Keys use dot notation (e.g.,
actor.metadata.platform,attrs.weapon). - Values can be:
- Simple comparisons:
{ "eq": "ios" },{ "ne": "bot" } - Numeric operators:
{ "gt": 10 },{ "lte": 100 } - Membership:
{ "in": ["ranked", "scrim"] }
- Simple comparisons:
- If
scopeis omitted, every event for the tenant may enter the leaderboard (subject to scoring rules).
Use scope filters to run simultaneous competitions on different segments without duplicating events.
5. Timeframes & Windows
| Type | Description | Additional Fields |
|---|---|---|
real_time | Always-open window; standings never reset automatically. | — |
hourly | Resets every hour at reset_time (defaults to 00:00). | timezone (optional) |
daily | Resets once per day at reset_time. | timezone (optional) |
weekly | Resets on the specified reset_day + reset_time. | timezone, reset_day, reset_time |
monthly | Resets on the first day of each month at reset_time. | timezone, reset_time |
custom | Resets based on custom_duration_seconds from the moment it becomes active. | custom_duration_seconds (required) |
Recommendations:
- Always set
timezonefor user-facing competitions; otherwise UTC is assumed. - Weekly leaderboards must specify
reset_day. - Custom durations are perfect for limited-time events (e.g., 6-hour flash competitions).
Each new window receives a unique window_key (e.g., 2025-11-18T12 for hourly), which clients can request explicitly or let Phoenix resolve automatically when querying.
6. Scoring Rules
Scoring determines how raw events convert into leaderboard points.
- Match by event type – specify an exact string or
*wildcard to match all events. - Guard with conditions – evaluate arbitrary attributes before awarding points.
- Compute points –
points_expressionsupports:- Literals:
100 - Attribute references:
attrs.coins_spent,actor.metadata.multiplier - Basic math:
attrs.score * 0.1 - 50 - Functions:
min(a, b),max(a, b),abs(x)
- Literals:
Rules are evaluated top-to-bottom. The first matching rule produces a score for that event; later rules are ignored for the same event.
7. Aggregation Strategies
The scoring.aggregation value defines how multiple events per user combine within the window:
| Aggregation | Behavior | Common Use Cases |
|---|---|---|
sum | Adds new points to the existing score (default). | XP, points, currency totals. |
count | Increments by 1 for every matched event (ignores points value). | “Most matches played”, “Daily logins”. |
max | Keeps the highest single-event score. | “Best lap time”, “Highest damage in one run”. |
min | Keeps the lowest single-event score. | “Fastest completion time” (lower is better). |
avg | Maintains the running average of event scores. | Quality-based metrics (accuracy, rating). |
Choose a strategy that aligns with the story you want to tell. For example, max avoids penalizing players who keep attempting a challenge after setting a high watermark.
8. Ranking Settings
method– determines how Phoenix orders the leaderboard:score_desc: highest score first (default).score_asc: lowest score first (useful for speedruns).time_asc: tie-breaker that favors earlier achievements (relies on event timestamps).
size– optional hard cap on visible entries (1–10,000). Useful for “Top 100” style boards.min_score– optional floor; users below this score are omitted even if they have activity.
Phoenix automatically assigns ranks starting at 1. Users who tie on score share the same rank; the next rank accounts for the tie (dense ranking).
9. Rewards & Snapshots
- Reward definitions live separately (via the Rewards API) but can be linked to a leaderboard.
- When a window finishes, Phoenix stores a snapshot of standings plus (optionally) the reward configuration in effect.
- Query responses include
reward_configfor completed windows so clients can display prize tiers alongside historical results.
Plan your rewards with the window cadence in mind—e.g., weekly rewards for weekly timeframes to keep player expectations clear.
10. Best Practices Checklist
- Use descriptive
leaderboard_idvalues (xp-weekly-global) to simplify analytics. - Keep scope filters minimal; complex filters belong in your ingestion pipeline.
- Validate configurations with Phoenix’s Admin API before activating them in production.
- Document each leaderboard’s purpose and reward schedule for your support team.
- When testing, start with small windows (hourly/custom) so you can iterate quickly.
With these concepts in mind, proceed to Creating Leaderboards for API-specific instructions on provisioning, updating, and deleting leaderboard configurations.