Published: 2025-10-20
Author: MidSpike (Developer)
Hello everyone! This dev blog has been sitting on my back-burner for a quite a while now, so some aspects might not quite line up with the experience that our Towny server provides today. Better late than never as the saying goes, now we can properly get started!
Minecraft servers are designed to run at 20 ticks per second (TPS), a rhythm as fundamental to gameplay as gravity. Every tick is a heartbeat of logic and updates: player movement, blocks updates, mob path finding, redstone pulses, and much more. But when TPS drops, so does the delicate lag-free experience. This blog will explore the internals of ticking, why gamemodes struggle during intense workloads, and what we’ve been doing about it.
A tick is a unit of time in Minecraft's server loop. Every 1/20th of a second, the server performs a wide range of tasks:
Take for example, our gamemode Towny; which manages massive regions, several thousands of chunks and entities, and a dense set of plugins and systems, each tick has a lot to juggle. When it can’t finish within around 50ms (1/20th of a second), the most amount of time a tick can take before falling behind; Towny will start to lag as TPS drops below 20 ticks per second.
In debugging Towny's tick issues, the first step was simple: watch what code was doing what and when. Using profilers and timing reports, we tracked how much time each subroutine consumed per tick, not just plugins, but internal server mechanics and player activity as well. What we found was honestly no surprise, but was still staggering:
Observations revealed a core truth: even 'lightweight' systems compound into heavy ones at this scale. Plugins that seem passive, like the pets plugin, often perform hundreds or thousands of checks per second, which is mind boggling! Profiling helped us identify not only the worst offenders, but also surprising hotspots: small code paths doing unexpected amounts of work under the radar. It's not always the biggest plugin causing lag; sometimes, it's a tiny lambda firing too often. This visibility is the foundation for everything that comes next. Before we can work on improving the TPS, we need to learn what is ticking hardest.
Many blocks in Minecraft react to their environment: redstone, crops, doors, pistons, observers; they all observe changes and can trigger updates. Now consider:
Towns in our Towny gamemode often use contraptions for item transportation and sorting infrastructure. These machines create block update storms, where one block change cascades into hundreds (or even thousands) of recalculations for neighboring blocks; all in a single tick!
Block updates don't stop at the source. A redstone signal can trigger a piston, which updates blocks around it, which might power other redstone, which might activate even more redstone, and so on. Propagation is exponential if unchecked. Think about how a layer of floating sand can cascade into a lot of falling blocks very quickly. That principle applies to all forms of block updates, even the ones you can't see!
Towny is home to many innovative and clever players who create feedback loops: powered rails resetting, water streams updating farmland, item sorters, or other various complex redstone machines pulsing repeatedly. While all valid gameplay, it pushes the limits of Towny's tick engine every day!
The solution is simple! Or is it?
A natural reaction to lag is "upgrade the hardware". And we have, many times; most recently on October 11th, 2025. The absolute unit of a machine powering Towny has some of the best single-core and multi-core performance available. But Minecraft (and Java) aren't miraculously scalable. After a certain point, more CPU or RAM simply just doesn’t help. The tick loop remains mostly single-threaded with many workloads already optimized and made asynchronous by our wonderful development team.
Lag on Towny isn’t caused by weak hardware, although that certainly can sometimes be a factor. It’s caused by the workload; and better hardware doesn't miraculously solve the fundamental problem: cramming too much computation into a 50ms window. The CPU caches then become very overworked.
CPUs are fast, but rely heavily on keeping data close. That means using small but ultra-fast caches to avoid waiting on main memory. The problem? Minecraft, Towny, and plugins that we use like CoreProtect, mcMMO, Towny, and others operate on huge, frequently changing datasets. Those datasets include: world data, player data, logs, mob path finding, inventories, and more! All of it competes for low-level ultra-fast cache; of which there is not much to go around. But further to that, its not just the size of the cache that matters, its how fast and how much data you can shove through it. Towny is no stranger to shoving too much data through at once!
When data doesn’t fit in the CPU cache, it falls back to slower memory access. That adds additional latency that, in aggregate, eats into the tick time. And the more players online, the more data there is that needs to be shuffled every tick: chunk loading, block state updates, metadata access, and network packet queuing. These are raw throughput limitations. The system isn’t just doing complex tasks, it’s doing thousands to millions of them per tick, across a constantly shifting state. Even the best silicon (at our disposal) can't brute force that. The solution just simply isn’t to acquire 'better' hardware. It’s about making the workload smarter, and that’s what the next section is about.
What we’re dealing with is a software vs hardware problem; and software is putting up a good fight against hardware. The hardware is already way beyond being considered 'UFO' status, but the server’s performance and bottlenecks come from how much data has to be processed in a short amount of time. Minecraft simply wasn’t designed to handle the scale and complexity that our Towny gamemode frequently faces.
Put simply. Towny isn't even able to run using a standard Paper server anymore; it would lag too much or even crash, even under nominal conditions. We’re maintaining a heavily customized fork of Paper (and forks of plugins we use) that include deep, low-level optimizations specifically targeted at Towny’s unique workloads. These optimizations include improved chunk management, reduced tile entity overhead, asynchronous handling where safe, and tailored profiling tools to identify hidden bottlenecks. Without these modifications, the sheer volume of data Towny processes every tick would overwhelm the server’s main thread, regardless of hardware.
Each additional plugin adds significant load. Every new feature adds logic that must run, and that logic often scales with things like player count, loaded chunks, and active blocks. Take for example the plugin which handles Towny's Jobs (/jobs). I (MidSpike) introduced a patch for that plugin which aimed to reduce the computation time for AbstractFurnaceBlockEntity.burn() by a hypothesized 33%. It turns out that later measurements after pushing the patch out for Towny showed a 10.5x reduction in computation time for AbstractFurnaceBlockEntity.burn(), suffice to say, far exceeded expectations. Optimizations can come from all kinds of places, including the most unexpected of all: players.
Players build in ways that continue to impress our team, creating complex interactions, and sometimes (unfortunately) pushing the server’s mechanics to their limits. But, we've been able to measure massive notable performance improvements when players choose to optimize their redstone contraptions and/or mob grinders. We truly appreciate the time players spend on considering how their builds could be optimized.
Back over to what we'll be doing:
We certainly don't want to restrict creativity, and actively attempt to avoid doing so as much as possible; our focus remains on server stability and player enjoyment, even during peak activity and heavy workloads. Performance is a shared effort between software and gameplay design, and we know that finding solutions synergizing server stability and player enjoyment is paramount to long-term success and viability for MineSuperior.
Server performance wont magically remedy itself when computations get rough, but at least we know where and how to find what makes things tick (pun intended). And more importantly, we’re working to become more transparent with you, the community. Without you, MineSuperior would not be possible. If you love MineSuperior and want to see your gamemode thrive, please consider supporting our efforts to promote fun and lag-free experiences. Make an effort to disable redstone contraptions when not in use, avoid unnecessary chunk loading, and consider how machines can be optimized to reduce block updates.
Putting down my digital pen until next time.
I can't wait to see what adventure comes next!
MidSpike,
Developer