How to Optimize Lag and Latency on MU Online Server
Advanced guide to eliminate lag and reduce latency on MU Online servers: SQL, network, GameServer and OS configured step by step.
Lag and high latency are the top complaints on MU Online private servers and almost always originate from three points: a poorly tuned SQL Server database, incorrect settings in the server processes (GameServer, ConnectServer), and undersized network or VPS resources. This guide covers each layer with concrete commands and values.
1. Initial Diagnosis — Identify the Source of Lag
Before changing any file, measure where time is being lost.
1.1 Check slow queries on SQL Server
Open SQL Server Management Studio (SSMS) and run:
-- Currently running queries with high CPU consumption
SELECT
r.session_id,
r.status,
r.cpu_time,
r.total_elapsed_time,
r.logical_reads,
SUBSTRING(st.text, (r.statement_start_offset/2)+1,
((CASE r.statement_end_offset WHEN -1 THEN DATALENGTH(st.text)
ELSE r.statement_end_offset END - r.statement_start_offset)/2)+1) AS statement_text
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) st
WHERE r.status = 'running'
ORDER BY r.cpu_time DESC;
If cpu_time or total_elapsed_time exceeds 3000 ms on routine MU queries, the database is the bottleneck.
1.2 Check CPU and RAM usage for GameServer
In Task Manager → Details tab, sort by CPU. The GameServer.exe process should not exceed 70% CPU under normal conditions. RAM above 80% of total available also causes swap and severe lag.
perfmon.exe → add the Processor\% Processor Time and Memory\Available MBytes counters for continuous monitoring.2. Optimize SQL Server
2.1 Disable AutoShrink and AutoClose
These features trigger unnecessary I/O operations during gameplay:
USE master;
GO
-- Disable for the MuOnline database
ALTER DATABASE MuOnline SET AUTO_SHRINK OFF;
ALTER DATABASE MuOnline SET AUTO_CLOSE OFF;
ALTER DATABASE MuOnline SET AUTO_CREATE_STATISTICS ON;
ALTER DATABASE MuOnline SET AUTO_UPDATE_STATISTICS ON;
GO
2.2 Configure SQL Server Maximum Memory
By default SQL Server consumes all available RAM, starving the GameServer. Limit its usage:
-- For a server with 8 GB total RAM: reserve 2 GB for OS + GameServer
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'max server memory (MB)', 4096; -- 4 GB for SQL
RECONFIGURE WITH OVERRIDE;
GO
| Total VPS RAM | Maximum for SQL Server |
|---|---|
| 4 GB | 2048 MB |
| 8 GB | 4096 MB |
| 16 GB | 10240 MB |
| 32 GB | 20480 MB |
2.3 Create Indexes on the Most-Queried Tables
MU Online constantly queries character and inventory tables. Missing indexes are a direct cause of lag during logins and map changes:
USE MuOnline;
GO
-- Index on the character table (queried by name and account)
IF NOT EXISTS (
SELECT * FROM sys.indexes
WHERE name = 'IX_Character_Name' AND object_id = OBJECT_ID('Character')
)
CREATE NONCLUSTERED INDEX IX_Character_Name
ON dbo.Character (Name ASC)
INCLUDE (AccountID, MapNumber, MapPosX, MapPosY, Level, Class);
-- Index on the inventory table
IF NOT EXISTS (
SELECT * FROM sys.indexes
WHERE name = 'IX_Inventory_AccountName' AND object_id = OBJECT_ID('Inventory')
)
CREATE NONCLUSTERED INDEX IX_Inventory_AccountName
ON dbo.Inventory (AccountID ASC)
INCLUDE (ItemStorage);
-- Index on the accounts table for fast authentication
IF NOT EXISTS (
SELECT * FROM sys.indexes
WHERE name = 'IX_MEMB_INFO_ID' AND object_id = OBJECT_ID('MEMB_INFO')
)
CREATE NONCLUSTERED INDEX IX_MEMB_INFO_ID
ON dbo.MEMB_INFO (memb__id ASC)
INCLUDE (memb__pwd, memb_name, bloc_code, ctl1_code);
GO
2.4 Transaction Log Cleanup
Bloated transaction logs consume I/O and cause slowdowns:
USE MuOnline;
GO
-- Check current file sizes
SELECT name, size/128.0 AS size_mb,
FILEPROPERTY(name, 'SpaceUsed')/128.0 AS used_mb
FROM sys.database_files;
-- Shrink only the log file (never the data file on an active server)
DBCC SHRINKFILE (MuOnline_log, 512); -- Reduces to 512 MB
GO
DBCC SHRINKDATABASE or SHRINKFILE on the data file (.mdf) while the server is in production. This fragments indexes and worsens performance. Only shrink the log file (.ldf) and only during a maintenance window.3. Adjust GameServer Settings
3.1 File GameServer/GameServer.ini
Locate the file at GameServer/GameServer.ini (or GameServer/Setup/GameServer.ini depending on your version) and adjust:
[GameServerInfo]
; Maximum simultaneous users — tune to available RAM
MaxUser=300
; Character save interval (milliseconds)
; Default 5000 is too frequent — increase to reduce queries
CharacterSaveInterval=15000
; Idle connection timeout (seconds)
ClientTimeout=60
; Maximum active monsters per map
MaxMonsterCount=2000
[NetworkInfo]
; Send buffer size per client (bytes)
SendBufferSize=65536
; Receive buffer size per client (bytes)
RecvBufferSize=32768
; Number of network threads
NetworkThreadCount=4
IGC_GameServerInfo.cfg, the parameter equivalent to MaxUser is called MaxUserCount. Check which file your version uses before editing.3.2 File ConnectServer/ConnectServer.ini
The ConnectServer controls the connection queue. Incorrect values cause mass disconnections during peak hours:
[ConnectServerInfo]
; Maximum clients waiting in the connection queue
MaxWaitUser=500
; Server list update interval (ms)
UpdateInterval=1000
; GameServer response timeout (ms)
GameServerTimeout=5000
[NetworkSetting]
Port=44405
MaxConnection=1000
3.3 Process Priority on Windows
Raise the GameServer process priority to ensure preferential CPU time:
REM Run as Administrator — add to your startup script
REM Launch GameServer with high priority
start /HIGH "" "C:\MuServer\GameServer\GameServer.exe"
REM Or, if the server is already running, use WMIC:
wmic process where name="GameServer.exe" CALL setpriority "high priority"
4. Optimize the Operating System (Windows Server)
4.1 Disable Unnecessary Services
Run in PowerShell as Administrator:
# Disable services that consume resources without benefit to the game server
$servicesToDisable = @(
"wuauserv", # Windows Update (schedule for off-peak hours)
"SysMain", # SuperFetch — causes unnecessary I/O on SSDs
"WSearch", # Windows Search
"Print Spooler" # Print spooler
)
foreach ($svc in $servicesToDisable) {
Set-Service -Name $svc -StartupType Disabled
Stop-Service -Name $svc -Force -ErrorAction SilentlyContinue
Write-Host "Disabled: $svc"
}
4.2 Set Power Plan to High Performance
# Activate the high performance power plan
powercfg /setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c
# Confirm active plan
powercfg /getactivescheme
4.3 Tune TCP/IP Network Parameters
# Increase TCP connection backlog
netsh int tcp set global autotuninglevel=normal
netsh int tcp set global chimney=disabled
netsh int tcp set global rss=enabled
netsh int tcp set global timestamps=disabled
# Reduce TIME_WAIT to free ports faster
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" `
-Name "TcpTimedWaitDelay" -Value 30 -Type DWord
# Increase the range of ephemeral ports available
netsh int ipv4 set dynamicport tcp start=10000 num=55000
5. Monitoring with an Automated Alert Script
Create the file C:\MuServer\Scripts\monitor_lag.bat for periodic checks:
@echo off
REM Lag monitor — run via Task Scheduler every 5 minutes
set LOG=C:\MuServer\Logs\monitor_%date:~10,4%%date:~4,2%%date:~7,2%.log
set THRESHOLD=80
REM Check CPU usage
for /f "tokens=2 delims==" %%i in ('wmic cpu get loadpercentage /value') do set CPU=%%i
if %CPU% GTR %THRESHOLD% (
echo [%time%] ALERT: CPU at %CPU%%% >> %LOG%
REM Add Discord webhook notification here if desired
)
REM Check available memory (in MB)
for /f "tokens=2 delims==" %%i in ('wmic OS get FreePhysicalMemory /value') do set MEM=%%i
set /a MEM_MB=%MEM%/1024
if %MEM_MB% LSS 512 (
echo [%time%] ALERT: Available memory only %MEM_MB% MB >> %LOG%
)
echo [%time%] CPU: %CPU%%% Free RAM: %MEM_MB% MB >> %LOG%
6. Weekly Database Maintenance
Run every Sunday in the early hours (schedule via SQL Server Agent):
USE MuOnline;
GO
-- 1. Reorganize indexes with 10%–30% fragmentation
ALTER INDEX ALL ON dbo.Character REORGANIZE;
ALTER INDEX ALL ON dbo.Inventory REORGANIZE;
-- 2. Rebuild indexes with fragmentation above 30%
ALTER INDEX ALL ON dbo.Character REBUILD WITH (ONLINE = OFF, FILLFACTOR = 80);
ALTER INDEX ALL ON dbo.Inventory REBUILD WITH (ONLINE = OFF, FILLFACTOR = 80);
-- 3. Update statistics
UPDATE STATISTICS dbo.Character WITH FULLSCAN;
UPDATE STATISTICS dbo.Inventory WITH FULLSCAN;
UPDATE STATISTICS dbo.MEMB_INFO WITH FULLSCAN;
-- 4. Clean up old game logs (adjust period as needed)
DELETE FROM dbo.GameLog WHERE LogDate < DATEADD(DAY, -30, GETDATE());
PRINT 'Maintenance completed at: ' + CONVERT(VARCHAR, GETDATE(), 120);
GO
REBUILD WITH (ONLINE = OFF) locks the table during the operation. Only run this with the game server shut down or during very low-traffic hours. For SQL Server 2014+ Enterprise Edition, you can use ONLINE = ON to avoid locking the table.Optimization Flow Summary
Follow this sequence when investigating lag:
- Measure → slow SQL queries, process CPU/RAM usage
- Database → disable AutoShrink, cap SQL memory, create indexes
- GameServer.ini → tune
MaxUser,CharacterSaveInterval, network buffers - OS → power plan, disable services, TCP parameters
- Monitor → alert script + continuous logging
- Maintenance → weekly index rebuild and log cleanup
With all these layers tuned, player-perceived latency typically drops from 200–500 ms down to 20–60 ms on properly sized servers.
Perguntas frequentes
What is the biggest cause of lag on MU Online servers?
In most cases it is a poorly configured SQL Server — slow queries, missing indexes, and AutoShrink enabled are the main culprits. Always check the database first before blaming the network.
What is the recommended MaxUser value for GameServer.ini?
For a VPS with 4 GB RAM, use MaxUser=300. With 8 GB RAM, use MaxUser=600. Never exceed the machine's actual capacity or the server will become unstable.
How do I know if lag is coming from the server or from the player's connection?
In SQL Server Management Studio run: SELECT TOP 20 * FROM sys.dm_exec_requests WHERE status = 'running' ORDER BY cpu_time DESC. If any queries exceed 5000 ms the problem is in the database. If not, the bottleneck is likely network or GameServer processing.
Does SQL Server AutoShrink really cause lag?
Yes. AutoShrink compacts the database in the background consuming I/O and CPU. Disable it with: ALTER DATABASE MuOnline SET AUTO_SHRINK OFF. Run manual shrink only during a scheduled maintenance window.