Guides · Product
How to see which commands players actually use in your Minecraft plugin
Count which commands and subcommands of your Spigot or Paper plugin get used, by how many players, and which ones nobody touches, with or without a library.
Every plugin grows commands. A /arena becomes /arena join, /arena leave, /arena setup, /arena stats, /arena reload and a dozen more, each one documented, tested and kept working through every Minecraft update. A year later you have no idea which of them anyone uses.
That matters. The command nobody runs is still code you maintain, and the one everybody runs is where a small improvement helps the most people. This guide shows two ways to find out: counting it yourself, and letting a library do it.
What you want to know
A raw count is a start, but it can mislead. One admin who runs /arena reload fifty times while setting up a server makes it look like your most popular command. The useful questions are:
- How often each command and subcommand is used, per day.
- By how many players, so one busy admin doesn't outweigh a hundred players.
- On how many servers, to tell a feature most servers use from one a single network relies on.
- Over time, to see whether a new command catches on after a release.
Option 1: count it yourself
The simplest version is a counter in your command executor:
public final class ArenaCommand implements CommandExecutor {
private final Map<String, Integer> uses = new ConcurrentHashMap<>();
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
String sub = args.length > 0 ? args[0].toLowerCase(Locale.ROOT) : "";
uses.merge(sub.isEmpty() ? "arena" : "arena." + sub, 1, Integer::sum);
// ... the command itself
return true;
}
}
It works on your own server. The trouble starts when you want the numbers from every server running your plugin:
- You need somewhere to send them: a server of your own, storage, and a way to look at the result.
- Arguments aren't always subcommands.
/arena Notchor/arena 5would create a "subcommand" per player name or number. Only count the first argument when it's one of your known subcommands. - Unique players need care. Counting distinct players means keeping a set of UUIDs per command, and sending UUIDs off the server is something server owners rightly dislike. Hash them on the server with a salt that never leaves it.
- It must never cost the server anything. Sending happens off the main thread, in batches, with short timeouts, and a failure must never reach your command.
- Owners need an off switch, and your resource page should say what's collected.
None of this is hard, but it's a small analytics service, and every hour spent on it is an hour not spent on the plugin.
Option 2: let the SDK count them
PluginAnalytics counts commands without any code. On Spigot, Paper and Purpur, every command your plugin declares in plugin.yml becomes an event when it's used:
| Typed | Event |
|---|---|
/arena | command:arena |
/arena join skywars | command:arena.join |
/arena Notch | command:arena |
/ap join (an alias) | command:arena.join |
The first argument only counts as a subcommand when your command's own tab completion offers it, so join, leave and setup count while player names, numbers and free text never become event names. Commands run by a player count as player events; from the console or a command block, as server events.
Setup is the SDK in your jar (Gradle and Maven) and one line in onEnable:
@Override
public void onEnable() {
analytics = PluginAnalytics.start(this, "pa_your_key");
}
The Events page then lists every command with its count, the change against the previous period and its reach: the share of all your players who have ever used it. Open one to see it day by day and how many players used it for the first time each day. Reach and first times are part of the Pro and Premium plans; counts are on every plan.
Players are never identified. Each one is an anonymous hash that's different on every server, so you count people without knowing who they are.
Commands you register another way
Commands registered through Brigadier, a command framework or at runtime don't go through plugin.yml, so track them where they run:
analytics.track("command:arena.join", player);
The same applies on Folia, on Velocity and BungeeCord, and in Fabric or NeoForge mods: call track from your command handlers. See what each platform supports.
Beyond commands: what players do
Commands show what people ask your plugin to do. Events show what happens next. A few lines turn usage into answers:
analytics.track("game_started", player, "mode", arena.getMode().id());
analytics.track("game_finished", player, "mode", arena.getMode().id(), "result", won ? "win" : "loss");
With game_started and game_finished you see how many games start, which modes people pick, and how many players who start a game finish it. Chain them in a funnel and you see exactly where players give up.
Keep property values low-cardinality: a mode, a kit, a result. Never a player name or a world name an admin typed.
Reading the numbers
Once data comes in from a few servers, a few patterns are worth looking for:
- A command with a high count but low reach is used heavily by a few people, usually admins. It's important for setup, not for everyday play.
- A command with low reach everywhere is either unknown or unwanted. Before removing it, check whether it's in your help message and your resource page at all.
- A subcommand that grows after a release is the feature that release was really about. Mention it first in the next update post.
- A setup command that new servers never run (
/arena create,/shop setup) means owners install the plugin and stop. That's a gap in your first-run experience, not in the feature.
Respect the server owner
Whichever way you count:
- Say on your resource page that the plugin collects anonymous usage statistics, and how to turn them off.
- Never collect player names, UUIDs, IPs or chat. Counting commands needs none of them.
- Count in memory and send in the background, so a command never waits for analytics.
The SDK does all three for you. Server owners turn it off in plugins/PluginAnalytics/config.yml, and Privacy for server owners lists exactly what's sent.
More guides
How to see how many servers use your Minecraft plugin
Two ways to count the servers running your Spigot or Paper plugin, bStats and PluginAnalytics, why it differs from downloads, and its limits.
4 min readProductHow to handle bug reports for your Minecraft plugin
Where server owners should report plugin bugs, what every report needs, a ready template, and how to triage reports without drowning in them.
3 min read