Here is a lag pattern almost every server owner has seen. The world runs at a flawless 20 TPS while players are in their bases, then someone heads out to explore and the whole server stutters. Mobs freeze, blocks break late, everyone complains, and it clears up the moment that player stops moving.
That is not a hardware fault or a mod conflict. It is world generation happening on the live server thread. When a player walks into terrain that has never existed before, the server has to generate it right then, inside the tick, and that work is heavy enough to blow the 50 millisecond tick budget.
The fix is to do that work ahead of time, when no one is waiting on it. This guide explains why world generation is so expensive, and how to pre-generate your world in 1.21.4 Java Edition using Chunky, the standard tool for the job.
Why exploring causes lag
Every chunk in Minecraft is generated exactly once. The first time any player gets close enough to load a chunk that has never existed, the server runs the full world-generation pipeline for it: shaping the terrain, carving caves, placing ores, growing structures, and decorating the surface. That is a lot of computation per chunk.
In normal play near generated terrain, the server has almost nothing to generate, so ticks are cheap. The trouble starts when a player moves into the frontier. As they travel, the loaded-chunk window slides into ungenerated territory, and the server has to generate a steady stream of brand new chunks to keep up, on the same thread that runs the game tick.
The cost is front-loaded and permanent. A chunk is only generated once, ever. After that, loading it is just reading saved data off the disk, which is cheap. This is the whole reason pre-generation works: you pay the generation cost once, in advance, and from then on those chunks load fast for every player forever.
This is also why a brand new server feels laggier than an old one. On a mature world, most of the area players visit is already generated, so exploration rarely triggers generation. On a fresh world, every direction is frontier, and the server is constantly generating under load.
What Chunky does
Chunky is a pre-generation tool that loads and generates a region of your world in a controlled, background process before players ever reach it. Instead of generation happening reactively when a player stumbles into new terrain, Chunky walks the world outward from a center point and generates every chunk in a defined radius up front.
It is available both as a plugin for Paper and Spigot servers and as a Fabric mod, so it covers the common 1.21.4 server setups. It is throttled and resumable: it generates at a pace that leaves tick budget for any players already online, and if you stop it or restart the server, it picks up where it left off.
The result is a world with a generated buffer around spawn. Players can explore that buffer freely without triggering any generation at all, because the chunks already exist on disk. The lag only returns if and when they reach the unpregenerated edge.
Pre-generating step by step
Install Chunky first. On a Paper or Spigot server, drop the plugin jar into the plugins folder and restart. On Fabric, place the mod in mods alongside the Fabric API. Then run the commands from the server console or in-game as an operator.
Set the center of the generation area. Spawn is the usual choice:
/chunky center 0 0
Set how far out to generate, in blocks from the center:
/chunky radius 5000
Start the pass:
/chunky start
That configuration generates a circular area 5000 blocks in radius, a 10,000-block-diameter region centered on spawn. Chunky reports progress as it runs: chunks completed, percentage, current rate, and an estimated time remaining.
You do not have to take the server offline for this. Chunky deliberately throttles itself so it does not starve the tick. Players can be online while it runs, though you may see slightly lower TPS during the pass, which is exactly the cost you are moving off of normal play. For the smoothest result, run the bulk of generation during quiet hours.
Useful control commands while a pass is running:
/chunky pauseand/chunky continueto stop and resume without losing progress/chunky cancelto abandon the current task/chunky progressto print current status/chunky quietto reduce how often progress is logged
To also pre-generate other dimensions, switch worlds before configuring. The Nether deserves particular attention because of its coordinate compression, where every block of Nether travel covers eight blocks of Overworld:
/chunky world world_nether
/chunky radius 1000
/chunky start
A Nether radius of around 1000 blocks usually covers far more Overworld travel than the number suggests, which makes the Nether cheap to pre-generate relative to its usefulness.
Picking a sensible radius
The right radius is a trade between disk space and generation time on one side, and how much frontier-free room you give players on the other. Bigger is not automatically better, because both the time to generate and the storage on disk grow with the area, which scales as the square of the radius. Doubling the radius roughly quadruples the work and the space.
Some practical starting points:
- Small or private server: a radius of 2000 to 3000 blocks around spawn is plenty for a handful of players.
- Public survival server: 5000 blocks is a common, comfortable choice that gives wide roaming room.
- Large community server: 10,000 blocks or more, but expect this to take many hours and consume a meaningful amount of disk.
Storage adds up faster than people expect. A pre-generated Overworld can run into many gigabytes at large radii, and modded worlds with extra structures and dimensions grow faster still. Check your host's disk allowance before kicking off a 20,000-block pass, and remember the Nether and End add to the total.
A strong pairing is to pre-generate to a chosen radius and then set the world border at or just inside that radius. With a border in place, players physically cannot reach ungenerated terrain, so the exploration lag spike is not just reduced, it is eliminated for the lifetime of the world.
/worldborder center 0 0
/worldborder set 10000
That sets a 10,000-block-wide border centered on spawn, matching a 5000-block pre-generation radius.
How pre-generation fits with everything else
Pre-generation is not a substitute for the rest of your performance work, it is one specific tool for one specific cause of lag. It only addresses TPS spikes that come from generating new terrain. It does nothing for lag from too many entities, heavy redstone, or an oversized simulation distance, all of which are separate problems with separate fixes.
What it does is remove an entire category of lag from the table so your profiling is cleaner. Once the area players use is pre-generated, the remaining TPS drops are no longer noise from world generation, and a tool like Spark can point at the real bottleneck without exploration spikes muddying the data.
The ordering that works well on a new server: pre-generate the area you expect players to use, set a world border to match, then bring players in, then profile whatever TPS issues remain. Doing pre-generation first means every later measurement is taken on a stable world instead of one that lags differently depending on who is exploring.
It also pairs naturally with render distance. A high render distance over ungenerated terrain forces generation just to draw the view, which spikes both the client and the server. Over a pre-generated world, far render distances stay smooth because the chunks being drawn already exist and only need loading, not generating.
The bottom line
Exploring is one of the most expensive things a Minecraft server does, and it is expensive precisely because world generation runs on the live tick the moment a player reaches new ground. Chunky moves that work off the live thread and into a controlled background pass, so the cost is paid once, in advance, instead of repeatedly under load.
Pre-generate the area around spawn, set a world border to match it, and the frontier lag spike that plagues new servers simply stops happening. It is one of the highest-value, lowest-effort optimizations you can make on a fresh 1.21.4 world.
Sources & further reading:
- Chunky pre-generation tool: https://modrinth.com/plugin/chunky
- Spark profiler documentation: https://spark.lucko.me/docs
- Minecraft Wiki on chunk generation: https://minecraft.wiki/w/Chunk




