Every server Unmetered traffic, DDoS protection and IPMI included. No setup fees, no contract. Unmetered traffic on every server See pricing

Guide · Gaming

Hosting game servers on dedicated hardware

Why clock speed and cache decide game server performance, how to estimate instances per server, and how to run game servers on Linux with DDoS protection.

  • 8 min read
  • Updated
  • FlexDedi Engineering

Run this guide on

Core 16X

  • AMD EPYC 4585PX · 16 cores
  • 192 GB DDR5 ECC
  • 2 × 3.84 TB NVMe Gen4
  • 10 Gbps unmetered
On this page

Game servers are an unusual workload. They are rarely limited by total CPU, memory or bandwidth; they are limited by how quickly one thread can finish each simulation tick. This guide explains what that means for hardware, how to estimate how many servers fit on one machine, and how to run them on Linux with sensible protection and backups.

The tick budget

An authoritative game server advances the world at a fixed rate. Each tick processes player input, physics, AI and game rules, then sends state to the clients. The time available per tick is simple arithmetic:

Tick rateTime per tick
20 Hz (Minecraft Java)50 ms
30 Hz33.3 ms
64 Hz15.6 ms
128 Hz7.8 ms

When a tick takes longer than its budget, the server falls behind and every player feels it as rubber-banding, delayed hits or blocks that reappear. More cores do not help when the work runs on one main thread, as much of the simulation does in many engines.

Why clock speed and cache matter

Per-thread performance is instructions per clock times frequency. Every FlexDedi server uses Zen 5 cores, so the differences come from clocks and cache: Core 16 boosts to 5.4 GHz and Core 16X to 5.7 GHz, against 4.4 to 4.5 GHz on the EPYC 9005 servers. Base clocks matter too, because a packed game host keeps all its cores busy: 4.3 GHz on Core 16X, 3.0 GHz on Core 16.

Cache matters because game state is irregular. Entities, chunks, physics bodies and pathfinding data are scattered through memory, and an L3 hit is roughly an order of magnitude faster than a trip to DRAM. A working set that fits in cache keeps the main thread computing instead of waiting.

3D V-Cache on Core 16X

The EPYC 4585PX in Core 16X stacks extra L3 cache on the processor, for 128 MB in total against 64 MB on the EPYC 4545P in Core 16. Large, irregular working sets are what 3D V-Cache is built for, and game simulation is one of them. How much it helps depends on the title, the map and the player count, so test your own game rather than assuming.

The cache is not split evenly. A 16-core Zen 5 processor has two 8-core dies (CCDs) with 32 MB of L3 each, and the extra 64 MB sits on one of them: 96 MB on one CCD, 32 MB on the other. Find which logical CPUs share the large cache:

bash
for d in /sys/devices/system/cpu/cpu*/cache/index3; do
  echo "$(cat "$d/size") $(cat "$d/shared_cpu_list")"
done | sort -u

Expect two lines such as 98304K 0-7,16-23 and 32768K 8-15,24-31; the numbering on your server may differ. Pin your most demanding servers to the large-cache CPUs. Some titles prefer frequency over cache, so benchmark the same map on each group before settling.

SMT and frequency policy

Give each server's main thread a physical core of its own; the SMT sibling can take helper threads. On bare metal you also control the frequency policy, which a VM never exposes. Check the driver and governor, and use performance on latency-sensitive hosts:

bash
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

The setting resets at reboot, so apply it from a small systemd unit to make it stick.

How many servers fit on one machine

There is no honest universal number. It depends on the title, mods, map size, player count and tick rate. Measure one instance at peak and do the arithmetic:

  1. Run one server with a realistic player count and record main-thread CPU use, resident memory (RSS), disk writes during saves, and network throughput.
  2. Apply each limit below and take the smallest result.
LimitEstimate
CPU(physical cores − cores reserved for OS, panel, backups) ÷ cores per instance
Memory(RAM − OS and page-cache headroom) ÷ peak RSS per instance
Network(port speed × safety factor) ÷ (players × bandwidth per player)
Disksaves that can overlap without stalling ticks

Example with assumed numbers, not measurements: each instance needs one physical core for its main thread and peaks at 8 GB of RAM. On Core 16X, reserving 2 cores and 32 GB gives 14 instances by CPU and (192 − 32) ÷ 8 = 20 by memory. CPU is the limit, so plan for about 14 and confirm under real load.

A few patterns hold across titles:

  • Persistent sandbox worlds (survival, building and colony games) grow in memory and save size as they age, so measure again every few weeks.
  • Match-based servers are short-lived and usually light on memory, so CPU sets the limit.
  • Minecraft Java runs world ticking on one main thread. Server software such as Paper lowers the cost per tick, and /mspt or the spark profiler shows how close you are to the 50 ms budget. Give the JVM a fixed heap (-Xms equal to -Xmx) sized to what the server uses, not to all the RAM you have.
  • Network is rarely the limit, because per-player traffic is small next to a 10 Gbps port. Packet rates and attack traffic are the bigger concerns.

DDoS protection

Game servers are a frequent DDoS target. Every FlexDedi IP has always-on DDoS protection included, so attack traffic is filtered without you having to switch anything on. Host-side hygiene still matters:

  • Open only the ports each game needs, with the right protocol, for example ufw allow 25565/tcp or ufw allow 27015/udp.
  • Keep RCON, query and admin ports off the public internet by binding them to 127.0.0.1 or your private network.
  • Put web panels behind a VPN or an IP allowlist, and never expose the databases that plugins or panels use.

Pick the location by where players are

Distance sets the latency floor. Light in fiber travels about 200 km per millisecond, so every 1,000 km of path adds at least 10 ms of round-trip time. As an estimate, Dallas is roughly 2,000 to 2,200 km from both Los Angeles and New York, a physical floor of about 20 to 22 ms round trip to either coast before routing adds more.

Choose the location nearest the bulk of your players: New York, Ashburn, Dallas or Los Angeles in North America; Amsterdam, Frankfurt or London in Europe; Singapore, Tokyo or Sydney in Asia-Pacific. Core 16 and Core 16X are available in all ten locations. Before you commit, run ping and traceroute toward your players' networks from the looking glass.

Linux setup with systemd

Start from a hardened baseline such as securing a new Linux server. Then run each game server as an unprivileged user, from its own directory, under systemd. A template unit covers many instances of the same game:

ini
# /etc/systemd/system/minecraft@.service
[Unit]
Description=Minecraft server %i
After=network-online.target
Wants=network-online.target

[Service]
User=minecraft
WorkingDirectory=/srv/minecraft/%i
ExecStart=/usr/bin/java -Xms8G -Xmx8G -XX:+UseG1GC -jar server.jar --nogui
Restart=on-failure
RestartSec=10
SuccessExitStatus=0 143
TimeoutStopSec=90
CPUAffinity=0-7 16-23
Nice=-5
NoNewPrivileges=true
ProtectSystem=full
PrivateTmp=true

[Install]
WantedBy=multi-user.target
bash
sudo useradd --system --create-home --home-dir /srv/minecraft --shell /usr/sbin/nologin minecraft
sudo systemctl daemon-reload
sudo systemctl enable --now minecraft@survival minecraft@creative
journalctl -u minecraft@survival -f

Each instance lives in /srv/minecraft/NAME. On stop, systemd sends SIGTERM; the server saves the world and the JVM exits with status 143, which SuccessExitStatus treats as clean. CPUAffinity pins instances to the large-cache CPUs found earlier. To move a lighter instance to the other CPUs, run sudo systemctl edit minecraft@creative and add an empty CPUAffinity= line followed by the new list, because the setting otherwise merges with the template's value. systemd provides no interactive console, so administer the servers over RCON with a client such as mcrcon.

LinuxGSM and panels

LinuxGSM

LinuxGSM is a command-line manager for more than 100 game servers. It installs the server, runs it in tmux, and adds monitoring, updates and backups. Each game gets its own user:

bash
sudo adduser vhserver
su - vhserver
curl -Lo linuxgsm.sh https://linuxgsm.sh && chmod +x linuxgsm.sh && bash linuxgsm.sh vhserver
./vhserver install
./vhserver start
./vhserver details

vhserver is Valheim; every supported game has its own short name. The project recommends cron jobs for monitor, which restarts a crashed server, and for update:

text
*/5 * * * * /home/vhserver/vhserver monitor > /dev/null 2>&1
*/30 * * * * /home/vhserver/vhserver update > /dev/null 2>&1

Pterodactyl-style panels

Panels in the Pterodactyl mold, including its fork Pelican, split the job in two: a web panel with a database where you create servers and users, and a daemon on each game host that runs every server in its own container with CPU, memory and disk limits. They suit hosts with many servers, or many people managing them. A few rules apply to any of them:

  • Run the panel on a small separate server or VM and reach the game hosts over private networking.
  • Set CPU limits per server and, where the panel supports it, pin threads so heavy servers land on the large-cache CPUs.
  • Containers publish ports through Docker, which bypasses UFW, so control exposure in the panel's port allocations and Docker's DOCKER-USER chain.

Backups

Worlds are the irreplaceable part. Back them up on a schedule, keep copies off the machine, and test restores:

  • Pause saving during the copy so the files are consistent. For Minecraft, send save-off and save-all flush over RCON, copy the world, then send save-on. LinuxGSM's ./vhserver backup writes its own archives.
  • Ship copies to another server with restic or rsync. A storage server in the same location receives them over the free private network, a second location protects against a site-level incident, and unmetered traffic means off-site copies add no transfer fees.
  • Keep several generations, because a corrupted world can go unnoticed for days.

Run it on FlexDedi

For most game hosting, start with Core 16X ($399/mo): EPYC 4585PX with 3D V-Cache, 4.3 GHz base and 5.7 GHz boost, 192 GB of DDR5 ECC and 2 × 3.84 TB NVMe. Core 16 ($299/mo) suits lighter titles and test servers. Both have 10 Gbps ports with unmetered traffic and always-on DDoS protection, are available in all 10 locations, and are usually ready within 15 minutes.

If you host many small servers alongside panels and databases, Pro 32 ($749/mo) trades per-core speed for 32 cores and 384 GB. See game server hosting for more.

More guides

Your next server is minutes away.

Deploy a Core 16 for $299/mo, or let our engineers size the right fleet for you.

  • No setup fees
  • Unmetered traffic
  • Cancel anytime