The cheapest useful way to watch a Valheim server is to ask it, over the Steam query protocol, how many players it has. The server answers A2S queries on the game port plus one - UDP 2457 by default - and any A2S tool returns the server name and player count in a few milliseconds. That covers "is it up" and "is anyone on". For who joined, who left and who died, read the server log instead, because it records every connection. Add an outside check that alerts when the query stops answering two or three times in a row, and you will know the server is down before your group does.
What follows covers each layer: the query, the log, uptime checks that actually understand UDP, resource monitoring, and how to keep alerts from turning into noise everyone mutes.
What is worth watching#
Monitoring is only useful if each signal answers a question you would act on. For a Valheim server there are four:
| Question | Signal | Where it comes from |
|---|---|---|
| Is the server reachable? | A2S query answers | UDP query port, from outside |
| Is anyone playing? | Player count | A2S query, or the log |
| Who joined, left or died? | Connection and character lines | The server log |
| Is it about to fall over? | Memory and CPU against the limit | The host or panel |
A process that is running is not the same as a server people can join. The process can be alive while stuck loading a world, while a firewall rule blocks the port, or while it waits on a mod that failed to load. The query from outside is the check that matches what players experience, so it is the one to alert on. Everything else is for diagnosis.
The general argument for alerting on symptoms rather than causes is in monitoring that tells you something. For Valheim specifically, it means: alert when the query fails, look at memory and the log when it does.
The Steam query port and A2S#
Valheim's dedicated server uses two UDP ports. The game port (-port, 2456 by default) carries gameplay. The port above it carries Steam server queries - the A2S protocol that server browsers use to list a server and show its player count.
| Port | Protocol | What answers there |
|---|---|---|
2456 | UDP | Game traffic |
2457 | UDP | A2S queries: info, players, rules |
If you change -port, the query port moves with it: -port 2466 means queries on 2467. Both must be open in every firewall between the monitoring tool and the server. A query that times out from outside but answers from the machine itself is a firewall problem, not a server problem.
A2S has three requests. A2S_INFO returns the server name, map, player count and maximum players. A2S_PLAYER returns a list of connected players with name, score and time connected. A2S_RULES returns key-value pairs a server chooses to publish. For Valheim, A2S_INFO is the reliable one. The player list is less useful than it sounds - names may be blank or generic, depending on version and platform - so treat the count as the truth and the list as a bonus. Query ports and A2S explains the protocol and why some games answer it differently from others.
Querying with python-a2s and GameDig#
Two tools cover almost every need. python-a2s is a small Python library that sends A2S requests and returns parsed results:
$ pip install python-a2simport a2sADDRESS = ("203.0.113.10", 2457) # query port, not game portinfo = a2s.info(ADDRESS, timeout=3.0)print(f"{info.server_name}: {info.player_count}/{info.max_players}")for player in a2s.players(ADDRESS, timeout=3.0): print(player.name or "(no name)", round(player.duration / 60), "min")A timeout raises an exception, which is what you want: a monitoring script can treat "exception" as "down". Print the whole info object once to see what your server version returns - the fields are the same for every A2S game, but what Valheim puts in some of them has changed over time.
GameDig is a Node.js tool that knows the quirks of hundreds of games, including which port to query:
$ npm install -g gamedig$ gamedig --type valheim 203.0.113.10:2456GameDig's Valheim profile accounts for the query port offset, so you give it the game port. If it times out, check the version's documentation for how it treats the port, and try the query port directly. It returns JSON with name, numplayers, maxplayers and a ping, which makes it easy to feed into anything else.
There is also the Steam Web API's IGameServersService/GetServerList, which lists servers registered with Steam's master server and needs a Steam Web API key. It shows what the community browser sees, which is useful when the question is "why is my server missing from the list". It is not a health check: registration lags behind reality by minutes. Valheim server not showing in the list covers that case.
Tracking players from the log#
The log is the only source that knows who did what. Every connection, character spawn and disconnect produces a line. The exact wording changes between versions, and crossplay servers log platform IDs through PlayFab rather than plain SteamIDs, so verify against your own log before you rely on a pattern. On a recent Steam-only server, the lines worth grepping look like this:
Got connection SteamID 76561198012345678Got character ZDOID from Ragnar : 1234567890:1Got character ZDOID from Ragnar : 0:0Closing socket 76561198012345678World saved ( 412.338ms )What each of those lines tells you:
Got connection SteamID- a client has connected, before it has picked a character. Use the ID for the admin and ban lists.Got character ZDOID from <name> : <id>- the player's character has spawned, so this is the real "joined" moment, with the character name.- The same line ending in
0:0- the character has died. This is the line Discord death announcers are built on. Closing socket- the client has gone.World saved- a save completed, with how long it took. A save time that keeps growing is an early sign of a world getting heavy.
On a systemd install, follow the log live with journalctl -u valheim -f. With -logFile, tail -F the file instead; -F follows the file through rotation. A small loop is enough for a join and leave feed:
#!/usr/bin/env bashjournalctl -u valheim -f -o cat | while read -r line; do case "$line" in *"Got character ZDOID from"*": 0:0"*) echo "DEATH ${line#*from }" ;; *"Got character ZDOID from"*) echo "JOIN ${line#*from }" ;; *"Closing socket"*) echo "LEAVE ${line##* }" ;; esacdoneThe death pattern must be tested before the join pattern, because both contain the same prefix. Replace the echo with a call to a Discord webhook and you have a basic announcer without any mods. A full walk through the log, including the start-up lines and the errors worth acting on, is in the Valheim server log explained.
If you would rather not maintain a script, the Discord Connector mod does the same job from inside the server and also handles crossplay IDs - see Discord Connector for Valheim.
Uptime checks that understand UDP#
Most uptime services check websites: an HTTP request, or a TCP connection to a port. Neither works for Valheim. The server does not speak HTTP, and both its ports are UDP, so a TCP port check against 2456 fails even when the server is perfectly healthy. A plain ICMP ping only proves the machine is up, not the game.
What works:
- A self-hosted checker that speaks A2S. Uptime Kuma, the common self-hosted option, has game server monitor types; recent versions include one built on GameDig. Point it at the game server address with the Valheim type, and it alerts through Discord, email, Telegram and most other channels. Older versions offered a Steam game server type that required a Steam Web API key, so check what your version has.
- A cron job on another machine. Run the Python script above every minute from a different server, count consecutive failures, alert on the third. Fifteen lines of code and no dependencies beyond
python-a2s. - A status endpoint from your container. The
lloesche/valheim-serverDocker image can run a small status web server that publishes the query result as JSON (theSTATUS_HTTPvariables in its README). An ordinary HTTP uptime checker can then watch that. Note that it runs inside the same container, so it cannot tell you the outside world cannot reach the game port.
Run the check from outside the server's own network. A check from the same machine says nothing about the firewall, the routing or the provider, which are the things that break without the process noticing.
Memory, CPU and disk#
The query tells you something is wrong; the resource graphs usually tell you what. Watch three numbers.
| Metric | Healthy | Worth acting on |
|---|---|---|
| Memory | Steady after the world loads, rising slowly over days | Within 10-15% of the limit, or a step jump after a mod |
| CPU | Spikes when players fight, build or arrive in new zones | Pinned at the limit with few players on |
| Disk | Grows slowly with world size and backups | Backups filling the disk, or the world .db doubling in a week |
Memory is the one that ends sessions. Valheim's usage grows with explored and built area, and a server that reaches its memory limit is stopped hard, without saving. The pattern to watch for is a slow upward slope across days with no levelling off - that is what a scheduled restart flattens, covered in Valheim scheduled restarts. For realistic figures by group size, see how much RAM a Valheim server needs.
On your own Linux machine, systemctl status valheim shows current memory for the unit, and ps -o rss,cmd -C valheim_server.x86_64 gives the process's resident memory in kilobytes. For history, anything that records metrics works - node_exporter and Prometheus, Netdata, or the host's own graphs.
On RE:NODE the console shows live graphs of memory, CPU and disk against the plan's limits, so the "how close am I" question is answered without installing anything. A watcher also polls every two minutes for a server that went offline or whose uptime went backwards. Restarts you asked for are not counted; three unexpected restarts in an hour put a warning on the server page and open a ticket automatically, so a crash loop is noticed even if you are asleep. The console section of the guides shows where the graphs are.
Alerts that people do not mute#
An alert that fires every time a player's ping wobbles is muted within a week, and then it misses the real outage. A few rules keep alerts meaningful:
- Require consecutive failures. One lost UDP packet is normal. Alert after three failed checks one minute apart, not after one.
- Alert on recovery too. "Back up after 4 minutes" tells you whether to investigate or ignore it.
- Separate admin alerts from player news. Join and death messages belong in a channel players read. Downtime and memory warnings belong somewhere only admins see.
- Silence planned work. If the server restarts at 05:00 every day, the checker should not page anyone at 05:01. Either pause it during the window or require failures to last longer than a restart takes.
- Include what you know. An alert that says "query failed from Frankfurt, last player count 3, memory 92% of limit" is one you can act on from a phone.
A minimal consecutive-failure checker:
import a2s, json, pathlib, sys, urllib.requestADDRESS = ("203.0.113.10", 2457)WEBHOOK = "https://discord.com/api/webhooks/REPLACE/ME"STATE = pathlib.Path("/var/tmp/valheim_failures")def notify(text): body = json.dumps({"content": text}).encode() req = urllib.request.Request(WEBHOOK, body, {"Content-Type": "application/json"}) urllib.request.urlopen(req, timeout=5)fails = int(STATE.read_text()) if STATE.exists() else 0try: a2s.info(ADDRESS, timeout=3.0) if fails >= 3: notify("Valheim is answering again.") fails = 0except Exception: fails += 1 if fails == 3: notify("Valheim has not answered queries for 3 minutes.")STATE.write_text(str(fails))Run it every minute from cron on a different machine. It alerts once on the third failure and once on recovery, not every minute in between. Discord webhooks for server status covers formatting and the rate limits Discord applies.
Common monitoring problems#
The query times out but players can join. The monitoring tool is hitting the game port instead of the query port, the query port is closed in a firewall, or the server is crossplay and is not answering Steam queries the way your tool expects. Query from the machine itself to separate the cases.
The player count is stuck at zero while people play. Same causes, or a tool that is querying a different server on the same address. Check the server name in the response.
The count is right but names are missing. Expected on many Valheim versions. Use the log for names.
Uptime check says down every morning. The scheduled restart. Pause the check during the window, or require failures to persist for longer than the restart takes.
The log patterns stopped matching after an update. Iron Gate changes log wording occasionally. Look at a fresh log after each major patch and update your patterns.
FAQ#
What port do I query to get a Valheim server's player count?
The game port plus one, over UDP. With the default -port 2456, query 2457. GameDig takes the game port and adds the offset itself; python-a2s and most other A2S libraries need the query port.
Can I see which players are online without a mod?
Yes, from the server log. Each character spawn is logged with the character's name and each disconnect with the player's ID, so a script that follows the log can keep a live list. The A2S player list may or may not include names depending on version.
Why does a TCP port check say my Valheim server is down?
Because Valheim does not use TCP. Both of its ports are UDP, so a TCP connection attempt always fails. Use a checker that sends A2S queries over UDP.
How often should an uptime check run?
Once a minute, alerting after three consecutive failures. That catches a real outage within about three minutes without waking anyone for a dropped packet.
Does monitoring the server slow it down?
No. An A2S query is a single small UDP packet and reply, answered off the main game thread. Even one per second would be invisible next to a single player's traffic.


