Skip to content
Guide

Claude Code skill usage counts: where they live

In ~/.claude.json, under a top-level key called skillUsage. Each skill you have invoked has an entry with usageCount, a lifetime total, and lastUsedAt, a Unix timestamp in milliseconds. Nothing in Claude Code displays it: the request to show these numbers in /skills is issue #51115, closed as not planned in May 2026. So the file is the interface, and jq is the reader.

The skillUsage key in ~/.claude.json

It sits alongside the other machine-level state Claude Code keeps for you — your MCP servers, your per-project entries, the startup counter. It is not in ~/.claude/ and it is not per project: one object, one entry per skill, for the whole machine.

"skillUsage": {
  "code-review":   { "usageCount": 105, "lastUsedAt": 1786975028876 },
  "security-review": { "usageCount": 48, "lastUsedAt": 1786487551098 },
  "vercel:nextjs": { "usageCount": 3,   "lastUsedAt": 1785770161303 }
}
Read straight out of ~/.claude.json.
usageCount
How many times the skill has been dispatched, ever. A lifetime total since you installed Claude Code: it never resets and it is never windowed to the last week or the last month.
lastUsedAt
When it last fired, as milliseconds since 1970. This is the field that tells you whether a large usageCount is current or archaeology.
the key itself
The skill name. A skill under a directory or a plugin is normally keyed qualified, like vercel:nextjs, but the same skill can also appear under its bare name — check both before calling a count zero.
jq -r '.skillUsage | to_entries
       | sort_by(-.value.usageCount)[]
       | "\(.value.usageCount)\t\(.key)"' ~/.claude.json

# lastUsedAt is in milliseconds, so divide before you format it:
date -r $((1786975028876 / 1000))
Every skill ranked, and one date made readable.

A skill you never used has no entry at all

There is no zero row. An entry is created the first time a skill is actually dispatched, which means the file can only ever tell you about skills that have run. Installing thirty skills and using four leaves twenty-six of them entirely absent, not sitting there at zero waiting to be noticed.

That is a feature once you know it: absence is the signal. The unused list is what you get by subtracting the keys from the folder.

comm -23 \
  <(ls ~/.claude/skills | sort) \
  <(jq -r '.skillUsage | keys[]' ~/.claude.json | sort)
Installed, never invoked.

It cuts the other way for plugins. pluginUsage, the neighbouring key, is seeded with a timestamp when a plugin is installed or re-enabled, so a plugin can carry a recent lastUsedAt and a usageCount of zero. For plugins, trust the count; for skills, trust both.

What the counters cover, and what they do not

Three keys in the same file carry counters, and between them they still leave most of your setup unmeasured.

skillUsage
Skills, personal and project and plugin-provided alike. Written on real dispatch only.
pluginUsage
Plugins, keyed "<name>@<marketplace>". Seeded on install and refreshed on re-enable, so a zero count with a fresh date means untouched.
toolUsage
Built-in tools — Bash, Grep, TodoWrite and the rest — with the same {usageCount, lastUsedAt} shape.

Nothing counts subagents in a way you can rank (agentLastUsed holds a bare timestamp, no total), nothing counts slash commands, and nothing counts individual MCP tools. Those exist only in the session transcripts under ~/.claude/projects, one .jsonl file per session, where an MCP call appears as mcp__<server>__<tool> and a slash invocation appears as a user line carrying <command-name>.

grep -ho '"name":"mcp__[^"]*"' ~/.claude/projects/*/*.jsonl \
  | sort | uniq -c | sort -rn
The half the counters miss.

The two sources have opposite weaknesses, which is why a serious answer reads both. The counters survive everything and remember no dates beyond the last one. The transcripts remember everything and survive nothing: clear old sessions, delete a project folder or move machine, and the evidence goes. Loadout reads both — the counters for the totals, the transcripts for the rest and for the timeline.

Questions

Where does Claude Code store skill usage counts?
In ~/.claude.json, under a top-level skillUsage object. Each key is a skill name and each value is { usageCount, lastUsedAt }. There is no per-project copy and nothing in ~/.claude/ duplicates it.
Is usageCount a lifetime total or a recent one?
Lifetime, since the install. It is never reset and never windowed, so it cannot tell you on its own whether a skill is still part of your week. Read lastUsedAt for that, dividing by 1000 first because it is in milliseconds.
Can I see skill usage counts inside Claude Code?
Not directly. Issue #51115 asked for them to be shown in /skills and was closed as not planned in May 2026. The /checkup command reads them as part of a wider cleanup, but it reports what it wants to act on rather than giving you the list to keep.

Loadout shows all of this in one list, with usage counts

A free Mac app that reads the same folders this guide describes: every skill, subagent, slash command, plugin and MCP server, and how often each one actually fires. Nothing leaves your machine.