---
title: "How to run 5v5 competitive matches on a Counter-Strike 2 server"
description: "Run pugs, scrims and locked 5v5 matches on a CS2 server with MatchZy: install it, load a match config, and use the ready-up, knife, pause and round-restore commands."
url: "https://www.gameserverkings.com/knowledge-base/counter-strike-2/how-to-run-competitive-matches/"
category: "Counter-Strike 2"
category_url: "https://www.gameserverkings.com/knowledge-base/counter-strike-2/"
published: "2026-08-07T08:27:38.624Z"
updated: "2026-08-07T08:27:38.624Z"
source_format: "markdown"
site: "GameServerKings"
---

# How to run 5v5 competitive matches on a Counter-Strike 2 server

A stock Counter-Strike 2 server can host ten people on a competitive map, and that is where its help ends. It has no ready-up, no knife round, no side-choice after the knife, no tactical timeouts either team can call, no way to lock five specific SteamIDs to each team, and no round backup you can restore when someone disconnects at 12-11. Those are the things that turn a server into a match server, and on CS2 they all come from a plugin.

The plugin that does it is **MatchZy**. It runs on the CounterStrikeSharp stack, handles pugs out of the box with no configuration, and takes a JSON file when you want a locked BO1, BO3 or BO5 with named teams.

This guide covers installing it, running an unconfigured pug, setting up a real match, and the commands players and admins actually use during one.

> [!WARNING] Check MatchZy's maintenance status before you build on it
> As of 7 August 2026, MatchZy's most recent release is **0.8.15, published 25 October 2025**, and there have been no commits on any branch since that date. CounterStrikeSharp has shipped many releases in the same window, most recently v1.0.371 on 10 July 2026. Users were still filing behaviour-specific bug reports as recently as late July 2026, which suggests it is still running for people, but we have not tested 0.8.15 against the current CounterStrikeSharp on our own hardware. Install it on a test server and confirm it loads before you schedule a match on it.

## What does MatchZy do that a stock CS2 server cannot?

| Capability | Stock CS2 server | With MatchZy |
|---|---|---|
| Ready-up before the match starts | No | `.ready` / `.unready`, configurable threshold |
| Knife round and side choice | No | Automatic, with `.stay` and `.switch` |
| Lock players to a team and side | No | Match config JSON by SteamID64 |
| Tactical and technical pauses | Native `mp_pause_match` only, no team logic | `.pause`, `.tech`, `.tac`, both-teams-unpause |
| Restore a round after a disconnect | Native backup files, restored by hand | `.stop` and `.restore <round>` |
| BO3 / BO5 series with veto | No | `num_maps`, `maplist`, `map_sides` |
| Automatic demo recording | Manual `tv_` setup | Starts on ready-up, stops on map result |
| Per-player match stats | No | SQLite or MySQL, plus a CSV per match |

## How do I install MatchZy on my CS2 server?

MatchZy is a CounterStrikeSharp plugin, so the framework goes on first.

1. Install Metamod:Source and CounterStrikeSharp. Full procedure in [How to install plugins on a Counter-Strike 2 server](/knowledge-base/counter-strike-2/how-to-install-plugins/).

2. Download the latest release from `github.com/shobhit-pathak/MatchZy/releases` and extract it into the `csgo/` directory of your server.

3. Restart the server.

4. Run `css_plugins list` in the server console. MatchZy should be listed.

MatchZy also publishes bundled `with-cssharp` archives that include CounterStrikeSharp, which lets you skip step 1. Be aware of what that means in practice: the bundle pins whichever CounterStrikeSharp build was current when that MatchZy release was cut — October 2025 for 0.8.15 — rather than the current one. If you are running other plugins that expect a newer framework, install the two separately.

On Windows you need the Windows build of CounterStrikeSharp specifically.

Everything MatchZy reads and writes lives in `csgo/cfg/MatchZy/`. If that folder is not there after a restart, the extraction went somewhere other than `csgo/`.

## How do I run a pug without configuring anything?

You do not have to set up a match to use MatchZy. It starts in **pug mode** by default, which means teams are not locked and anyone can join either side.

Get ten people in, then:

- Everyone types `.ready` (or `!ready`, or the short `.r`).
- Once enough players are ready, warmup ends and the knife round starts.
- The knife winner types `.stay` or `.switch`.
- The match goes live.

Both `.` and `!` work as prefixes for almost every command.

Two settings decide how the start behaves, and they are the first two you will want to change:

- `.readyrequired <number>` — how many ready players are needed. `0` means every connected player must ready up.
- `.roundknife` — toggles the knife round off, so warmup goes straight to live.

`.settings` prints the current state of both, which is quicker than reading the config.

MatchZy has three other modes beyond pug: **practice mode** (`.prac`), **scrim mode** (`.playout`, which plays out all rounds regardless of who has clinched), and **match mode**, which is what a config file loads.

## How do I set up a locked 5v5 match?

Write a JSON file, put it in the `csgo` directory, and load it. This is what locks players to teams and sides.

```json title="csgo/team_a_vs_team_b.json"
{
  "matchid": 27,
  "team1": {
    "name": "Team A",
    "players": {
      "76561197990682262": "player1",
      "76561198010511021": "player2",
      "76561197979669175": "player3",
      "76561198028458803": "player4",
      "76561198024248129": "player5"
    }
  },
  "team2": {
    "name": "Team B",
    "players": {
      "76561198034202275": "player6",
      "76561198044045107": "player7",
      "76561198246607476": "player8",
      "76561198121220486": "player9",
      "76561198040577200": "player10"
    }
  },
  "num_maps": 3,
  "maplist": ["de_mirage", "de_overpass", "de_inferno"],
  "map_sides": ["team1_ct", "team2_ct", "knife"],
  "clinch_series": true,
  "players_per_team": 5,
  "cvars": {
    "hostname": "Team A vs Team B",
    "mp_friendlyfire": "0"
  }
}
```

Load it from the server console:

```text title="Loading a match"
matchzy_loadmatch team_a_vs_team_b.json
```

The path is relative to the `csgo` directory. To load one over HTTP instead — useful if a bot or web panel generates the file — use `matchzy_loadmatch_url <url>`, optionally with a header name and value for authentication. Wrap all arguments in double quotes.

### Match config fields

| Field | Required | What it does |
|---|---|---|
| `maplist` | Yes | Maps in the series, in order |
| `team1` / `team2` | Yes | Team name and a SteamID64-to-nickname map of its players |
| `num_maps` | Yes | Number of maps in the series |
| `matchid` | No | Series identifier; auto-generated by the server if left empty |
| `map_sides` | No | Starting sides per map — `team1_ct`, `team2_ct` or `knife` |
| `spectators` | No | SteamID64s allowed in the spectator slots |
| `clinch_series` | No | End the series as soon as one team cannot be caught |
| `players_per_team` | No | Expected players per side |
| `cvars` | No | Convars applied for the match, restored when the series ends |

Two limitations are documented by the project. Coaches cannot be assigned in the config — add them to a team's `players` and have them run `.coach <side>` in the server. And only SteamID64 is supported; the `STEAM_0:1:1` form is not.

## What commands do players use during a match?

### Starting the match

| Command | What it does |
|---|---|
| `.ready` | Mark yourself ready (aliases `.r`) |
| `.unready` | Mark yourself unready (aliases `.ur`, `.notready`) |
| `.forceready` | Force-ready your whole team — match setup via JSON or Get5 only |
| `.stay` | Knife winner keeps the current side |
| `.switch` / `.swap` | Knife winner switches sides |

### Pausing and timeouts

| Command | What it does |
|---|---|
| `.pause` | Pause at freezetime — tactical or normal, depending on `matchzy_use_pause_command_for_tactical_pause` |
| `.tech` | Pause at freezetime for a technical issue |
| `.tac` | Start a tactical timeout |
| `.unpause` | Request unpause — **both** teams must type it |

### Restoring a round

| Command | What it does |
|---|---|
| `.stop` | Restore the backup of the current round — both teams must agree |
| `.restore <round>` | Admin only: restore a specific round number |

`.stop` is **disabled by default** — `matchzy_stop_command_available` ships as `false`. Turn it on before a match if you want teams to be able to roll a round back themselves. A related setting, `matchzy_stop_command_no_damage`, makes `.stop` unavailable once someone has damaged an opponent that round. After any restore, the match stays paused by default until both teams `.unpause` or an admin force-unpauses.

### Coaching

| Command | What it does |
|---|---|
| `.coach <side>` | Take the coach slot for a side, e.g. `.coach t` |
| `.uncoach` | Leave the coach slot |

## What admin commands does MatchZy have?

| Command | What it does |
|---|---|
| `.start` | Force-start the match |
| `.restart` | Force-restart or reset the match (aliases `.endmatch`, `.forceend`) |
| `.forcepause` | Pause as an admin — players cannot unpause it (alias `.fp`) |
| `.forceunpause` | Force-unpause (alias `.fup`) |
| `.restore <round>` | Restore a specific round's backup |
| `.skipveto` | Skip the veto phase (alias `.sv`) |
| `.roundknife` | Toggle the knife round (alias `.rk`) |
| `.playout` | Toggle playing out all rounds — the scrim setting |
| `.whitelist` | Toggle player whitelisting |
| `.readyrequired <n>` | Set how many ready players start the match |
| `.settings` | Print the current settings |
| `.map <mapname>` | Change the map |
| `.team1 <name>` / `.team2 <name>` | Set team names |
| `.asay <message>` | Speak in all-chat as an admin |
| `.prac` | Enter practice mode (alias `.tactics`) |
| `.exitprac` | Leave practice mode and return to match mode |
| `.reload_admins` | Reload `admins.json` without a restart |
| `.rcon <command>` | Send a command to the server |

## How do I make myself a MatchZy admin?

Two ways, and either works.

Use **CounterStrikeSharp's admin system** by adding yourself to `addons/counterstrikesharp/configs/admins.json` with the relevant flags. MatchZy maps them like this:

| Flag | Grants |
|---|---|
| `@css/root` | All MatchZy admin commands |
| `@css/config` | Config-related admin commands |
| `@css/map` | Change map and toggle practice mode |
| `@css/rcon` | Run `.rcon <command>` |
| `@css/chat` | Send admin chat with `.asay` |
| `@custom/prac` | Practice-related admin commands |

Or use **MatchZy's own list** at `csgo/cfg/MatchZy/admins.json`, which is simply SteamID64s:

```json title="csgo/cfg/MatchZy/admins.json"
{
  "76561198154367261": "",
  "76561198808392634": ""
}
```

The file creates itself when the plugin first loads. `.reload_admins` picks up changes without a restart.

> [!CAUTION] `matchzy_everyone_is_admin` does exactly what it says
> It defaults to `false`. Setting it to `true` gives every connected player admin permissions, including `.rcon`. It is a convenience for a private test server and nothing else.

## How do I record demos of my matches?

MatchZy records automatically. Recording starts once all teams have readied up and stops when the map produces a result. GOTV must be enabled — `tv_enable 1` — for this to work.

| Setting | Default | What it controls |
|---|---|---|
| `matchzy_demo_path` | `MatchZy/` | Folder for demos. Must not start with a slash, must end with one |
| `matchzy_demo_name_format` | `{TIME}_{MATCH_ID}_{MAP}_{TEAM1}_vs_{TEAM2}` | Filename pattern; `.dem` is added automatically |
| `matchzy_demo_upload_url` | `""` | If set, the zipped demo is POSTed here when recording stops |

Keep `{TIME}` in the name format — it is what makes each file unique, and without it demos overwrite each other.

If you upload demos, MatchZy sends three headers your endpoint can read: `MatchZy-FileName`, `MatchZy-MatchId` and `MatchZy-MapNumber` (zero-indexed within the series).

One warning from the project worth repeating: do not change `tv_delay` or `tv_enable` inside `warmup.cfg`, `live.cfg` and the other phase configs. Set `tv_delay` on the server generally instead. Changing it mid-match causes problems with demos.

## Which settings should I change before my first match?

Everything lives in `csgo/cfg/MatchZy/config.cfg`, which executes whenever the plugin loads. After editing, run `exec MatchZy/config.cfg` to reload it without restarting.

| Setting | Default | Why you might change it |
|---|---|---|
| `matchzy_minimum_ready_required` | `2` | Set to `0` to require every connected player to ready up |
| `matchzy_knife_enabled_default` | `true` | Set to `false` for scrims where sides are agreed in advance |
| `matchzy_playout_enabled_default` | `false` | Set to `true` for scrims — plays all rounds regardless of the winner |
| `matchzy_stop_command_available` | `false` | Set to `true` to let teams roll back a round themselves |
| `matchzy_pause_after_restore` | `true` | Whether the match stays paused after a round restore |
| `matchzy_kick_when_no_match_loaded` | `false` | Set to `true` on a dedicated match server so nobody wanders in between matches |
| `matchzy_autostart_mode` | `1` | `0` neither, `1` match mode, `2` practice mode on startup |
| `matchzy_hostname_format` | `MatchZy \| {TEAM1} vs {TEAM2}` | Server browser name; `""` keeps your existing hostname |
| `matchzy_enable_damage_report` | `true` | Per-round damage breakdown in chat |

The four phase configs — `warmup.cfg`, `knife.cfg`, `live.cfg` and `prac.cfg`, all in `csgo/cfg/MatchZy/` — are executed when each phase begins. This is where match convars belong, not in `server.cfg`. If those files are missing, MatchZy falls back to defaults compiled into the plugin. You can also add `live_override.cfg` or `live_wingman_override.cfg` to layer changes on top of the shipped live config rather than editing it.

## Where do match stats go?

MatchZy configures a local SQLite database automatically, writing to two tables: `matchzy_stats_matches` for match-level data such as match ID, team names and scores, and `matchzy_stats_players` for per-player stats.

To share stats across several servers, switch to MySQL in `csgo/cfg/MatchZy/database.json` by changing `DatabaseType` from `SQLite` to `MySQL` and filling in the host, database, username, password and port.

A CSV is also written per match into `csgo/MatchZy_Stats`, named `match_data_map{mapNumber}_{matchId}.csv`.

## FAQ

### Do I need a match config file to use MatchZy?

No. MatchZy starts in pug mode, where `.ready` and the knife round work with no configuration at all. A match config is only needed when you want players locked to specific teams and sides, or a BO3/BO5 series.

### Why can nobody join my server?

Check `matchzy_kick_when_no_match_loaded`. If it is `true`, MatchZy kicks everyone and blocks joins until a match is loaded with `matchzy_loadmatch`. That is deliberate behaviour for a dedicated match server, and surprising everywhere else. It defaults to `false`.

### Why does `.stop` do nothing?

`matchzy_stop_command_available` defaults to `false`, so the command is disabled until you turn it on. If it is enabled and still does nothing, check `matchzy_stop_command_no_damage` — that makes the command unavailable once a player has damaged an opponent that round.

### Can MatchZy work with a web panel?

Yes. MatchZy supports the Get5 web panel — G5V for the front end and G5API for the back end — so you can create teams, set up matches, run veto and see live scores and stats from a browser. The project documents three gaps in that integration: some stats such as KAST, flash assists and bomb plants are reported as zero; coaches cannot be assigned from the panel, only with `.coach <side>` in game; and backups cannot be listed or restored from the panel, though `.stop` and `.restore` still work in game.

### Does MatchZy replace an admin plugin?

No. Its admin commands are match commands — start, restart, pause, restore, change map. It has no kick, ban, gag or mute. For those you need either the native RCON commands covered in [Counter-Strike 2 server commands](/knowledge-base/counter-strike-2/how-to-add-admins-and-commands/) or a separate admin plugin.

### Why do my `.` commands do nothing?

Either MatchZy is not loaded — check `css_plugins list` — or the chat trigger has been changed. CounterStrikeSharp's `core.json` sets `PublicChatTrigger` to `!` and `SilentChatTrigger` to `/` by default; MatchZy's own commands accept both `.` and `!`.

### Can I use MatchZy just for grenade practice?

Yes, and it is one of the better reasons to install it. `.prac` puts the server in practice mode, which adds spawn teleports, bot placement and boosting, grenade rethrow with per-nade delays, saved lineups with `.savenade` and `.loadnade`, and `.clear` to remove active smokes and molotovs. `.exitprac` returns to match mode.

## What to read next

- [How to install plugins on a Counter-Strike 2 server](/knowledge-base/counter-strike-2/how-to-install-plugins/) — the Metamod and CounterStrikeSharp stack MatchZy needs
- [Counter-Strike 2 server commands](/knowledge-base/counter-strike-2/how-to-add-admins-and-commands/) — native RCON, kick and ban commands, and the full convar reference
- [Counter-Strike 2 configuration](/knowledge-base/counter-strike-2/configuration-overview/) — which config file executes when
- [Getting started with your Counter-Strike 2 server](/knowledge-base/counter-strike-2/getting-started-with-your-server/) — first boot, ports and connecting

Match servers are bursty by nature — idle most of the week, then ten players and a GOTV feed on a Tuesday night. Our [Counter-Strike 2 server hosting](/games/counter-strike-2/) plans give you the console and file access this setup needs.

---

Made with 💜 by GameServerKings
