You want to run your own Hytale server. The official manual has every flag and config key — what it doesn't have is the opinionated "this is the order you should actually do things, and here's where you'll get stuck" walkthrough. That's this post.

I'll assume you want a small-to-medium server (up to ~40 players), running on Linux, staying up through the night without babysitting. Windows notes where it matters.


TL;DR — what it takes

  • A Linux box with 4 GB+ RAM, modern CPU (good single-thread perf wins here), ~50 GB NVMe.
  • Java 25 (Temurin) — older Java won't start the server.
  • One UDP port open. 5520 by default.
  • A Hytale account for the one-time device-auth flow.
  • About 30 minutes if you follow along; ~2 hours if you improvise.

If you only read one thing: Hytale speaks QUIC over UDP, not TCP. Every "my friends can't join" thread boils down to someone forwarding TCP. Forward UDP.


Pick a host that actually fits

Don't over-spec. A 4-vCPU, 8 GB VPS is plenty for a dozen friends. RAM is the first thing you'll run out of — not CPU — because every extra chunk a player loads sits in the JVM heap until it unloads.

My rule of thumb:

  • Up to 10 players: 4 vCPU, 8 GB RAM, NVMe. Pick the cheapest option you trust.
  • 10–40 players: 6–8 fast cores, 16 GB RAM.
  • 40+ or modded: dedicated box, 8+ cores, 32 GB+. Don't do this on a shared VPS.

A raw VPS beats a managed "game server" panel for learning — you keep full control, you learn the stack, and you're not locked into anyone's UI. If you'd rather skip the sysadmin side and just play, any reputable game host will have a one-click Hytale template. Pick one that understands UDP-based games (which is all of modern gaming).


Step 1 — Install Java 25 (and don't trust apt's default)

Ubuntu 24.04 and Debian 12 ship with older Java in their default repos. Hytale needs Java 25 exactly — it's happy with Eclipse Temurin, which is the OpenJDK build most server folks run.

Quickest path on Debian/Ubuntu:

sudo apt install -y wget apt-transport-https gpg
wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public | sudo gpg --dearmor -o /etc/apt/keyrings/adoptium.gpg
echo "deb [signed-by=/etc/apt/keyrings/adoptium.gpg] https://packages.adoptium.net/artifactory/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/adoptium.list
sudo apt update
sudo apt install -y temurin-25-jre

Verify:

java --version

If the first line isn't openjdk 25.x.x, stop here and fix the PATH. I've burned an hour debugging a config only to realize apt had silently left Java 17 as the default.


Step 2 — A dedicated user (non-negotiable)

Never run a game server as root. If a mod does something bad, it has root on your box. Create a service user:

sudo adduser --disabled-password --gecos "" hytale
sudo mkdir -p /opt/hytale
sudo chown hytale:hytale /opt/hytale

Everything below runs as hytale inside /opt/hytale.


Step 3 — Get the server files the boring way

There are two documented ways to obtain the server binaries: copy them out of the Hytale Launcher install, or use the official hytale-downloader CLI.

Use the CLI. Always.

Copying from the Launcher is tempting for a one-off test, but it breaks the folder layout that the built-in auto-updater expects, which means you lose the one big sysadmin win the server gives you for free. The downloader lays out Server/, Assets.zip, start.sh and jvm.options in the exact shape the updater needs.

Grab it from the official URL:

cd /opt/hytale
sudo -u hytale wget https://downloader.hytale.com/hytale-downloader.zip
sudo -u hytale unzip hytale-downloader.zip
sudo -u hytale rm hytale-downloader.zip
sudo -u hytale chmod +x hytale-downloader
sudo -u hytale ./hytale-downloader
ls
# → Server/  Assets.zip  start.sh  start.bat  jvm.options  hytale-downloader

Direct download: downloader.hytale.com/hytale-downloader.zip (Linux & Windows in the same archive). Read the bundled QUICKSTART.md for the full flag list.

If you want the bleeding edge:

./hytale-downloader -patchline pre-release

Keep this on release for anything resembling production.


Step 4 — First launch & the one-time device auth

Start it once in the foreground so you can complete auth. Use the wrapper script — it handles the JVM args, the Assets path, and the exit-code-8 update loop correctly:

cd /opt/hytale
./start.sh

You'll see it come up, generate config.json, load the assets, and park on a console prompt. Type:

/auth login device

It prints a URL and a code. Open the URL on any machine, sign in, paste the code. When you see:

Authentication successful! Mode: OAUTH_DEVICE

…the server is ready to accept players. The token is stored on disk, so you won't do this again on the same box unless you wipe the auth state.

Gotcha worth knowing: there's a hard cap of 500 authenticated servers per Hytale license. For a single community server you will never hit it. If you plan to operate a network, read the Server Provider Authentication Guide before you start auto-provisioning anything.


Step 5 — Open the right port (UDP, not TCP)

Hytale's networking is built on QUIC, which lives entirely over UDP. TCP port 5520 does nothing. Forward UDP.

sudo ufw allow 5520/udp
sudo ufw status numbered

Behind a home router: forward UDP port 5520 to your server's LAN IP. On a cloud VPS: make sure the provider's security group/firewall (separate from Linux's!) also allows UDP 5520.

Changing the port is one flag — pass it via the wrapper:

./start.sh --bind 0.0.0.0:3500

Or the same flag inside your systemd ExecStart.


Step 6 — Run it under systemd (correctly)

This is where naive guides go wrong. Hytale's wrapper script restarts on exit code 8 to apply updates — if your systemd unit sets Restart=always, you'll end up fighting systemd over who restarts the process. You want systemd to restart on failure only and let the wrapper handle updates.

sudo tee /etc/systemd/system/hytale.service >/dev/null <<'EOF'
[Unit]
Description=Hytale Server
After=network-online.target

[Service]
Type=simple
User=hytale
WorkingDirectory=/opt/hytale
ExecStart=/opt/hytale/start.sh
SuccessExitStatus=0 8
Restart=on-failure
RestartSec=10
LimitNOFILE=65535
KillSignal=SIGINT
TimeoutStopSec=60

# hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ReadWritePaths=/opt/hytale

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now hytale
sudo systemctl status hytale
journalctl -u hytale -f

Two things that are not in most examples:

  • SuccessExitStatus=0 8 — tells systemd that exit code 8 (update-triggered) is not a failure. The wrapper will re-exec itself; systemd sits out of it.
  • KillSignal=SIGINT — gives the server a chance to flush world data on shutdown. Default SIGTERM sometimes cuts off mid-write, and voxel worlds do not forgive half-written chunks.

Step 7 — Tune memory in jvm.options

The wrapper reads a jvm.options file sitting next to start.sh. One flag per line, # for comments. For an 8 GB VPS running a small server:

# /opt/hytale/jvm.options
-Xms2G
-Xmx6G
-XX:+UseG1GC
-XX:+ParallelRefProcEnabled
-XX:MaxGCPauseMillis=200

Rule of thumb: give the JVM at most ~75% of physical RAM. The rest belongs to the OS, filesystem cache, and the asset file the server mmaps. If -Xmx is too aggressive and the box starts swapping, latency explodes and players blame your "laggy server" for two hours before you notice.

If the server feels sluggish and CPU is pinned for no obvious reason, it's almost always the garbage collector. Either give it more heap, or tune MaxGCPauseMillis down.


Step 8 — Back up before you regret it

The wrapper already runs periodic in-process backups into Server/backups/. That's good for accidental player damage; it's not a backup. Same disk, same server — if the box dies, both are gone.

Add a second layer: compressed snapshots of the whole universe/ directory, retained 14 days, ready to sync off-box:

sudo -u hytale mkdir -p /opt/hytale/offsite

sudo tee /etc/cron.d/hytale-backup >/dev/null <<'EOF'
0 */6 * * * hytale tar -czf /opt/hytale/offsite/universe-$(date +\%Y\%m\%d-\%H\%M).tar.gz -C /opt/hytale/Server universe 2>/dev/null
30 3 * * * hytale find /opt/hytale/offsite -name 'universe-*.tar.gz' -mtime +14 -delete
EOF

Then point restic, rclone or rsync at /opt/hytale/offsite/ and push it to object storage. A backup that lives on the same machine as the server is not a backup.


Step 9 — Let the server update itself

Hytale ships with a built-in updater. The flow is simple once you know it:

  1. Server checks for a new version hourly (by default).
  2. New build downloads to updater/staging/.
  3. You (or auto-apply) run /update apply --confirm. Server exits with code 8.
  4. The wrapper detects the 8, swaps in new binaries without touching config.json, your mods or your worlds, and relaunches.

The full set of in-console commands is in java -jar HytaleServer.jar --help and the manual. The three you'll use most:

/update check
/update apply --confirm
/update status

If you want updates to apply themselves when nobody is online, set this in config.json:

"Update": {
  "AutoApplyMode": "WhenEmpty",
  "RunBackupBeforeUpdate": true
}

Protocol note: right now server and client protocol versions must match exactly. When Hytale pushes an update, you have a short window before updated clients can't connect anymore. Plan 10-minute maintenance blocks around release days and you'll never feel it.


Common mistakes (the ones I keep seeing)

  • Forwarding TCP. Hytale is UDP-only. TCP forwarding achieves nothing.
  • Running as root. One compromised mod = compromised box. Always use a dedicated user.
  • Using Java 17 or 21. Hytale won't start. Use Java 25.
  • Allocating -Xmx = total RAM. The OS and asset mmap also need memory. Leave ~25% to the system.
  • Copying files out of the Launcher for a production server. Breaks auto-update. Use the downloader CLI.
  • Skipping the second backup layer. In-process backups on the same disk do not survive disk failure.
  • Forgetting the provider firewall. Cloud hosts have their own security group on top of Linux. Both must allow UDP 5520.

FAQ

What are the minimum requirements for a Hytale server?

4 GB RAM, Java 25, x64 or arm64, enough disk for Assets.zip (~3 GB) plus world data. Official manual lists 4 GB as the floor.

What port does Hytale use?

UDP 5520 by default. It uses the QUIC protocol, so TCP is not involved.

Can I run the Hytale server on a Raspberry Pi?

Technically yes — arm64 is officially supported, and a Pi 5 has enough cores. Practically you'll want more than 4 GB RAM and a fast microSD or NVMe HAT. For more than 2–3 players it will struggle.

Does Hytale need port forwarding?

If your server is behind a home router, yes — forward UDP 5520 (or your custom port) to the server's LAN IP. On a VPS with a public IP, just open it in the firewall.

How do I authenticate a Hytale server?

Run /auth login device in the server console. It prints a URL and a one-time code; sign in at accounts.hytale.com/device, enter the code, the server stores the token locally.

Can Hytale servers install mods?

Yes. Drop the .zip or .jar mod file into Server/mods/ and restart.

How do I update a Hytale server?

Run /update check, then /update apply --confirm. The server exits with code 8, the wrapper script restarts it on the new version. Config, worlds and mods are preserved.


Reference

Official Hytale links

Java runtime

Community

Related guides on this blog

I'll keep this post in sync when the protocol-tolerance window ships and when the community Docker images stabilise.

Last updated: April 2026.