How to Profile Your Minecraft Server with Spark (Find What's Causing Lag)
Performance

How to Profile Your Minecraft Server with Spark (Find What's Causing Lag)

Stop guessing why your server lags. Spark shows you exactly which plugin, entity, or tick is eating CPU — a complete guide to profiling Paper, Purpur, Fabric, and Forge servers.

Swelis TeamMay 3, 202611 min read

You've allocated more RAM. You're using Paper. You've added Aikars flags to your startup script. And your server still stutters when more than ten players are online.

Here's the problem: you're guessing. RAM, Java flags, and server software are all valid levers — but pulling them randomly is like swapping car parts until the engine runs. You need diagnostics first. You need to see what's actually happening during each server tick.

That's what Spark does. It's a profiler: a tool that samples your server's CPU usage thousands of times per second and shows you exactly which code paths are taking the longest. Not "entities are causing lag" — you'll see net.minecraft.world.entity.ai.goal.RandomStrollGoal.canUse() taking 23% of your tick. That's a diagnosis you can act on.

This guide walks you through installing Spark, running a profile, reading the flame graph output, and translating what you find into fixes. By the end, you'll stop asking "is it plugins or entities?" and start knowing.


What Profiling Actually Measures

Before diving in, let's clear up what a profiler does and what it doesn't.

TPS vs MSPT

You've probably seen TPS — ticks per second. A Minecraft server runs 20 ticks per second when healthy. If it drops to 15, you're lagging.

But TPS tells you there's a problem, not what the problem is. MSPT — milliseconds per tick — is more useful. Each tick has a 50ms budget (1000ms / 20 ticks = 50ms). If your server averages 42ms, you're fine. If it spikes to 120ms, those ticks are taking more than twice as long as they should, and TPS drops to compensate.

Spark measures what's happening inside those milliseconds.

CPU Sampling

Spark doesn't slow your server down or log every method call. It uses sampling: many times per second, it asks "where is the server right now?" and records the answer. After running for a few minutes, it assembles these samples into a statistical picture of where time is being spent.

This means Spark is safe to run on a live server with players. The sampling overhead is negligible.

Why RAM Is Rarely the Bottleneck

New admins throw RAM at lag problems because it feels intuitive — more memory, more room for stuff, faster server. But Minecraft servers are single-threaded. The main game loop runs on one core, and that core is the bottleneck.

Adding RAM beyond what's actually used doesn't speed up a tick. It just means the garbage collector has more to scan. For most servers, 4–10 GB is plenty. The CPU doing the ticking is what matters — and that's what Spark profiles.

This is why hardware with high single-threaded performance matters more than core count. It's also why hosting providers that use CPUs with large L3 caches (like the Ryzen X3D series) make a measurable difference for Minecraft specifically — the main tick loop fits in cache, avoiding slower RAM access.

If you're curious about RAM sizing for your specific setup, see the RAM guide.


Installing Spark

Spark comes in different packages depending on your server software. The plugin and mod are functionally identical — it's just how they're loaded.

Paper / Purpur (Plugin)

  1. Download the latest Spark release from the Spark website (spark.lucko.me/download) — grab the Bukkit version.
  2. Drop the .jar file into your server's plugins/ folder.
  3. Restart the server.
  4. Confirm it's loaded: run /spark in the console or in-game. You should see the help menu.

Fabric (Mod)

  1. Make sure Fabric Loader is installed on your server.
  2. Download the Spark Fabric version for your Minecraft version.
  3. Place the .jar in the mods/ folder.
  4. Restart the server.
  5. Run /spark to verify.

Forge (Mod)

  1. Download the Spark Forge version matching your Minecraft version.
  2. Place it in the mods/ folder.
  3. Restart.
  4. Run /spark.

Permissions

By default, only operators can use Spark commands. If you're using LuckPerms or another permission plugin, grant the spark permission node to admins:

spark.*

Or, for finer control:

PermissionWhat It Allows
spark.profilerStart and stop CPU profiles
spark.tpsView TPS and MSPT stats
spark.healthView health reports
spark.gcView garbage collection stats

For a full permissions setup guide, see the LuckPerms guide.


Running Your First Profile

Spark has several commands, but the one you care about most is /spark profiler.

Starting a Profile

In-game or in the console, run:

/spark profiler start

Spark begins sampling immediately. Let it run while the lag is happening. If your server hitches at noon when players are active, run the profile then — not at 3 AM when the server is empty.

A good profile duration is 2–5 minutes. Long enough to capture representative data, short enough to not bloat the output.

Stopping and Viewing

When you're ready, run:

/spark profiler stop

Spark compiles the samples and uploads the result to its viewer. You'll see a message with a URL like:

https://spark.lucko.me/abcd1234

Click it. This opens the Spark viewer — an interactive flame graph showing where your server spent CPU time.

The --only-ticks-over Flag

If your lag comes in spikes rather than constant slowdown, use:

/spark profiler start --only-ticks-over 50

This tells Spark to only sample ticks that exceeded 50ms (the healthy budget). You'll see exactly what made those bad ticks slow, without the noise of normal ticks diluting the data.


Reading Flame Graphs

The Spark viewer shows a flame graph. If you've never seen one, it looks intimidating. It's actually straightforward once you know how to read it.

What the Structure Means

Each horizontal bar is a method (a function in the server's code). The width of the bar represents how much time that method took — wider bars mean more time.

Bars stack vertically: if method A calls method B, B appears on top of A. The bottom of the flame graph is the server tick loop. As you move up, you drill into the specific code paths within that loop.

Colors

In Spark's default coloring:

  • Green bars are Minecraft's own code (net.minecraft...).
  • Yellow/orange bars are plugins or mods.
  • Blue bars are Java library code or reflection.

If you see a wide yellow bar, that's a plugin or mod taking significant time. If you see a wide green bar, it's vanilla Minecraft — and you'll need to address it through config, not by removing a plugin.

Finding Hot Methods

Look for wide bars near the top of the graph. These are "hot" methods — the specific code taking the most time.

Click on a bar to zoom in. Spark shows you the percentage of total tick time that method consumed. If WorldServer.tick() is 100% (it always is — that's the main loop), but EntityGoalSelector.tick() under it is 40%, you now know that mob AI is eating 40% of your tick.

Thread Isolation

By default, Spark shows the main server thread. Use the dropdown in the viewer to switch threads. Most of your focus should be on the main thread — that's where the tick runs — but chunk loading and async tasks appear on other threads.


Common Culprits and What to Do

Once you've found the hot spots, here's what common ones mean and how to address them.

Chunk Generation

If you see time spent in ServerChunkCache or ChunkGenerator, your server is generating new terrain. This happens when players explore unloaded areas.

Fix: Pre-generate your world with Chunky before opening the server. See the Chunky guide. For Paper/Purpur, also ensure you're using the async chunk system (it's on by default in recent versions).

Entity AI

Methods like GoalSelector, PathfinderGoal, or Brain indicate mob AI calculations. With many mobs, this adds up.

Fix: Reduce mob caps in spigot.yml or paper-world-defaults.yml. Consider plugins like Mob Stacker that merge duplicate mobs. For a deeper dive, see the entity management guide.

Slow Plugins

If you see a plugin's namespace (e.g., com.exampleplugin.SomeClass) taking significant time, that plugin is the problem.

Fix options:

  1. Check for plugin updates — performance regressions are common in older versions.
  2. Audit plugin configs — some plugins have expensive features that can be disabled.
  3. Replace the plugin — find a lighter alternative or remove it.
  4. Contact the plugin author with your Spark profile link. Good developers will investigate.

Datapack Functions

If you're running datapacks with complex functions, you might see time in CommandFunction or CustomFunction.

Fix: Audit your datapacks. Remove or simplify ones that run every tick. The game rule maxCommandChainLength can limit runaway function loops, but the real fix is leaner datapacks.

Hopper and Redstone Tick

Hoppers and active redstone machines run calculations every tick. Large farms or sorting systems can become CPU sinks.

Fix:

  • In spigot.yml, increase hopper-transfer and hopper-check intervals to reduce hopper tick frequency.
  • Use water streams instead of hoppers where possible.
  • For redstone, encourage players to build clock-based systems with longer intervals.

Plugin Reflection Abuse

If you see deep stacks in java.lang.reflect, a plugin is using reflection heavily at runtime. This is slow.

Fix: Report it to the plugin author. There's not much you can do from the config side — the plugin needs a rewrite.


Memory Profiling with Spark

CPU isn't the only thing Spark can analyze. If you suspect memory issues — or the garbage collector shows up in your CPU profile — Spark has tools for that too.

Heap Dump

Run:

/spark heapdump

This creates a snapshot of everything in memory. Spark uploads it to a viewer where you can see which objects are consuming the most RAM. If a plugin is leaking memory (holding references to objects it no longer needs), the heap dump will show it.

GC Monitoring

Run:

/spark gc

This shows garbage collection statistics: how often the GC runs and how long each pause takes. Frequent long pauses mean your server is thrashing — either you're using too much memory, or your GC settings need tuning.

If GC pauses show up as a significant portion of your tick time in the CPU profile, see the lag guide's section on Java flags for GC tuning recommendations.


When to Profile

Knowing how to profile is only useful if you profile at the right time.

Profile during lag. If your server only lags at peak hours, profile at peak hours. A profile from 4 AM with two players online will show you nothing useful about why the server stutters at 8 PM with thirty.

Profile after changes. Added a new plugin? Run a profile before and after. If MSPT jumps by 10ms, you know exactly what caused it.

Profile before blaming hardware. If you're considering upgrading your hosting plan or switching providers, profile first. If your profile shows a single plugin taking 60% of your tick, no amount of CPU upgrade will make that plugin efficient.


Quick Reference

CommandWhat It Does
/spark profiler startBegin CPU sampling
/spark profiler stopEnd sampling and upload the profile
/spark profiler start --only-ticks-over 50Only sample ticks exceeding 50ms
/spark tpsShow current TPS and MSPT
/spark healthSummary of CPU, memory, and disk
/spark gcGarbage collection statistics
/spark heapdumpUpload a memory snapshot
TermMeaning
TPSTicks per second (target: 20)
MSPTMilliseconds per tick (target: under 50)
Flame graphVisual representation of where CPU time is spent
Hot methodA function taking disproportionate CPU time
SamplingPeriodically checking what code is running (low overhead)


Your server lag has a cause. It's not "just Minecraft being Minecraft." It's a specific method, in a specific plugin or in vanilla code, running too long during a specific phase of the tick loop.

Spark shows you where. Everything else — RAM, flags, view distance — is downstream of that diagnosis. Profile first, then fix. You'll stop guessing and start solving.

Ready to Start Your Adventure?

Join lots of users already enjoying lag-free hosting.

Launch Your Server
Swelis Hosting

Premium Minecraft server hosting starting at €1.50/GB RAM. Experience lightning-fast performance, 24/7 support, and 99.9% uptime guarantee.

© 2026 Swelis International e.U. All rights reserved.