What the scoring system does
The scoring system converts raw GitHub activity into ranked leaderboards for three entity types: contributors (individual users), repositories, and teams. Every leaderboard entry has a score, rank, breakdown by signal type, and optional code-addition/deletion counts.
Scoring runs in three sequential phases: ingest, score, and serve. Each phase is independently cacheable and can be skipped when fresh data is already available.
See Pipeline for the full phase-by-phase breakdown.
Entity types
| Entity type | Aggregation | Quotas & diminishing returns | Notes |
|---|---|---|---|
contributor | Per-user, chronological | Applied | Full scoring context |
repository | Group signals by repo | Skipped (skipQuota: true) | Zero-point conditions still apply |
team | Sum member scores | Inherited from contributor pass | User in multiple teams scores full points to each |
The active scoring preset controls all weights, multipliers, and zero-point conditions. One preset per installation is active at any time; all 6 time periods are pre-computed for it.
Time periods
| Period | Range |
|---|---|
today | 00:00:00 UTC → now |
week | now − 7d → now |
month | now − 30d → now |
quarter | now − 90d → now |
half_year | now − 180d → now |
all_time | entire signals table (no date filter) |
Caching layers
| Layer | What is cached | Key |
|---|---|---|
| Redis response cache | Serialised API response | Per-route, short TTL |
| Redis ingest lock | Prevents concurrent ingests | leaderboard:lock:{stableIngestScopeId} |
| Redis advisory lock | Prevents concurrent score writes | Per preset + scope |
computed_scores table | Pre-aggregated scores per period | materialization_id + entity_type + subject_id |
leaderboard_materializations table | Metadata + retention state for each materialization | Per preset + scope + period |
Custom date-range requests bypass the computed_scores table and aggregate in-memory from the signals table. They are not written to the DB.