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.
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 gap-based queueing modes, averaged across 5 independent seeded runs. Unfamiliar with a term below? Jump to the glossary.
Everyone got on a court — in both gap-based modes here, and in all five queueing modes across every room size tested.
The busiest player averaged about 9 games, the quietest about 3 or 4 — exceptional outliers aside, out of ~6.4 each over 4 hours.
Difference in average games played, male vs. female — 5.2% in Mixed, 6.1% in Skill-matched.
Share of groupmates you already played with in your previous game — the rest are new faces, rotated by the variety bench and recency rotation. Enforcing the wait promise in a busy room costs some of that rotation; see the conclusion.
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
- The two gap-based modes compared in these tables: Mixed (configurable skill gap, no widening fallback) and Skill-matched (tight gap + a fallback that widens in steps when no group exists at all). The console offers five queueing modes — Round robin, Tiered and First come, first served as well — and a separate run of the same engine compares all five across seven room sizes
- Pairing weight 0.65 — 65% wait-time fairness / 35% skill fit (app default)
- Wait promise: once a candidate group’s longest-waiting member exceeds the session’s Max wait, the group is exempted from the skill-gap check and heavily favored — and a second pass then trades a seat inside the finished round to anyone still past it, so the wait is enforced rather than merely favored. 20 minutes by default, settable (or switchable off); it was a tuned 25-minute constant before it became a manager’s setting
- Manager pins, whole fixed groups and half-filled fixed units are protected from that trade — the promise is kept with the seats the matcher chose freely, never by breaking a pair the manager pinned
- 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 about 9 games and the quietest about 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. It is the session’s “Max wait” setting (default 20 minutes; 10 / 15 / 20 / 30 or off), not a hidden constant — and a second pass runs after the round exists and trades a seat to anyone still past the promise, which is what makes it a promise rather than a preference. A rescue inside the matcher can only make leaving someone out less likely; checking the round is what prevents it.
- 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.
- Queueing modes
- Five answers to “who gets the next court”, all sharing the same wait promise. Mixed allows a wider skill-rating gap within a group (the manager’s setting, default ±1.5) and simply waits if no group fits. Skill-matched enforces a tighter gap (±0.5) but, when no group can be formed at all, widens it in steps (×2, ×4, ×8, ×16, then unlimited) and takes the first window that can field a game — so the queue mixes skill only as far as it must, and a court still never sits idle. Round robin keeps that same gap ceiling and, among the games it allows, prefers the pairings that have not met yet — it is the only mode that remembers who played with whom. Tiered runs separate Beginner / Intermediate / Advanced queues that take turns by who has waited longest, and only reaches across bands when a band cannot field four players by itself. First come, first served takes the next four names on the queue in arrival order, whatever their level. The tables on this page compare the two gap-based modes; a separate run of the same engine covers all five across seven room sizes.
- Partner coherence
- A group is scored by the teams it will actually produce, not just its total rating: team-sum balance plus a charge for a lopsided partnership inside them. A mirrored split — 3-star + 6-star against 3-star + 6-star — is perfectly balanced on team totals but hands a beginner an advanced partner; the coherence term makes it lose to a tighter 3+3 against 4.5+4.5. Measured as the share of algorithm-chosen games where the widest partnership inside a team spans 1.5 skill stars or more.
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.
A third problem only became visible once the algorithm was measured on partnerships rather than group totals (v1.10.0). The scorer rewarded groups that could split into two equally-rated teams — a good instinct — but a group like 3-star + 6-star against 3-star + 6-star is equally rated on team totals while handing a beginner an advanced partner. Because the group scorer and the team splitter were optimizing two different things, the scorer kept proposing exactly the mirrored split the splitter then produced. They now minimize one shared cost — team-sum balance plus a charge for a lopsided partnership inside the teams — and the Skill-matched fallback widens its gap in steps rather than jumping to unlimited. Mismatched partnerships fell from 15.5% to 6.2% of algorithm-chosen games with no fairness metric on this page moved; the residual cases are overwhelmingly pools where no coherent option existed at that moment, not choices the matcher got wrong.
A fourth change (v1.12.0) turned that rescue from a preference into a promise. A term inside a score can only make leaving someone out less likely, so the check moved after the round: the same number is now the session’s Max wait setting (20 minutes by default, 10 / 15 / 20 / 30 or off), and once the console has planned a round, anyone still past it who isn’t in it trades into a seat. The failure the pass exists to remove has a name — a game walking onto a court with a fresher player in it while somebody past the promise was still standing in the queue — and simulated across seven room sizes it goes from up to 50 games a session to exactly 0.0 in every room with the capacity to avoid it. Where a room genuinely cannot keep the promise (64 players across 3 courts), the queue says so and names who is owed a court rather than pretending. Manager pins and fixed groups are never traded away to pay for somebody else’s turn.
Each change 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). Its blended target in the sim is ~5.2–5.4 games; the four members average ~4.6–5.2 in Mixed and ~5.0–5.6 in Skill-matched, which is the two outcomes straddled into one number — held at the discounted count in most seeds, higher in the ~1-in-4 where the manager frees it.
- 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 bounded surplus over its per-check-in expectation (up to ~1.3 games in Skill-matched, ~2 in Mixed). That’s a 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 ~96% within one — the only players beyond that are pinned pairs carrying the pair surplus above, and no non-pinned player lands more than a game off. 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 the wait rescue at its shipped 20-minute threshold, for the two gap-based modes side by side. This is the matcher on its own — the seat-trading pass that enforces the promise is measured separately, and both sides of that trade are quoted in the conclusion below. All other tables on this page average across 5 seeds for statistical robustness — this one is a single illustrative run.
- Beginner (n=4): 5.75
- Low Intermediate (n=19): 6.58
- High Intermediate (n=20): 6.75
- Advanced (n=5): 6.6
- Beginner (n=4): 6.25
- Low Intermediate (n=19): 6.95
- High Intermediate (n=20): 6.4
- Advanced (n=5): 6.2
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
| Rescue | Avg stdev(games) | Avg spread | Avg stranded | Gender gap % | Advanced avg | Max wait | Utilization |
|---|---|---|---|---|---|---|---|
| OFF (no rescue) | 1.548 | 7.4 | 0 | 12.44% | 5.32 | 77.0m | 94.4% |
| 10 min | 1.325 | 5.8 | 0 | 5.02% | 5.58 | 76.5m | 97.2% |
| 15 min | 1.218 | 5.2 | 0 | 4.52% | 6.19 | 78.9m | 97.2% |
| 20 min (winner) | 1.215 | 5.4 | 0 | 4.35% | 5.77 | 65.1m | 97.3% |
| 25 min | 1.233 | 5.4 | 0 | 7.04% | 6.08 | 62.2m | 97.3% |
Mixed, gap 1.5 (current default)
| Rescue | Avg stdev(games) | Avg spread | Avg stranded | Gender gap % | Advanced avg | Max wait | Utilization |
|---|---|---|---|---|---|---|---|
| OFF (no rescue) | 1.521 | 6.6 | 0 | 11.86% | 5.45 | 84.7m | 93.9% |
| 10 min | 1.211 | 5.4 | 0 | 4.79% | 5.76 | 69.3m | 97.3% |
| 15 min | 1.317 | 5.4 | 0 | 5.33% | 6.08 | 66.2m | 97.3% |
| 20 min (winner, shipped) | 1.145 | 4.8 | 0 | 3.84% | 6.06 | 70.4m | 97.3% |
| 25 min | 1.19 | 5.6 | 0 | 5.56% | 6.18 | 69.4m | 97.3% |
Mixed, gap Any (99)
| Rescue | Avg stdev(games) | Avg spread | Avg stranded | Gender gap % | Advanced avg | Max wait | Utilization |
|---|---|---|---|---|---|---|---|
| OFF (no rescue) | 1.345 | 6 | 0 | 6.62% | 6.22 | 70.4m | 97.6% |
| 10 min (winner) | 1.196 | 5 | 0 | 3.73% | 6.01 | 77.5m | 97.5% |
| 15 min | 1.276 | 5.6 | 0 | 5.28% | 5.96 | 74.9m | 97.5% |
| 20 min | 1.407 | 6 | 0 | 8.07% | 6.13 | 72.5m | 97.5% |
| 25 min | 1.243 | 5.2 | 0 | 3.38% | 6 | 76.1m | 97.5% |
Skill-matched, gap 0.5 (current default)
| Rescue | Avg stdev(games) | Avg spread | Avg stranded | Gender gap % | Advanced avg | Max wait | Utilization |
|---|---|---|---|---|---|---|---|
| OFF (no rescue) | 1.771 | 8 | 0 | 6.42% | 5.44 | 92.9m | 97.5% |
| 10 min | 1.254 | 6.2 | 0 | 6.15% | 5.68 | 83.7m | 97.5% |
| 15 min | 1.517 | 6.8 | 0 | 6.67% | 5.8 | 85.4m | 97.5% |
| 20 min (winner, shipped) | 1.194 | 5.2 | 0 | 4.14% | 6.05 | 80.2m | 97.5% |
| 25 min | 1.324 | 5.8 | 0 | 3.67% | 6.05 | 78.1m | 97.6% |
Skill-matched, gap 1.0 (previous default)
| Rescue | Avg stdev(games) | Avg spread | Avg stranded | Gender gap % | Advanced avg | Max wait | Utilization |
|---|---|---|---|---|---|---|---|
| OFF (no rescue) | 1.614 | 7.4 | 0 | 10.12% | 5.31 | 103.9m | 97.5% |
| 10 min | 1.254 | 6.2 | 0 | 6.15% | 5.68 | 83.7m | 97.5% |
| 15 min | 1.517 | 6.8 | 0 | 6.67% | 5.8 | 85.4m | 97.5% |
| 20 min | 1.289 | 5.6 | 0 | 6.34% | 6.02 | 79.8m | 97.6% |
| 25 min (winner) | 1.072 | 5 | 0 | 4.57% | 6.19 | 68.0m | 97.6% |
Winner: Skill-matched, gap 1.0 (previous default) · rescue 25 min (avg stdev 1.072, 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: the best-scoring variant moved between runs of this sweep, which is precisely the noise the note below describes. The shipped session sits on the 20-minute row instead: that threshold is a manager’s setting now rather than a constant, 20 is what the wait is promised at, and it is the best row inside each current default’s own group (Mixed ±1.5 at 20 min — stdev 1.145, spread 4.8, gender gap 3.84%).
Pairing weight & catch-up games
With mode and rescue threshold held at the Phase 1 winner (Skill-matched, gap 1.0, rescue 25 min), we swept pairing weight (wait-time fairness vs. skill fit) and the catch-up-games toggle.
| Config | Avg stdev(games) | Avg spread | Avg stranded | Gender gap % | Advanced avg | Max wait | Utilization |
|---|---|---|---|---|---|---|---|
| weight 0.5 · catch-up OFF | 1.164 | 5.4 | 0 | 5.22% | 5.98 | 64.9m | 97.6% |
| weight 0.5 · catch-up ON | 1.35 | 6 | 0 | 8.87% | 5.74 | 73.1m | 97.6% |
| weight 0.65 · catch-up OFF (shipped default / winner) | 1.072 | 5 | 0 | 4.57% | 6.19 | 68.0m | 97.6% |
| weight 0.65 · catch-up ON | 1.243 | 5.4 | 0 | 5.07% | 6.23 | 66.2m | 97.5% |
| weight 0.8 · catch-up OFF | 1.228 | 5.6 | 0 | 4.28% | 6.15 | 63.9m | 97.6% |
| weight 0.8 · catch-up ON | 1.315 | 5.6 | 0 | 5.17% | 6.08 | 71.4m | 97.6% |
The app’s shipped default — weight 0.65 · catch-up OFF — posted the tightest stdev (1.072); weight 0.5 · catch-up OFF was a close second (1.164). Differences within Phase 2 are small relative to the rescue effect, so no change is recommended.
Conclusion
- The wait promise (shipped as the session’s Max wait setting — 20 minutes by default, 10 / 15 / 20 / 30 or off — and enforced by a pass that trades a seat after the round is built) remains the biggest single fairness lever. As a rescue inside the matcher it shows a clear OFF penalty in this sweep (stdev up to ~1.8 without it vs ~1.1–1.5 with it, worst-case waits up to ~104 min, and courts idling down to ~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. Enforcing it removes a failure the rescue alone only made less likely — a game fielded with a fresher player in it while somebody past the promise was still waiting — from up to 50 games a session to exactly 0.0 in every room with the capacity to avoid it, and it costs rotation, not structure: in the busy room partner gap ≥1.5 goes 0.0% → 15.0% and repeat groupmates 9.0% → 21.1%, while utilization moves by at most two tenths of a point, because the seat changes hands inside the same game.
- The novelty penalty (shipped) cut repeat groupmates from ~60% to under a sixth (~15–16% 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 the two gap-based modes above matters far less than whether the wait promise is enabled — they converge to similar fairness once it is. A separate run of the same engine put all five queueing modes through seven room sizes: with the promise on, the modes finish a session within a minute of each other on average wait (12.1–12.3 minutes in a 36-player room, 20.0–20.2 in a 48-player one), and nobody was left without a game in any of them. What differs is what each mode promises about the group itself: where the matcher picks freely, tiered holds a single skill band together on 94% of its groups where first-come crosses bands on 88% — but in a club whose bands are unequal depth that steadiness leaves the shallowest band about a quarter fewer games than the busiest one, and first-come pays for its strict order with repeat groupmates (31% against 15–17% for the skill-aware modes). Round robin is the one mode that remembers who played with whom, and on the games the matcher chose itself it re-uses an existing partnership on 9.9% of them in that 36-player room, where the other four run 19–36% — 6.2% once the wait promise is on. What it pays is partner quality: reaching for someone new means passing over the tightest available pairing, so its wide-partnership rate rises (6.6% against mixed’s 4.8% in the same room).
- The app’s shipped default — pairing weight 0.65 · catch-up OFF — was again the best performer in Phase 2 (stdev 1.072, 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 3–12% across the whole sweep (the largest gaps sit in the rescue-OFF rows), sitting around 3–8% at the shipped thresholds and 5.2% in the headline Mixed-mode run (6.1% in Skill-matched).
- Partner coherence (v1.10.0) changed who partners whom rather than how many games anyone gets. Scoring a group by the teams it will actually produce cut mismatched partnerships (a 1.5-star-or-wider spread inside a pair) from 15.5% to 6.2% of algorithm-chosen games — 14.0% → 5.4% on a two-tier 3.0/4.5 club, 10.6% → 0.7% on a roster spanning all seven skill steps — with every fairness metric on this page unchanged. It is a game-quality fix, not a fairness one, which is why it moves none of the numbers above.
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.
