Valheim Server Performance and Optimization Guide
Running a Valheim dedicated server is straightforward, but keeping it running smoothly as your world grows is a different challenge. Large builds, terrain modifications, and mods all take their toll on performance. This guide walks you through every optimization available to keep your Viking world lag-free.
Understanding Valheim Server Performance
Valheim's server operates on a tick-based system. Each tick, the server processes world state, entity positions, AI behavior, and player actions. When the server cannot complete a tick in time, players experience lag, rubber-banding, and desync.
Key Performance Concepts
| Concept | Description | Target |
|---|---|---|
| Tick Rate | How often the server updates game state | 20 ticks/second (50ms per tick) |
| World Complexity | Total number of placed objects, terrain changes, and entities | Lower is better |
| Instance Count | Number of active creatures, items, and interactable objects | Under 800 recommended |
| Network Latency | Round-trip time between player and server | Under 100ms ideal |
| World File Size | Size of the .db and .fwl files on disk | Monitor for unusual growth |
---
System Requirements and Hardware Recommendations
Performance scales with player count, world age, and mod usage. Use this table as a starting point.
Hardware Scaling Guide
| Players | CPU | RAM | Storage | Bandwidth | World Age |
|---|---|---|---|---|---|
| 2-4 | 2 cores @ 3.0 GHz | 4 GB | 10 GB SSD | 5 Mbps up | Any |
| 5-7 | 4 cores @ 3.0 GHz | 8 GB | 20 GB SSD | 10 Mbps up | Any |
| 8-10 | 4+ cores @ 3.5 GHz | 16 GB | 30 GB SSD | 20 Mbps up | Moderate |
| 8-10 (heavy mods) | 6 cores @ 3.5 GHz | 32 GB | 50 GB NVMe | 30 Mbps up | Any |
---
Step 1: Server Startup Optimization
The way you launch your server has a measurable impact on performance. Startup flags control memory behavior, logging, and core functionality.
Startup Flags and Parameters
Linux start script with optimized flags:
#!/bin/bash
export SteamAppId=892970
export LD_LIBRARY_PATH=./linux64:$LD_LIBRARY_PATH
# Set process priority to high
nice -n -10 ./valheim_server.x86_64 \
-nographics \
-batchmode \
-name "My Valheim Server" \
-port 2456 \
-world "Dedicated" \
-password "YourPassword" \
-public 1 \
-saveinterval 1800 \
-backups 4 \
-crossplay
Windows start script:
@echo off
cd /d "%~dp0"
start /high valheim_server.exe -nographics -batchmode -name "My Valheim Server" -port 2456 -world "Dedicated" -password "YourPassword" -public 1 -saveinterval 1800 -backups 4 -crossplay
Key Flags Explained
| Flag | Purpose | Recommendation |
|---|---|---|
-nographics | Disables GPU rendering | Always use on dedicated servers |
-batchmode | Runs without GUI window | Always use on dedicated servers |
-saveinterval | Seconds between autosaves (default: 1200) | 1800 for large worlds |
-backups | Number of automatic backup copies | 4 minimum |
-crossplay | Enables cross-platform play | Slight overhead, enable only if needed |
-public 0 | Hides from server browser | Reduces query traffic |
Memory Allocation
Valheim's Unity engine manages memory automatically, but you can influence behavior at the OS level.
Linux -- increase memory limits:
# Add to your start script before the server binary
ulimit -v unlimited
ulimit -m unlimited
Windows -- set process priority via PowerShell:
Start-Process -FilePath "valheim_server.exe" -ArgumentList "-nographics -batchmode -name `"Server`" -port 2456 -world `"Dedicated`" -password `"pass`"" -Priority High
CPU Affinity Settings
On multi-core systems, pinning the server to specific cores prevents the OS from migrating the process between cores, which reduces cache misses.
Linux -- set CPU affinity:
# Pin to cores 0 and 1
taskset -c 0,1 ./valheim_server.x86_64 -nographics -batchmode ...
Windows -- set CPU affinity via PowerShell:
$process = Get-Process -Name "valheim_server"
$process.ProcessorAffinity = 0x03 # Cores 0 and 1 (binary: 11)
---
Step 2: World Optimization
As players explore, build, and terraform, the world file grows. An unmanaged world will eventually cause performance degradation.
World File Size Management
Valheim stores world data in two files:
| File | Purpose | Typical Size |
|---|---|---|
WorldName.db | World objects, terrain modifications, structures | 5-50 MB |
WorldName.fwl | World metadata, seed, generator version | ~1 KB |
| World Age | Players | Expected .db Size | Status |
|---|---|---|---|
| Fresh | Any | 1-3 MB | Normal |
| 50-100 hours | 2-4 | 5-15 MB | Normal |
| 200+ hours | 5-10 | 15-30 MB | Monitor |
| Any | Any | 40+ MB | Needs attention |
ls -lh ~/.config/unity3d/IronGate/Valheim/worlds_local/
On Windows:
dir "%USERPROFILE%\AppData\LocalLow\IronGate\Valheim\worlds_local\"
Terrain Modification Impact on Performance
Every pickaxe swing, hoe use, or cultivator action creates a terrain modification entry. These stack up and are one of the biggest performance drains in mature worlds.
Reducing terrain modification impact:
Build Complexity and Its Effect on Server Load
Every placed building piece is a tracked entity. The server must process stability, weather damage, and rendering for each piece.
Building performance guidelines:
| Build Size | Piece Count | Performance Impact |
|---|---|---|
| Small house | Under 200 | Minimal |
| Medium base | 200-500 | Low |
| Large base | 500-1500 | Moderate |
| Mega build | 1500-5000 | High |
| Extreme build | 5000+ | Severe -- expect lag in the area |
- >Consolidate multiple small bases into fewer larger ones
- >Remove unused or abandoned structures
- >Avoid excessively tall or complex roofing systems
- >Use iron beams for structural support instead of stacking wood
Instance Count Management
Instances include creatures, dropped items, tamed animals, fireplaces, and smelters. Each one consumes server resources every tick.
Common instance sources to monitor:
- >Dropped items on the ground (despawn timer is 2 in-game days)
- >Tamed animals (each one is an active AI entity)
- >Active fires and torches (process fuel consumption each tick)
- >Portals (maintain network connections)
- >Beehives and fermenting barrels (process production cycles)
- >Pick up items instead of leaving drops on the ground
- >Limit tamed animal populations (10-15 per area maximum)
- >Destroy unused workbenches, fires, and crafting stations
- >Consolidate portals when possible
Step 3: Mod Performance Considerations
Mods add functionality but can significantly impact server performance if not managed carefully.
Valheim Plus Performance Settings
Valheim Plus includes settings that directly affect performance. Edit BepInEx/config/valheim_plus.cfg:
[Server]
; Enforce configuration sync -- keeps all clients consistent
enforceClientConfigSync = true
; Reduce data sent per tick if experiencing network issues
dataRate = 60
[Building]
; Disabling weather damage removes per-tick damage calculations
noWeatherDamage = true
[Game]
; Reduce item despawn time to clean up drops faster (seconds)
autoDestroyDroppedItems = 3600
BepInEx Mod Loader Optimization
BepInEx itself has configuration options that affect startup time and runtime performance. Edit BepInEx/config/BepInEx.cfg:
[Logging.Console]
; Disable console logging in production for better performance
Enabled = false
[Logging.Disk]
; Enable disk logging for debugging, disable for performance
Enabled = true
LogLevels = Fatal, Error, Warning
[Preloader.Entrypoint]
; Default assembly -- do not change unless you know what you are doing
Assembly = UnityEngine.CoreModule.dll
Type = Application
Method = .cctor
Identifying Problematic Mods
Not all mods are created equal. Some introduce per-tick overhead that compounds over time.
Warning signs of a problematic mod:
- >Server CPU usage jumps after installing the mod
- >Log file shows repeated warnings or errors from the mod
- >Players report lag that correlates with mod-specific activities
- >Memory usage climbs steadily over time (memory leak)
BepInEx/LogOutput.log# Check for errors in the BepInEx log
grep -i "error\|exception\|warning" BepInEx/LogOutput.log | tail -50
Server-Side vs Client-Side Mods
| Mod Type | Installed On | Server Impact | Examples |
|---|---|---|---|
| Server-side | Server only | Direct | Valheim Plus, server config mods |
| Client-side | Client only | None | UI mods, visual enhancements |
| Both | Server + Client | Direct | Most gameplay mods |
---
Step 4: Network Optimization
Network performance is critical for multiplayer Valheim. Poor network settings cause rubberbanding, desync, and phantom hits.
Bandwidth Requirements Per Player
| Players | Minimum Upload | Recommended Upload | Notes |
|---|---|---|---|
| 2-3 | 3 Mbps | 5 Mbps | Light builds |
| 4-6 | 5 Mbps | 10 Mbps | Moderate activity |
| 7-10 | 10 Mbps | 20 Mbps | Active combat/building |
Network Send/Receive Rates
Valheim uses a custom networking layer on top of Steam networking. You can adjust the server's network behavior through Valheim Plus or by modifying startup parameters.
Valheim Plus network settings:
[Server]
; Maximum data rate in KB/s per connection
dataRate = 60
; Maximum number of connections
maxPlayers = 10
; Reduce network send queue size for lower-bandwidth servers
sendRate = 150
Connection Quality Settings
Firewall rules for optimal connectivity:
Linux (UFW):
# Allow Valheim ports
sudo ufw allow 2456:2458/udp
# Verify rules
sudo ufw status numbered
Windows (PowerShell):
# Create firewall rules for Valheim
New-NetFirewallRule -DisplayName "Valheim Server" -Direction Inbound -Protocol UDP -LocalPort 2456-2458 -Action Allow
# Verify
Get-NetFirewallRule -DisplayName "Valheim Server" | Format-List
Port requirements:
| Port | Protocol | Purpose |
|---|---|---|
| 2456 | UDP | Game traffic |
| 2457 | UDP | Steam query |
| 2458 | UDP | Steam master server |
Step 5: Backup Strategies
World corruption can happen during crashes, power outages, or failed updates. A solid backup strategy protects hundreds of hours of progress.
World File Locations
| Platform | Path |
|---|---|
| Linux | ~/.config/unity3d/IronGate/Valheim/worlds_local/ |
| Windows | %USERPROFILE%\AppData\LocalLow\IronGate\Valheim\worlds_local\ |
| Docker | Mapped volume (e.g., ./data/worlds/) |
worlds_local/
├── WorldName.db # World data (critical)
├── WorldName.fwl # World metadata (critical)
├── WorldName.db.old # Previous save
├── WorldName.fwl.old # Previous metadata
adminlist.txt # Admin Steam IDs
bannedlist.txt # Banned players
permittedlist.txt # Whitelist
BepInEx/config/ # All mod configurations
Automated Backups -- Linux (Bash)
Create a backup script at /home/valheim/backup.sh:
#!/bin/bash
# Configuration
WORLD_DIR="$HOME/.config/unity3d/IronGate/Valheim/worlds_local"
BACKUP_DIR="$HOME/valheim-backups"
WORLD_NAME="Dedicated"
MAX_BACKUPS=14
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Create backup directory if it does not exist
mkdir -p "$BACKUP_DIR"
# Create compressed backup
tar -czf "$BACKUP_DIR/${WORLD_NAME}_${TIMESTAMP}.tar.gz" \
-C "$WORLD_DIR" \
"${WORLD_NAME}.db" \
"${WORLD_NAME}.fwl" \
2>/dev/null
if [ $? -eq 0 ]; then
echo "[$(date)] Backup created: ${WORLD_NAME}_${TIMESTAMP}.tar.gz"
else
echo "[$(date)] ERROR: Backup failed!"
exit 1
fi
# Remove old backups (keep last MAX_BACKUPS)
cd "$BACKUP_DIR"
ls -1t ${WORLD_NAME}_*.tar.gz 2>/dev/null | tail -n +$((MAX_BACKUPS + 1)) | xargs -r rm -f
echo "[$(date)] Backup rotation complete. $(ls -1 ${WORLD_NAME}_*.tar.gz | wc -l) backups retained."
Set up a cron job to run every 6 hours:
chmod +x /home/valheim/backup.sh
# Add to crontab
crontab -e
# Add this line:
0 */6 * * * /home/valheim/backup.sh >> /home/valheim/backup.log 2>&1
Automated Backups -- Windows (PowerShell)
Create C:\ValheimServer\backup.ps1:
# Configuration
$WorldDir = "$env:USERPROFILE\AppData\LocalLow\IronGate\Valheim\worlds_local"
$BackupDir = "C:\ValheimServer\backups"
$WorldName = "Dedicated"
$MaxBackups = 14
$Timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
# Create backup directory
New-Item -ItemType Directory -Force -Path $BackupDir | Out-Null
# Create compressed backup
$BackupFile = Join-Path $BackupDir "${WorldName}_${Timestamp}.zip"
$FilesToBackup = @(
(Join-Path $WorldDir "${WorldName}.db"),
(Join-Path $WorldDir "${WorldName}.fwl")
)
try {
Compress-Archive -Path $FilesToBackup -DestinationPath $BackupFile -Force
Write-Host "[$(Get-Date)] Backup created: $BackupFile"
} catch {
Write-Host "[$(Get-Date)] ERROR: Backup failed! $_"
exit 1
}
# Remove old backups
Get-ChildItem -Path $BackupDir -Filter "${WorldName}_*.zip" |
Sort-Object LastWriteTime -Descending |
Select-Object -Skip $MaxBackups |
Remove-Item -Force
$count = (Get-ChildItem -Path $BackupDir -Filter "${WorldName}_*.zip").Count
Write-Host "[$(Get-Date)] Backup rotation complete. $count backups retained."
Schedule with Task Scheduler:
# Run this in an elevated PowerShell prompt
$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-ExecutionPolicy Bypass -File C:\ValheimServer\backup.ps1"
$Trigger = New-ScheduledTaskTrigger -RepetitionInterval (New-TimeSpan -Hours 6) -At "00:00" -Once
Register-ScheduledTask -Action $Action -Trigger $Trigger -TaskName "Valheim Backup" -Description "Automated Valheim world backup" -User "SYSTEM"
Backup Rotation
A good backup rotation strategy balances storage space with recovery options:
| Backup Type | Frequency | Retention | Purpose |
|---|---|---|---|
| Frequent | Every 6 hours | 2 days (8 backups) | Recent recovery |
| Daily | Once per day | 7 days | Short-term rollback |
| Weekly | Once per week | 4 weeks | Long-term safety net |
Step 6: Monitoring Server Health
Proactive monitoring catches problems before players notice them.
Log File Analysis
Valheim server logs are your first line of defense. Key log locations:
| Platform | Log Path |
|---|---|
| Linux | ./output_log.txt in the server directory |
| Windows | valheim_server_Data/output_log.txt |
| BepInEx | BepInEx/LogOutput.log |
# Check for errors in the last 100 lines
tail -100 output_log.txt | grep -i "error\|exception\|failed"
# Monitor world save times (should be under 5 seconds)
grep "World saved" output_log.txt | tail -10
# Check for player connection issues
grep -i "disconnect\|timeout\|kicked" output_log.txt | tail -20
Performance Metrics to Watch
Monitor these system-level metrics alongside game logs:
# CPU usage of the Valheim process (Linux)
top -bn1 -p $(pgrep valheim_server) | tail -1
# Memory usage
ps -o pid,vsz,rss,comm -p $(pgrep valheim_server)
# Disk I/O (watch for high write activity during saves)
iostat -x 1 5
Healthy performance baselines:
| Metric | Healthy | Warning | Critical |
|---|---|---|---|
| CPU Usage | Under 50% | 50-75% | Over 75% |
| RAM Usage | Under 4 GB | 4-6 GB | Over 6 GB |
| World Save Time | Under 3s | 3-10s | Over 10s |
| Tick Time | Under 50ms | 50-100ms | Over 100ms |
Discord Webhooks for Server Alerts
Send automated alerts to your Discord server when issues are detected.
Create /home/valheim/discord_alert.sh:
#!/bin/bash
WEBHOOK_URL="https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_WEBHOOK_TOKEN"
send_alert() {
local message="$1"
local color="${2:-16711680}" # Default: red
curl -s -H "Content-Type: application/json" \
-X POST "$WEBHOOK_URL" \
-d "{
\"embeds\": [{
\"title\": \"Valheim Server Alert\",
\"description\": \"$message\",
\"color\": $color,
\"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"
}]
}"
}
# Check if server is running
if ! pgrep -x "valheim_server" > /dev/null; then
send_alert "Server is DOWN! Process not found." 16711680
exit 1
fi
# Check CPU usage
CPU_USAGE=$(top -bn1 -p $(pgrep valheim_server) | tail -1 | awk '{print $9}')
if (( $(echo "$CPU_USAGE > 80" | bc -l) )); then
send_alert "High CPU usage detected: ${CPU_USAGE}%" 16776960
fi
# Check memory usage (in MB)
MEM_USAGE=$(ps -o rss= -p $(pgrep valheim_server) | awk '{print int($1/1024)}')
if [ "$MEM_USAGE" -gt 6000 ]; then
send_alert "High memory usage: ${MEM_USAGE} MB" 16776960
fi
# Check for errors in recent logs
ERROR_COUNT=$(tail -100 /home/valheim/server/output_log.txt | grep -ci "error\|exception")
if [ "$ERROR_COUNT" -gt 5 ]; then
send_alert "Multiple errors detected in logs: $ERROR_COUNT errors in last 100 lines" 16711680
fi
Schedule the monitor to run every 5 minutes:
chmod +x /home/valheim/discord_alert.sh
crontab -e
# Add:
*/5 * * * * /home/valheim/discord_alert.sh >> /home/valheim/monitor.log 2>&1
---
Auto-Restart and Crash Recovery
Servers crash. The goal is to minimize downtime when they do.
Systemd Service Configuration (Linux)
Create /etc/systemd/system/valheim.service:
[Unit]
Description=Valheim Dedicated Server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=valheim
Group=valheim
WorkingDirectory=/home/valheim/server
Environment=SteamAppId=892970
Environment=LD_LIBRARY_PATH=/home/valheim/server/linux64
ExecStartPre=/home/valheim/backup.sh
ExecStart=/home/valheim/server/valheim_server.x86_64 -nographics -batchmode -name "My Server" -port 2456 -world "Dedicated" -password "YourPassword" -public 1 -saveinterval 1800 -backups 4
Restart=always
RestartSec=15
# Resource limits
LimitNOFILE=100000
Nice=-5
# Security hardening
ProtectHome=false
ProtectSystem=strict
ReadWritePaths=/home/valheim
[Install]
WantedBy=multi-user.target
Enable and manage the service:
sudo systemctl daemon-reload
sudo systemctl enable valheim
sudo systemctl start valheim
# Check status
sudo systemctl status valheim
# View live logs
sudo journalctl -u valheim -f
# Restart the server
sudo systemctl restart valheim
Windows Task Scheduler Setup
Create a recovery script at C:\ValheimServer\watchdog.ps1:
$ProcessName = "valheim_server"
$ServerPath = "C:\ValheimServer\start_server.bat"
$LogFile = "C:\ValheimServer\watchdog.log"
$process = Get-Process -Name $ProcessName -ErrorAction SilentlyContinue
if (-not $process) {
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Add-Content $LogFile "$timestamp - Server not running. Restarting..."
Start-Process -FilePath $ServerPath -WorkingDirectory "C:\ValheimServer"
Add-Content $LogFile "$timestamp - Server restart initiated."
} else {
# Optional: check memory usage
$memMB = [math]::Round($process.WorkingSet64 / 1MB, 0)
if ($memMB -gt 6000) {
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Add-Content $LogFile "$timestamp - WARNING: High memory usage: ${memMB} MB"
}
}
Register a scheduled task to run the watchdog every 2 minutes:
$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-ExecutionPolicy Bypass -File C:\ValheimServer\watchdog.ps1"
$Trigger = New-ScheduledTaskTrigger -RepetitionInterval (New-TimeSpan -Minutes 2) -At "00:00" -Once
Register-ScheduledTask -Action $Action -Trigger $Trigger -TaskName "Valheim Watchdog" -Description "Restarts Valheim server if it crashes" -User "SYSTEM"
---
Troubleshooting Performance Issues
High CPU Usage
Symptoms: Server process consistently above 70% CPU, players report lag.
Common causes and fixes:
# Identify CPU usage per core (Linux)
mpstat -P ALL 1 5
# Check Valheim-specific CPU time
pidstat -p $(pgrep valheim_server) 1 5
Memory Leaks
Symptoms: RAM usage increases steadily over hours or days without stabilizing.
Diagnosis:
# Monitor memory over time (log every 10 minutes)
while true; do
echo "$(date) - $(ps -o rss= -p $(pgrep valheim_server) | awk '{print int($1/1024)}') MB" >> /home/valheim/memory.log
sleep 600
done
Fixes:
Automated daily restart via cron:
# Restart at 4 AM daily
0 4 * * * sudo systemctl restart valheim
Desync Problems
Symptoms: Players see different world states, creatures appear in different positions for different players, building pieces desync.
Causes and solutions:
| Cause | Solution |
|---|---|
| High server tick time | Reduce world complexity, upgrade hardware |
| Network packet loss | Check server network path, use wired connection |
| Mod conflicts | Test with vanilla server to isolate |
| Client-server version mismatch | Ensure all players are on the same version |
World Loading Delays
Symptoms: Server takes a long time to start, new zones load slowly for players.
Fixes:
# Check disk I/O during world operations (Linux)
iotop -p $(pgrep valheim_server) -o
---
Quick Reference
Performance Checklist
- >[ ] Server runs on SSD/NVMe storage
- >[ ] CPU affinity is configured
- >[ ] Process priority is set to high
- >[ ] Save interval is set to 1800 seconds for large worlds
- >[ ] Automated backups run every 6 hours
- >[ ] Monitoring script checks server health every 5 minutes
- >[ ] Systemd service (or Task Scheduler) handles crash recovery
- >[ ] Terrain modifications are periodically cleaned
- >[ ] Dropped item cleanup is active
- >[ ] Mod count is minimal and all mods are up to date
- >[ ] Discord alerts are configured for server issues
- >[ ] Scheduled restarts prevent memory leaks
Useful Commands
# Check server status
sudo systemctl status valheim
# Live log monitoring
sudo journalctl -u valheim -f
# World file size
du -sh ~/.config/unity3d/IronGate/Valheim/worlds_local/*
# Force backup
/home/valheim/backup.sh
# Restart server
sudo systemctl restart valheim
---
Conclusion
Valheim server optimization is an ongoing process. Start with hardware and startup optimizations, then focus on world management as your server ages. Regular monitoring, automated backups, and crash recovery will keep your server running reliably.
The biggest performance gains usually come from managing world complexity -- terrain modifications and instance counts have far more impact than hardware upgrades. Keep your world clean, your mods updated, and your backups current.
For more information, visit the Valheim Wiki and the Valheim Discord.