Use case · Game server

Project Zomboid dedicated server on bare metal: memory, ports, Build 42

A Project Zomboid dedicated server is Steam app 380870, pulled anonymously with SteamCMD, launched with start-server.sh on Linux or StartServer64.bat on Windows, and reached by players on UDP 16261 and 16262. It is a Java process, so the number that decides whether it stays up is the heap you give it with -Xmx. This page covers the install as PZwiki documents it, where memory is set, the server settings that matter, and the Build 41 to 42 change.

See the machines

What the server process needs

The server needs a 64-bit OS, a Java heap sized for the world, and two open UDP ports. PZwiki publishes no per-player RAM figure, so size from the heap you intend to set and leave headroom for the operating system. The official numbers it does publish are these:

ItemPZwiki valueWhere it lives
Steam app id380870SteamCMD app_update
Game port16261 UDP (DefaultPort)servertest.ini
Direct connection port16262 UDP (UDPPort)servertest.ini
PlayersMaxPlayers=32 default, 100 maxservertest.ini
RCONRCONPort=27015, RCONPassword emptyservertest.ini
Heap-Xms / -Xmx, 16 GB in the stock Windows batchStartServer64.bat

PZwiki warns that more than 32 players may give poor map streaming and desync. Raising MaxPlayers is a setting; whether the world copes is a separate question.

Setting the heap

Memory is set with the JVM flags -Xms (starting heap) and -Xmx (ceiling). On Windows they sit on the java line in StartServer64.bat, and PZwiki says that file starts the server with 16 GB: edit both values down to the memory you can give it, or the server fails at launch with memory errors. Its own example runs -Xms6g -Xmx6g.

The dedicated-server page documents only the Windows file. On Linux, open start-server.sh and look for -Xmx; if it is not there, the flags are in the vmArgs list of the ProjectZomboid64.json file beside it, the launcher config the wiki names among its startup parameters. Set -Xmx wherever your copy keeps it. The wiki also notes that if the JVM cannot reserve the -Xms amount the process will not start, so on a shared box a lower or absent -Xms is the safer choice.

No official table maps players to gigabytes. What grows the heap is the number of players, how much of the map they have loaded, and the mods in Mods=. Start conservative, watch the process under a full evening of play, and raise -Xmx before it hits the ceiling, not after.

Installing on Linux with SteamCMD

PZwiki's Linux procedure installs SteamCMD from the distribution, creates an unprivileged user, and keeps the server in /opt/pzserver. Do not run it as root.

  1. Install steamcmd (Debian and Ubuntu need the multiverse or non-free repository and the i386 architecture).
  2. Create the user with sudo adduser pzuser, then sudo mkdir /opt/pzserver and sudo chown pzuser:pzuser /opt/pzserver.
  3. Switch to it with sudo -u pzuser -i and write the SteamCMD script below. Running the same script later is how you update.
  4. Open UDP 16261 and 16262 in the firewall.
  5. Start tmux, cd /opt/pzserver/, run bash start-server.sh, and type the admin password when the first start asks for it.
cat >$HOME/update_zomboid.txt <<'EOL'
// update_zomboid.txt
//
@ShutdownOnFailedCommand 1 //set to 0 if updating multiple servers at once
@NoPromptForPassword 1
force_install_dir /opt/pzserver/
//for servers which don't need a login
login anonymous
app_update 380870 validate
quit
EOL

export PATH=$PATH:/usr/games
steamcmd +runscript $HOME/update_zomboid.txt
sudo ufw allow 16261/udp
sudo ufw allow 16262/udp
sudo ufw reload

bash start-server.sh -servername NAME switches to a different .ini and save folder; -nosteam runs a non-Steam server for GOG players. A Windows box uses SteamCMD's force_install_dir C:\PZServer and StartServer64.bat instead; both Linux and Windows Server images are in the one-click OS list.

Files and settings after the first start

The first start writes a world called servertest under the server user's home: settings in ~/Zomboid/Server/servertest.ini, sandbox rules in servertest_SandboxVars.lua, spawn files beside them, and the world in ~/Zomboid/Saves/Multiplayer/servertest. Those two directories are what you back up.

  • Password= gates joining; Open=false makes admins create accounts by hand.
  • Public=true lists the server in the in-game browser; PublicName= is what it shows.
  • Mods= and WorkshopItems= take mod IDs and Workshop item IDs; clients download Workshop mods on connect.
  • SaveWorldEveryMinutes= defaults to 0, so loaded areas are saved only as players leave them.
  • .ini edits can be made while the server runs; reloadoptions applies them, showoptions prints them.

PZwiki flags a bug where DoLuaChecksum=true rejects some clients on Linux servers with false positives. Turning it off removes a file-integrity check, so do it only if players actually hit it.

Build 42 and the legacy41 branch

PZwiki lists Build 42 as the stable release since 29 July 2026 (42.20.x), so a plain app_update 380870 validate installs it. To keep a Build 41 world, install with app_update 380870 -beta legacy41 validate and put the same line in the update script. Keep the server on the branch your players run.

A machine that hosted Build 41 can fail under Build 42 with "Illegal termination of worker thread". The wiki's fix: check that steam_appid.txt holds only 108600, back up your .ini, .lua and saves, then remove the old Zomboid folder so Build 42 recreates it.

Running it day to day

Admin commands work in the console or in game with a leading slash: save, quit (save and stop), players, servermsg "text", setaccesslevel and checkModsNeedUpdate. Stop with quit before every update and every copy of the save folder.

PZwiki gives a systemd unit that feeds commands through a FIFO, but notes the developers discourage running the server that way because it does not handle SIGTERM; tmux and a clean quit remain the documented path. For a second world on the same box, run a second user with its own SteamCMD copy and give it two further UDP ports, for example 16274 and 16275.

Why a whole machine, and which one

The heap is the constraint, so the machine's memory should belong to the server and nothing else. Our game server hosting is bare metal: the gaming page puts access at up to 90% of a server's resources against 15% on virtual machines, with each configuration offered with the operating systems its line supports (up to 33 install in one click on the widest lines). Rack servers and blades each have an out-of-band controller (HPE iLO, Dell iDRAC or a Supermicro BMC) whose browser console the dashboard publishes once you add a console login, so a box that stops booting is still reachable.

Every machine has an unmetered port, 1 Gbps on most lines and 500 Mbps on the rest, with no transfer allowance. Pick the city nearest your players from the five locations, three in the US (New York, Miami, San Francisco) and two in Europe (Amsterdam, Bucharest), all on our own network, AS19624. A racked machine goes live roughly half an hour after approval; a build to order takes 4 to 24 hours. The dedicated range lists every line, from single cartridges to dual-socket blades with ECC memory.

Wrong place for it: two friends for one weekend. The in-game Host button runs a multiplayer server from your own PC, and PZwiki equates its Server Memory option with the heap setting above.

Questions

Which ports does a Project Zomboid server use?

UDP 16261, the default game port players enter when they add the server, and UDP 16262 for direct connections. Both are set in servertest.ini as DefaultPort and UDPPort. RCON, if you enable it, listens on 27015 by default. Each extra instance on the same machine needs two more UDP ports.

What heap size does the server want?

PZwiki gives no per-player figure. The heap is set with -Xmx, and the stock Windows batch starts at 16 GB, which PZwiki says to change to the memory you actually have free. Size from players, explored map and mods, watch real usage, and leave memory for the operating system.

Where is the admin password set?

The first start of start-server.sh or StartServer64.bat asks for it and creates the admin account. It can also be passed as the -adminpassword startup parameter. The join password for players is a different setting, Password= in servertest.ini.

Can I still run Build 41?

Yes. Install or update with app_update 380870 -beta legacy41 validate. Build 42 is the stable branch, so a plain app_update moves the server to it.

Do settings changes need a restart?

Not for servertest.ini. Save the file while the server runs, then run reloadoptions in the console. Check the live values with showoptions.

Put the world on its own machine

Bare metal for game servers in five cities: an unmetered port, root, and an out-of-band console on rack servers and blades.

See the machines

Related on Server Room

Other use cases