A developer discovered that a hidden npx lookup was adding roughly 10 seconds to every Claude Code turn, and swapping the lookup for a global install shaved six seconds off each interaction.
Why the latency mattered
Claude Code navigates a monorepo with dozens of components, indexes symbols, persists transcripts in Postgres, and fires error reports. The workflow feels smooth until the model’s responses start lagging. A health check then exposed several inefficiencies and one costly network call.
What the health check uncovered
- Duplicate installations – a native launcher and an outdated npm-global version co-existed. Removing the stale copy eliminated a needless path lookup.
- Broken agent file – a file without a description duplicated a valid file’s name, causing Claude Code to ignore it. Deleting the broken entry cleared the confusion.
- Unused extensions – a plugin and an MCP server that never fired were disabled, trimming the runtime footprint.
- Bloated “CLAUDE.md” files – these files repeated information already present in the code (e.g., build commands), inflating the payload sent to the model. Cutting them down left only essential context.
These clean-ups helped, but the biggest win came from the Stop hook that runs after every model response.
The hidden npx tax
The Stop hook executes six separate commands, each prefixed with npx -y. The -y flag forces npx to check the npm registry for a newer version before running the command, triggering a network request. Each lookup averaged 1.6 seconds, so the six calls added about 10 seconds to every turn. In practice the hook’s overall latency measured 12 seconds, with occasional spikes up to 113 seconds when the network hiccuped.
The simple fix
Replacing the npx calls with a globally installed binary removed the registry lookup:
- Before:
npx -y @invariance/gps→ 1.6 s per call - After:
gps(installed globally) → 0.7 s per call
The change cut the Stop hook’s runtime by roughly 6 seconds per turn and eliminated the massive spikes caused by the remote check.
What to watch next
- Hook timing – instrument any custom hooks to surface latency before it hurts users.
- Dependency hygiene – regularly prune duplicate installs and unused extensions.
- Configuration files – keep “CLAUDE.md” lean; only surface information the model cannot infer.
The lesson is simple: automation can hide costly plumbing. A quick health check can reveal hidden network calls that turn a smooth AI assistant into a sluggish one.
Takeaway: When Claude Code feels slow, time the hooks and eliminate any npx lookups; a global install can cut seconds off every turn and keep your development flow humming.
