Skip to main content
5Stack supports four tournament formats, each designed for different competitive scenarios. This guide covers how each format works, when to use them, and how they’re implemented.

Format Comparison

Swiss

Best for: Large tournaments (10-64 teams) with fair matchmakingDuration: 5-7 rounds typicalComplexity: Medium

Round Robin

Best for: Small groups (4-16 teams) where everyone plays everyoneDuration: (N-1) rounds for N teamsComplexity: Low

Single Elimination

Best for: Quick tournaments with clear progressionDuration: log2(N) roundsComplexity: Low

Double Elimination

Best for: Fair competition with second chancesDuration: 2 * log2(N) roundsComplexity: High

Swiss Format

Swiss is a non-elimination format where teams play until they reach a win or loss threshold. It’s ideal for large tournaments where you want fair matchmaking without eliminating teams.

How Swiss Works

1

Initial Matches

All teams start at 0-0. First round matches are created randomly or by seed.
2

Record-Based Pairing

After each round, teams are matched against others with similar records:
  • 1-0 teams play 1-0 teams
  • 0-1 teams play 0-1 teams
  • 1-1 teams play 1-1 teams
3

Advancement/Elimination

Teams reaching 3 wins advance to the next stage.Teams reaching 3 losses are eliminated.
4

Continue Until Complete

Tournament continues until all teams have either advanced or been eliminated.

Swiss Match Types

Swiss tournaments have three types of matches:
Standard matches where teams haven’t reached advancement/elimination threshold.Example: 1-1 vs 1-1, 2-0 vs 2-0
Teams at 2-X playing for their 3rd win.Example: 2-0 vs 2-0, 2-1 vs 2-1, 2-2 vs 2-2Winner advances to next stage.
Teams at X-2 playing to avoid 3rd loss.Example: 0-2 vs 0-2, 1-2 vs 1-2, 2-2 vs 2-2Loser is eliminated from tournament.

Record Pool Structure

The Swiss bracket viewer groups matches by win-loss records:
interface RecordPool {
  record: string;          // e.g., "2-1"
  wins: number;
  losses: number;
  brackets: Bracket[];     // Matches in this pool
  advancedTeams: string[]; // Teams that advanced from here
  eliminatedTeams: string[];// Teams eliminated from here
}

Swiss Configuration

const swissStage = {
  stage_type: 'Swiss',
  groups: 1,
  min_teams: 10,      // Minimum 10 teams (must be even)
  max_teams: 64,      // Maximum 64 teams
  default_best_of: 1, // Default BO1 for regular matches
  settings: {
    round_best_of: {
      'regular': 1,       // Regular matches: BO1
      'advancement': 3,   // Advancement matches: BO3
      'elimination': 3    // Elimination matches: BO3
    }
  }
};
Swiss requires an even number of teams to ensure proper pairing. Odd team counts will result in errors.

Record Encoding

Swiss uses numeric group values to encode win-loss records:
// Group value encoding:
// If < 100: group = losses (e.g., 1 = 0-1, 2 = 0-2)
// If >= 100: wins * 100 + losses (e.g., 100 = 1-0, 201 = 2-1)

function parseGroupToRecord(group: number): { wins: number; losses: number } {
  if (group === 0) return { wins: 0, losses: 0 };
  if (group < 100) return { wins: 0, losses: group };
  
  const wins = Math.floor(group / 100);
  const losses = group % 100;
  return { wins, losses };
}

When to Use Swiss

Use Swiss when:
  • You have 10-64 teams
  • You want fair matchmaking based on performance
  • You need to seed teams for a playoff stage
  • You want longer tournaments with many matches
Avoid Swiss when:
  • You have fewer than 10 teams
  • You need quick results
  • Teams expect single-elimination format

Round Robin Format

Round Robin is a format where every team plays every other team once. It’s perfect for small groups where you want complete standings.

How Round Robin Works

1

Generate All Matchups

System creates matches for every possible pairing:
  • 4 teams = 6 matches
  • 6 teams = 15 matches
  • 8 teams = 28 matches
2

Play All Matches

Teams play all their scheduled matches. Order doesn’t matter.
3

Calculate Standings

Final standings determined by:
  1. Match wins
  2. Round differential (tiebreaker)
  3. Head-to-head (tiebreaker)

Round Robin with Groups

You can split teams into multiple parallel round-robin groups:
const roundRobinStage = {
  stage_type: 'RoundRobin',
  groups: 4,          // 4 parallel groups
  min_teams: 16,      // 4 teams per group minimum
  max_teams: 16,      // 4 teams per group exactly
  default_best_of: 1
};
Teams are distributed evenly across groups:
  • 16 teams, 4 groups = 4 teams per group
  • Each group runs independently
  • Top teams from each group can advance

Round Robin Results

The results table tracks detailed statistics:
<template>
  <Table>
    <TableHeader>
      <TableRow>
        <TableHead>Team</TableHead>
        <TableHead>Games Played</TableHead>
        <TableHead>Wins</TableHead>
        <TableHead>Losses</TableHead>
        <TableHead>Rounds Won</TableHead>
        <TableHead>Rounds Lost</TableHead>
        <TableHead>Matches Remaining</TableHead>
      </TableRow>
    </TableHeader>
    <TableBody>
      <TableRow v-for="result in stage.results">
        <TableCell>{{ result.team.name }}</TableCell>
        <TableCell>{{ result.games_played }}</TableCell>
        <TableCell>{{ result.wins }}</TableCell>
        <TableCell>{{ result.losses }}</TableCell>
        <TableCell>{{ result.rounds_won }}</TableCell>
        <TableCell>{{ result.rounds_lost }}</TableCell>
        <TableCell>{{ result.matches_remaining }}</TableCell>
      </TableRow>
    </TableBody>
  </Table>
</template>

When to Use Round Robin

Use Round Robin when:
  • You have 4-16 teams total
  • You want complete standings
  • You’re running group stages
  • Time permits many matches
Avoid Round Robin when:
  • You have many teams (match count explodes)
  • You need quick tournament completion
  • Teams expect bracket-style progression

Single Elimination Format

Single Elimination is a traditional bracket where teams are eliminated after one loss. It’s the fastest format and easiest to understand.

How Single Elimination Works

1

Generate Bracket

Teams are placed in a bracket sized to next power of 2:
  • 5-8 teams = 8-team bracket
  • 9-16 teams = 16-team bracket
  • 17-32 teams = 32-team bracket
Byes are awarded to top seeds if needed.
2

Play Matches

Winners advance to next round, losers are eliminated.
3

Crown Champion

Final match determines tournament winner.

Round Structure

Rounds are calculated based on bracket size:
function calculateSERounds(teamsPerGroup: number): RoundInfo[] {
  const totalRounds = Math.max(
    Math.ceil(Math.log(teamsPerGroup) / Math.log(2)),
    1
  );
  const rounds: RoundInfo[] = [];
  
  for (let r = 1; r <= totalRounds; r++) {
    const matchesInRound = Math.pow(2, totalRounds - r);
    rounds.push({
      key: `WB:${r}`,
      label: getRoundLabel(r, matchesInRound, true),
      path: 'WB',
      round: r
    });
  }
  
  return rounds;
}

Round Labels

Single Elimination uses descriptive labels:
  • Round 1, 2, 3…: Early rounds
  • Quarterfinals: 4 teams remaining
  • Semifinals: 2 matches remaining
  • Grand Final: Championship match

Third Place Match

Optionally include a 3rd place decider match:
const singleElimStage = {
  stage_type: 'SingleElimination',
  groups: 1,
  min_teams: 8,
  max_teams: 16,
  default_best_of: 3,
  third_place_match: true,
  decider_best_of: 3  // Best-of for 3rd place match
};

Per-Round Configuration

Configure different best-of settings per round:
settings: {
  round_best_of: {
    'WB:1': 1,  // Round 1: BO1
    'WB:2': 1,  // Quarterfinals: BO1
    'WB:3': 3,  // Semifinals: BO3
    'WB:4': 5   // Grand Final: BO5
  }
}

When to Use Single Elimination

Use Single Elimination when:
  • You need fast tournament completion
  • Bracket format is preferred by players
  • You have any number of teams (2-256)
  • Simple progression is desired
Avoid Single Elimination when:
  • You want to give teams second chances
  • Fairness is prioritized over speed
  • Early upsets would be controversial

Double Elimination Format

Double Elimination features both winners and losers brackets, giving teams a second chance before elimination. It’s the most complex but fairest bracket format.

How Double Elimination Works

1

Winners Bracket Start

All teams start in the winners bracket (upper bracket).
2

First Loss

Teams losing in winners bracket drop to losers bracket (lower bracket).
3

Losers Bracket

Teams in losers bracket play elimination matches. One more loss eliminates them.
4

Grand Final

Winners bracket champion faces losers bracket champion.Some formats give WB champion one-match advantage.

Bracket Structure

Double Elimination has three bracket components:
Upper bracket where all teams start. Winners advance, losers drop to LB.
// WB rounds for 8 teams
rounds: [
  { key: 'WB:1', label: 'Winners Round 1', matches: 4 },
  { key: 'WB:2', label: 'Winners Semifinals', matches: 2 },
  { key: 'WB:3', label: 'Winners Finals', matches: 1 }
]

Round Calculation

function calculateDERounds(teamsPerGroup: number): RoundInfo[] {
  const W = Math.pow(2, Math.ceil(Math.log(teamsPerGroup) / Math.log(2)));
  const wbRounds = Math.round(Math.log(W) / Math.log(2));
  const lbRounds = wbRounds <= 1 ? 0 : 2 * (wbRounds - 1);
  const rounds: RoundInfo[] = [];
  
  // Winners Bracket rounds
  for (let r = 1; r <= wbRounds; r++) {
    rounds.push({
      key: `WB:${r}`,
      label: getRoundLabel(r, true, false),
      path: 'WB',
      round: r
    });
  }
  
  // Losers Bracket rounds
  for (let r = 1; r <= lbRounds; r++) {
    rounds.push({
      key: `LB:${r}`,
      label: getRoundLabel(r, false, true),
      path: 'LB',
      round: r
    });
  }
  
  // Grand Final
  if (wbRounds > 0) {
    rounds.push({
      key: 'GF',
      label: { key: 'Grand Final' },
      path: 'WB',
      round: wbRounds + 1
    });
  }
  
  return rounds;
}

Bracket Connections

Double Elimination brackets have complex connections:
interface Bracket {
  id: string;
  round: number;
  path: 'WB' | 'LB';           // Winners or Losers bracket
  parent_bracket?: Bracket;     // Where winner goes
  loser_bracket?: Bracket;      // Where loser goes (WB only)
  feeding_brackets?: Bracket[]; // Brackets feeding into this one
}

Configuration Example

const doubleElimStage = {
  stage_type: 'DoubleElimination',
  groups: 1,
  min_teams: 8,
  max_teams: 16,
  default_best_of: 3,
  settings: {
    round_best_of: {
      'WB:1': 1,  // WB Round 1: BO1
      'WB:2': 3,  // WB Semifinals: BO3
      'WB:3': 3,  // WB Finals: BO3
      'LB:1': 1,  // LB Round 1: BO1
      'LB:2': 1,  // LB Round 2: BO1
      'LB:3': 3,  // LB Round 3: BO3
      'LB:4': 3,  // LB Finals: BO3
      'GF': 5     // Grand Final: BO5
    }
  }
};

Bracket Visualization

Double Elimination brackets display both WB and LB:
  • Winners Bracket: Displayed on top
  • Losers Bracket: Displayed below
  • Connection Lines: Show progression paths
    • White lines: Winner advancement
    • Red lines: Loser drops to LB

When to Use Double Elimination

Use Double Elimination when:
  • Fairness is top priority
  • You want to reward consistency
  • Teams expect second chances
  • You have time for more matches
Avoid Double Elimination when:
  • Bracket complexity would confuse players
  • Tournament duration is limited
  • Single-elim simplicity is preferred

Format Selection Guide

Choose the right format based on your tournament goals:
  • 4-8 teams: Round Robin or Single Elimination
  • 8-16 teams: Single/Double Elimination
  • 16-32 teams: Swiss → Single/Double Elim
  • 32+ teams: Swiss → Single Elim playoffs

Multi-Format Tournament

Combine formats for optimal tournament structure:

Example: Large Tournament

// Stage 1: Swiss for seeding
{
  stage_type: 'Swiss',
  max_teams: 64,
  default_best_of: 1,
  settings: {
    round_best_of: {
      'regular': 1,
      'advancement': 3,
      'elimination': 3
    }
  }
}

// Stage 2: Double Elim playoffs
{
  stage_type: 'DoubleElimination',
  max_teams: 16,  // Top 16 from Swiss
  default_best_of: 3,
  settings: {
    round_best_of: {
      'GF': 5  // BO5 grand final
    }
  }
}

Example: Group Stage Tournament

// Stage 1: 4 Round Robin groups
{
  stage_type: 'RoundRobin',
  groups: 4,
  max_teams: 16,  // 4 teams per group
  default_best_of: 1
}

// Stage 2: Single Elim playoffs
{
  stage_type: 'SingleElimination',
  max_teams: 8,   // Top 2 from each group
  default_best_of: 3,
  third_place_match: true
}

Implementation Details

Bracket Generation

Brackets are generated automatically when tournament starts:
-- Called on tournament start
SELECT update_tournament_stages(tournament_id);

-- Generates brackets based on:
-- 1. Stage type
-- 2. Team count  
-- 3. Team seeds
-- 4. Group configuration

Match Creation

Matches are created progressively as tournament advances:
  • Initial Matches: Created on tournament start
  • Subsequent Matches: Created when previous round completes
  • Bracket Updates: Automatic based on match results

Next Steps

Creating Tournaments

Step-by-step tournament creation guide

Bracket Visualization

Understanding bracket display and navigation

Managing Tournaments

Team management and tournament administration

Match Scheduling

Schedule and manage tournament matches

Build docs developers (and LLMs) love