Minecraft Server Tick-Skipping & Lag-Spike-Diagnose: Ursachen schnell finden und beheben
# Minecraft Server Tick-Skipping & Lag-Spike-Diagnose: Ursachen schnell finden und beheben
Dein Server läuft stundenlang mit stabilen 20 TPS — dann fällt er plötzlich für fünf Sekunden auf 8 TPS, Spieler rubberbanden, Entities frieren ein, und danach läuft alles wieder normal. Klingt bekannt?
Das sind Lag-Spikes, und sie gehören zu den frustrierendsten Performance-Problemen überhaupt. Im Gegensatz zu dauerhaft niedrigem TPS (der meist eine offensichtliche Ursache hat) sind Lag-Spikes unregelmäßig, schwer reproduzierbar und leicht fehlzudiagnostizieren. Dieser Guide gibt dir eine systematische Methode, die echte Ursache schnell zu finden.
---
Was ist Tick-Skipping?
Minecrafts Server-Loop läuft einmal alle 50 Millisekunden (20 Ticks pro Sekunde). Wenn ein einzelner Tick länger als 50ms dauert, gerät der Server in Rückstand. Bei starker Überschreitung erscheint folgende Log-Meldung:
Can't keep up! Is the server overloaded? Running 200ms or 2 ticks behind
Das ist Tick-Skipping — der Server überspringt nichts, er braucht einfach zu lange für einzelne Ticks. Das Resultat: wahrgenommener Lag, stockende Bewegung, verzögerte Interaktionen und kurz eingefrorene Mob-KI.
---
Schritt 1: Spike-Typ bestimmen
Bevor du etwas reparierst, kategorisiere deinen Spike:
| Spike-Typ | Dauer | Wahrscheinliche Ursache |
|---|---|---|
| Kurzer Spike | < 200ms | Chunk-Load, GC-Pause, plötzlicher Entity-Burst |
| Mittlerer Spike | 200ms–2s | Plugin-Tick, World-Save, schwere Redstone-Last |
| Langer Spike | 2s–10s+ | Disk-I/O-Stall, Speicherdruck, Terrain-Generierung |
| Periodischer Spike | Alle X Minuten | Geplante Tasks, Auto-Save, Plugin-Timer |
Wenn deine Spikes in regelmäßigen Abständen auftreten, überprüfe zuerst die Auto-Save-Einstellung:
bukkit.yml
ticks-per:
autosave: 6000
Der Standardwert ist 6000 Ticks (5 Minuten). Auf Servern mit großen Welten kann das Erhöhen auf 12000 oder 18000 zusammen mit einem Async-Save-Plugin periodische Spikes vollständig eliminieren.
---
Schritt 2: Spark zur Spike-Erfassung nutzen
[Spark](https://spark.lucko.me/) ist der Goldstandard für Minecraft-Profiling. Installiere es als Plugin und nutze den Sampler-Modus, um zu erfassen, was während eines Spikes passiert:
/spark sampler --timeout 120
Das startet einen 2-Minuten-Profiler. Löse den Spike aus (oder warte darauf), dann öffne den Report. Achte auf:
- Methoden, die > 10% der Tick-Zeit verbrauchen und nicht zu Vanilla-Minecraft gehören
- Plugin-Namen, die oben im Call-Stack erscheinen
CraftScheduler-Einträge, die auf Async-Tasks hinweisen, die in den Main-Thread einbluten
Für Spike-only-Profiling nutze die Health-Monitoring-Funktion:
/spark healthreport
Das liefert einen Snapshot von GC-Aktivität, CPU-Last und TPS-Verlauf — unschätzbare Kontextinformationen beim nachträglichen Analysieren eines Spikes.
---
Schritt 3: Chunk-bezogene Spikes isolieren
Chunk-Loading ist eine der häufigsten Spike-Quellen. Wenn ein Spieler in einen ungeladenen Bereich läuft, muss der Server:
- Den Chunk von der Festplatte lesen
- NBT-Daten deserialisieren
- Alle Entities und Block-Entities im Chunk ticken
- Chunk-Pakete an nahegelegene Spieler senden
All das kann den Main-Thread blockieren. In paper-world.yml diese Einstellungen optimieren:
chunks:
max-auto-save-chunks-per-tick: 8
prevent-moving-into-unloaded-chunks: true
entity-per-chunk-save-limit:
experience_orb: 16
snowball: 8
arrow: 16
Stelle sicher, dass du Async Chunk Loading verwendest, das Paper standardmäßig aktiviert. Wer noch Spigot ohne Paper nutzt, sollte eine Migration ernsthaft in Betracht ziehen — dieses eine Feature eliminiert eine ganze Kategorie von Chunk-Load-Spikes.
---
Schritt 4: Plugin-Scheduler-Missbrauch prüfen
Viele Plugins registrieren Wiederholungs-Tasks, die unnötigerweise jeden oder jeden paar Ticks laufen. Öffne deinen Spark-Report und schau in den CraftScheduler-Abschnitt. Wenn ein Plugin schwere Logik synchron jeden Tick ausführt, ist das dort klar erkennbar.
Alternativ nutze den /timings-Befehl (eingebaut in Paper/Spigot):
/timings reset
/timings report
Warte einen Spike ab, dann erstelle den Report. Achte auf Worst-case-Tick-Einträge — sie zeigen die maximale Zeit eines Abschnitts in einem einzelnen Tick, nicht den Durchschnitt.
Häufige Übeltäter:
- Economy-Plugins, die jedes Tick Kontostände neu berechnen
- Schutz-Plugins, die bei jedem Block-Update Regionen prüfen
- Custom-NPC-Plugins, die Pathfinding zu häufig ausführen
---
Schritt 5: GC-induzierte Spikes diagnostizieren
Javas Garbage Collector kann alle Threads pausieren, einschließlich des Server-Main-Threads. Diese Stop-the-World-Pausen erscheinen als saubere, harte Spikes ohne offensichtliche In-Game-Ursache.
Um zu prüfen, ob GC verantwortlich ist, füge diesen JVM-Flag zum Startskript hinzu:
-Xlog:gc*:file=gc.log:time,uptime:filecount=5,filesize=10m
Öffne dann gc.log nach einem Spike und suche nach Pause Full-Events länger als 100ms. Wenn du welche findest, muss dein GC-Tuning überarbeitet werden — stelle insbesondere sicher, dass du Aikars Flags oder G1GC mit korrekter Region-Größe verwendest.
Wer [PulseNode](https://pulsenode.tech) zur Server-Überwachung einsetzt, kann TPS-Einbrüche direkt mit Speicherauslastungs-Graphen korrelieren — das macht es deutlich einfacher, GC-Spikes von Plugin-Spikes zu unterscheiden, ohne manuell durch Logs zu wühlen.
---
Schritt 6: World-Save-Stalls
Selbst mit aktiviertem Async-Saving können Stalls auftreten, wenn die Save-Queue zu groß wird. In paper-world.yml:
chunks:
max-auto-save-chunks-per-tick: 8
Diesen Wert zu verringern verteilt die Save-Last über mehr Ticks. Alternativ kannst du ein Plugin wie ChunkSaver einsetzen oder in server.properties prüfen:
level-type=minecraft:normal
Stelle sicher, dass du keine Custom-Terrain-Generatoren verwendest, die den Save-Thread blockieren — einige ältere Generatoren sind nicht Async-sicher.
---
Schritt 7: Entity & NBT-Load-Spikes
Wenn ein Chunk geladen wird, der Tausende von Items in einer Truhe (oder Tausende von Entities) enthält, kann das Deserialisieren aller NBT-Daten den Server für Hunderte von Millisekunden blockieren.
In paper-world.yml Per-Chunk-Entity-Limits setzen:
entity-per-chunk-save-limit:
item: 32
experience_orb: 16
arrow: 16
fireball: 8
Für Item-Frames, Gemälde und Rüstungsständer sinnvolle Per-Chunk-Limits in spigot.yml setzen:
world-settings:
default:
item-despawn-rate: 6000
merge-radius:
item: 2.5
exp: 3.0
---
Schritt 8: Ein Spike-Log aufbauen
Sobald du Kandidaten-Ursachen identifiziert hast, führe ein strukturiertes Log:
- Zeitstempel des Spikes
- Dauer in ms
- TPS vor und nach dem Spike
- Spieleranzahl zum Zeitpunkt
- Aktuelle Aktivität (neues Gebiet erkundet, Item-Farm aktiv, etc.)
Nach 10–20 Einträgen werden Muster sichtbar. Spikes, die immer auftreten wenn die Spieleranzahl 30 überschreitet, haben eine andere Ursache als Spikes, die immer exakt um Mitternacht auftreten.
---
Zusammenfassung: Spike-Diagnose-Checkliste
- [ ]
bukkit.ymlAutosave-Intervall prüfen - [ ] Mit
/spark samplerwährend eines Spikes profilen - [ ]
/timings reportauf Worst-case-Tick-Zeiten prüfen - [ ] GC-Logging aktivieren und Stop-the-World-Pausen prüfen
- [ ]
paper-world.ymlChunk-Save-Limits optimieren - [ ] Entity-per-Chunk-Save-Limits gegen NBT-Bloat setzen
- [ ] Plugin-Scheduler-Tasks auf synchronen Missbrauch prüfen
---
Lag-Spikes manuell zu diagnostizieren kostet Zeit — aber der systematische Ansatz oben bringt dich deutlich schneller zur echten Ursache als blindes Raten. Wer einen kontinuierlichen Überblick über TPS, Speicher und CPU haben möchte, ohne manuell Profiler starten zu müssen, findet in [PulseNode](https://pulsenode.tech) ein Echtzeit-Monitoring-Dashboard, das Spike-Muster auf einen Blick sichtbar macht.