Skip to Content
GuidesTrack command usage

How to track Discord bot command usage

Once a bot is in more than a handful of servers, “which commands do people actually use?” stops being a guess you can afford. Usage data tells you what to invest in, what to deprecate, and — when a command’s success rate quietly drops — that something broke before the bug reports arrive.

This guide covers what’s worth measuring, why the obvious approaches fall short, and how to get it in a few lines with Mochi.

What “command usage” actually means

A single counter per command name isn’t enough to act on. The metrics that change decisions are:

  • Use count — invocations over a window, so you can rank commands and spot trends.
  • Unique users — 10,000 calls from 50 people is a very different feature than 10,000 calls from 8,000 people.
  • Success rate — the share of invocations that finished without throwing. A dip here is your earliest signal of a regression.
  • Latency — p50 and p95 execution time, so a slow command doesn’t quietly degrade the experience.
  • Where — guild vs. DM, and which shard, when you’re debugging something regional or shard-specific.

Why the do-it-yourself version gets painful

The first instinct is a Map<string, number> incremented in your interaction handler. It works until it doesn’t:

  • It’s in memory, so a restart or a deploy resets everything.
  • It counts invocations, not outcomes — you can’t tell success from failure or measure duration without threading timing through every handler by hand.
  • “Unique users” means storing user ids, which turns your analytics into a pile of personal data you now have to secure and justify (see privacy-friendly analytics).
  • Putting it in a database means writing the schema, the aggregation queries, and eventually a dashboard — a project in its own right.

Capturing it with Mochi

Mochi records command usage as command events. The SDK wires this into your client, so an attached bot starts reporting immediately:

import { Client, GatewayIntentBits } from "discord.js"; import { MochiClient } from "@mochi-analytics/core"; import { attachMochi } from "@mochi-analytics/discordjs"; const mochi = new MochiClient({ url: "https://mochi.example.com", apiKey: process.env.MOCHI_API_KEY!, }); const client = new Client({ intents: [GatewayIntentBits.Guilds] }); attachMochi(client, mochi);

That alone records every slash and context-menu command. Auto-tracking fires when the interaction arrives, though, so it can’t see whether your handler succeeded or how long it took. For accurate success and latency, wrap the handler instead:

import { wrapHandler } from "@mochi-analytics/discordjs"; attachMochi(client, mochi, { autoTrackCommands: false }); const play = wrapHandler(mochi, async (interaction) => { // your command logic — duration and thrown errors are recorded automatically });

Not on discord.js? The same event shape works from any language over the raw Ingest API, and there are first-party SDKs for discord.py, discordgo, and more.

Reading it back

Command metrics show up on the dashboard ranked by use, each with success rate, unique users, and p50/p95 latency. To pull the same numbers into a /stats command or an external page, use the Stats API:

curl -H "Authorization: Bearer $MOCHI_API_KEY" \ "https://mochi.example.com/api/v1/stats/commands?range=7d"
{ "range": "7d", "commands": [ { "name": "play", "uses": 18402, "users": 5210, "successRate": 99.4, "p50": 88, "p95": 310 } ] }

Raw user ids never touch disk — Mochi hashes them server-side with a per-bot salt before counting uniques, so “unique users” stays accurate without you holding personal data.

Next steps

Last updated on