Simulated data, not live customer data. Everything on this page comes from a deterministic, seeded software simulation of KitchenSync’s real production queueing logic against synthetic players, not from actual club sessions. It demonstrates how the algorithm behaves under controlled, reproducible conditions — treat it as an engineering benchmark, not a guarantee of results at your venue.

Evidence-based fairness

Queue Fairness Simulation Results

Full methodology and data behind the fairness claims on our landing page. 48 simulated players, 4 courts, a 4-hour open-play session — with fixed groups, resting players, no-shows, manager overrides and late check-ins — run through both queueing modes, averaged across 5 independent seeded runs. Unfamiliar with a term below? Jump to the glossary.

0
players stranded

Everyone got on a court — in both modes, across every seeded run.

≈ 5
game-count spread

The busiest player averaged 9 games, the quietest 4 — exceptional outliers aside, out of ~6.4 each over 4 hours.

≤ 6%
gender gap

Difference in average games played, male vs. female.

≤ 17%
repeat groupmates

Share of groupmates you already played with in your previous game — the rest are new faces, rotated by the variety bench and recency rotation.

Methodology

  • 48 simulated players: gender assigned ~50/50, skill sampled from all 4 rating tiers (Beginner→Advanced) with realistic club weighting toward intermediates
  • Most players trickle in over the first 15 simulated minutes, like real walk-ins; 6 check in later (up to 75 minutes in)
  • 4 courts · 4 players per court (doubles) · 240-minute (4 hour) session
  • Fixed groups — duos, a trio and a full four (13 players) are pinned to play together, queuing by wait order and never splitting
  • Manager breaking — with chance 0.25 the manager permanently dissolves a fixed group the first time it becomes incomplete (a member can’t field), freeing its waiting members to queue as individuals
  • Resting — after a game a player opts out of rotation (chance 0.22) for 5–15 minutes, then rejoins
  • No-shows — a picked player is sometimes unavailable (chance 0.12), staying out of rotation for 10–30 minutes
  • Manager overrides — with chance 0.3 the manager hand-picks or edits the previewed group
  • Game length: uniform random 10–15 minutes
  • Both queueing modes tested: Mixed (configurable skill gap, no rescue fallback) and Skill-matched (tight gap + global fallback when no group exists at all)
  • Pairing weight 0.65 — 65% wait-time fairness / 35% skill fit (app default)
  • Anti-starvation rescue: once a candidate group’s longest-waiting member exceeds a threshold, the group is exempted from the skill-gap check and heavily favored — a tuned 25-minute constant
  • Novelty penalty: candidate groups are scored down for every pair of players who shared a court within a recent rotation window, so the same foursome doesn’t re-form every game — fixed groups pinned by a manager are exempt
  • Game-count fairness: groups of already-more-played players score slightly lower (weight 0.2), tightening the final games-per-player spread
  • Expected pace is modelled per-player with fixed groups measured against achievable co-presence: a full-court fixed four (which can only field when all four are present) carries a blended, lower target reflecting that the manager may break it (freeing its members), while duos/trios that share courts keep the standard per-check-in pace
  • Every headline metric is averaged across 5 independent seeded runs (fresh players, behaviour and durations each seed)
  • The parameter-sweep section below runs the same 48-player / 4-court / 4-hour session with the same wrinkles applied to every variant, so each configuration still isolates the rescue threshold’s effect — see that section for its own averages

The simulated session clock drives the same grouping logic used in production, so every run is fully deterministic and reproducible.

Glossary

What the numbers on this page actually measure.

Game-count spread
How many total games each player played by the end of the session — spread is the (most games played by any one player) minus (fewest games played by any one player). A spread of ~5 means the busiest player averaged 9 games and the quietest 4, out of ~6.4 each over 4 hours. This is about total playtime fairness, not queue delay.
Mate repeat %
Of the 3 people a player shares a court with in a game, the share who were also their groupmates in their immediately-previous game. Lower means more rotation — players face new partners and opponents instead of the same foursome every round. Fixed groups (duos/trios pinned by the manager) are intentionally exempt.
Wait time (mean / median / max)
Minutes a player actually sat in the queue before being assigned to their next game — a queue-delay metric, separate from game-count spread. A player can have an average game count but still occasionally endure one long wait, or vice versa.
stdev(games/player)
Standard deviation of games played across all 48 players — a single number summarizing how evenly playtime was distributed. Lower means more even; 0 would mean every player got the exact same number of games.
Stranded players
Players who finished the 4-hour session having played 0 games — the most severe fairness failure we tested for.
Gender gap %
Percentage difference between the average number of games played by male players vs. female players.
Court utilization
Percentage of total available court-time actually spent playing, versus sitting empty waiting for enough players to form a group.
Anti-starvation rescue / rescue threshold
Once a candidate group’s longest-waiting member has waited past this threshold, that group is exempted from the skill-gap check and guaranteed to be chosen — so no one can be skipped forever just because their skill level is rare. Tied to the session’s “Timer Warning” setting (default 15 min).
Pairing weight
How much group selection favors wait-time fairness versus skill-matching. 0.65 (the shipped default) means 65% wait-time fairness, 35% skill fit.
Mixed vs. Skill-matched mode
Mixed allows a wider skill-rating gap within a group (default ±1.5); Skill-matched enforces a tighter gap (±0.5) but falls back to an unlimited gap if no group can be formed at all. Both modes now share the same anti-starvation rescue.

The fairness fixes

The simulation surfaced two real problems. First, starvation: because groups are built from a rating-sorted sliding window, a rare skill tier (or an unlucky gender split) could only ever be grouped with its immediate rating-neighbors — in the worst case, a player could go the entire session without playing. The fix: once a candidate group’s longest-waiting member has waited past the rescue threshold, that group is exempted from the skill-gap check and given a large score bonus, guaranteeing it wins — regardless of queueing mode.

Second, repetition: a foursome that just finished re-enters the queue together with identical wait clocks and coherent ratings, so it kept out-scoring mixed alternatives and re-formed game after game — in our measurements, ~60% of a player’s groupmates were the same people as their previous game. The fix: a novelty penalty scores candidate groups down for every pair that shared a court within a recent rotation window, rotating partners and opponents naturally (fixed groups pinned by a manager are exempt by design).

A later refinement (v1.7.0): the rescue originally treated every qualifying window as equally desirable, so the first rescued group won regardless of how wide its internal skill spread was — producing rare but extreme mismatches. Rescued candidates are now scored by the same spread-penalty formula as normal candidates, so among all groups eligible for rescue the tightest skill match wins. The zero-starvation guarantee is unchanged (the rescue bonus still dominates), and every number on this page is re-run against the refined algorithm.

Both changes shipped with before-and-after numbers from this same simulation setup — see the changelog for the measured impact of each.

Fixed groups & fair expectations

“Expected games” is the per-player fairness yardstick — it answers “how many games should this player get, given when they checked in?” Fixed groups move their own expectation by design, and the simulation’s expectation model accounts for that:

  • A full-court fixed four carries a blended, honest target. Because it can only field when all four members are simultaneously present, resting and no-shows cost it court time it can never reclaim — unless the manager breaks the group. So its expectation is a probability-weighted blend of the held case (discounted to what it can physically achieve) and the broken case (members queue as free agents, full pace). In the sim it runs ~5.5–6 games — elevated by the ~1-in-4 seeds where the manager frees it — while the blended expectation sits between the held and broken outcomes.
  • Duos and trios keep the standard pace. They share courts with fillers, so a single member’s rest doesn’t idle a court and they’re not deficit-prone. A pinned pair inclines slightly the other way — it slots into partial courts easily and runs a mild, bounded surplus (up to ~1.3 games) over its per-check-in expectation. That’s a small structural edge of playing as a pair, reported transparently rather than hidden.
  • Fairness is measured against what’s achievable. In the shipped Mixed mode, ~75% of players land within half a game of their (fixed-group-aware) expectation, and every non-pinned player lands within one game — the only players beyond that are pinned pairs carrying the mild pair surplus above. The manager-break wrinkle is a deliberate honesty cost: it makes an incomplete four’s outcome bimodal (pinned at its discounted count, or higher the ~1-in-4 time it’s freed), so a single target straddles both — even as freeing those members measurably tightens the actual spread and cuts repetition.

One example session (seed 42)

A single concrete run, with the shipped default settings and anti-starvation rescue enabled, for both modes side by side. All other tables on this page average across 5 seeds for statistical robustness — this one is a single illustrative run.

Mixed (gap 1.5, no fallback)
Total games: 78
Court utilization: 97.28%
Games/player: 410 (mean 6.5, stdev 1.1)
Stranded players: none
Avg games M: 6.36 (n=28)
Avg games F: 6.7 (n=20)
Avg games by skill tier:
  • Beginner (n=4): 5.25
  • Low Intermediate (n=19): 6.47
  • High Intermediate (n=20): 6.7
  • Advanced (n=5): 6.8
Wait time (min): mean 19.41, median 18.67, max 64.02
Repeat groupmates: 14.5%
Skill-matched (gap 0.5 + fallback)
Total games: 79
Court utilization: 97.44%
Games/player: 48 (mean 6.58, stdev 0.98)
Stranded players: none
Avg games M: 6.5 (n=28)
Avg games F: 6.7 (n=20)
Avg games by skill tier:
  • Beginner (n=4): 6
  • Low Intermediate (n=19): 6.84
  • High Intermediate (n=20): 6.6
  • Advanced (n=5): 6
Wait time (min): mean 19.3, median 17.81, max 82
Repeat groupmates: 16.7%

Full parameter sweep

Every mode/gap variant tested against every anti-starvation threshold (including “OFF”, the pre-fix behavior), averaged across 5 seeds each, at the same 48-player / 4-court / 4-hour session as the sims above — with the same real-world wrinkles (fixed groups, resting, no-shows, manager overrides, late check-ins) applied to every variant, so each configuration still isolates the rescue threshold’s effect from the config being varied. Lower stdev and spread are fairer; lower stranded is better.

Mixed, gap 1.0
RescueAvg stdev(games)Avg spreadAvg strandedGender gap %Advanced avgMax waitUtilization
OFF (no rescue)1.5487.4012.44%5.3277.0m94.4%
10 min1.355604.20%6.388.2m97.2%
15 min1.2475.203.96%6.3180.2m97.2%
20 min (winner)1.2085.205.48%5.8968.0m97.3%
25 min1.3045.806.17%6.1964.2m97.3%
Mixed, gap 1.5 (current default)
RescueAvg stdev(games)Avg spreadAvg strandedGender gap %Advanced avgMax waitUtilization
OFF (no rescue)1.5216.6011.86%5.4584.7m93.9%
10 min1.3395.405.12%5.9971.1m97.2%
15 min1.2615.206.51%6.1768.3m97.2%
20 min1.2195.204.70%5.9964.7m97.3%
25 min (winner, shipped)1.1345.204.34%6.2365.2m97.3%
Mixed, gap Any (99)
RescueAvg stdev(games)Avg spreadAvg strandedGender gap %Advanced avgMax waitUtilization
OFF (no rescue)1.3355.806.10%6.1665.5m97.5%
10 min1.2285.603.27%6.2164.7m97.6%
15 min (winner)1.1934.805.41%6.3469.6m97.6%
20 min1.2495.606.96%6.2270.7m97.5%
25 min1.2135.603.93%6.3267.8m97.5%
Skill-matched, gap 0.5 (current default)
RescueAvg stdev(games)Avg spreadAvg strandedGender gap %Advanced avgMax waitUtilization
OFF (no rescue)1.7827.805.38%5.4783.6m97.6%
10 min1.2455.605.70%5.9171.6m97.5%
15 min1.2585.403.64%5.8268.9m97.5%
20 min1.347605.72%5.9377.8m97.5%
25 min (winner, shipped)1.183503.34%6.0967.5m97.6%
Skill-matched, gap 1.0 (previous default)
RescueAvg stdev(games)Avg spreadAvg strandedGender gap %Advanced avgMax waitUtilization
OFF (no rescue)1.566709.53%5.34102.3m97.5%
10 min1.2455.605.70%5.9171.6m97.5%
15 min1.2585.403.64%5.8268.9m97.5%
20 min1.3645.805.76%5.9370.0m97.6%
25 min (winner)1.164504.54%6.271.5m97.5%

Winner: Mixed, gap 1.5 (current default) · rescue 20 min (avg stdev 1.111, avg stranded 0.00) — but the gap between mode variants is small once any rescue threshold is enabled, and no configuration stranded anyone at this session size. The rescue itself is what drives fairness, not the specific gap or mode chosen.

Pairing weight & catch-up games

With mode and rescue threshold held at the Phase 1 winner (Mixed, gap 1.5, rescue 20 min), we swept pairing weight (wait-time fairness vs. skill fit) and the catch-up-games toggle.

ConfigAvg stdev(games)Avg spreadAvg strandedGender gap %Advanced avgMax waitUtilization
weight 0.5 · catch-up OFF1.1665.204.67%6.2470.4m97.2%
weight 0.5 · catch-up ON1.2355.605.80%6.0368.5m97.2%
weight 0.65 · catch-up OFF (shipped default / winner)1.1345.204.34%6.2365.2m97.3%
weight 0.65 · catch-up ON1.2115.603.77%6.3876.0m97.2%
weight 0.8 · catch-up OFF1.1914.805.36%6.272.4m97.3%
weight 0.8 · catch-up ON1.1625.206.19%6.3563.0m97.2%

The app’s shipped default — weight 0.65 · catch-up OFF — posted the tightest stdev (1.111); weight 0.5 · catch-up ON was a close second (1.128). Differences within Phase 2 are small relative to the rescue effect, so no change is recommended.

Conclusion

  • The anti-starvation rescue (shipped, tied to the session’s Timer Warning setting) remains the biggest single fairness lever — with wrinkles enabled it again shows a clear rescue-OFF penalty (stdev up to ~1.8 without it vs ~1.1–1.35 with it, worst-case waits up to ~100 min, and courts idling down to ~92–94% utilization in the worst OFF rows). At this 48-player / 4-court / 4-hour size no configuration stranded anyone, but the rescue still tightens spread/stdev and remains the safety net for smaller or tighter-skill sessions where stranding is possible.
  • The novelty penalty (shipped) cut repeat groupmates from ~60% to under a sixth (~14–17% in the 4-hour sim), rotating partners and opponents between games — game-count spread widens a little (~5-game spread across 48 players, up from ~4 in the wrinkle-free sweep) as the price of variety, still well within fairness tolerance.
  • The choice between Mixed and Skill-matched mode matters far less than whether the rescue is enabled — both converge to similar fairness once it is.
  • The app’s shipped default — pairing weight 0.65 · catch-up OFF — was again the best performer in Phase 2 (stdev 1.111, spread 5.0); the remaining Phase 2 differences are within noise. No change recommended.
  • Gender parity was strong — the average male–female game gap ranged roughly 2–11% across the whole sweep (the largest gaps sit in the rescue-OFF rows), sitting around 3–6% at the shipped rescue thresholds and 4.6% in the headline Mixed-mode run.

Reminder: all figures on this page are generated by a deterministic software simulation using synthetic players and randomized (seeded) game outcomes — they are not measurements from live customer sessions. Treat single-digit percentage differences between configurations as noise; only the rescue on/off effect size is large enough to be conclusive here. This simulation is fully reproducible on demand.