Dev.to AI πŸ€– Ai πŸ‘ 0 πŸ“– 4 min read

Where did my coding agent's 49 minutes go?

I asked my coding agent to merge a branch and clean up the worktree. It took 49 minutes. That's a long time for a merge, so I wanted to know where it went. Was the model slow? Were the edits hard? Was the agent stuck in

Where did my coding agent's 49 minutes go?

I asked my coding agent to merge a branch and clean up the worktree. It took 49 minutes.

That's a long time for a merge, so I wanted to know where it went. Was the model slow? Were the edits hard? Was the agent stuck in a loop? Neither Claude Code nor Codex could tell me. Both keep detailed logs on disk, but neither shows you a timeline of what actually took the time.

So I built one. 47 of those 49 minutes were a single full test-suite run. Not the model, not the edits: one command.

The merge prompt in session-profiler: one hatched background job spans almost the whole 49-minute timeline, and the ranking shows

The screenshots use a demo session built to match my real numbers, so no private prompts or paths are visible.

What it shows

session-profiler reads the session logs that Claude Code and Codex already keep on your machine and opens a local report:

  • One lane per agent. The main session, its subagents and the side sessions it started sit on one shared timeline, so you can see what ran in parallel and what blocked what.
  • Every tool call and background job as a bar you can hover or click for the exact command.
  • The time split into three parts that add up: the agent working, only background jobs running, and nothing running (usually: waiting for you).
  • The slowest steps, ranked. This is where the one command eating the session jumps out.

The whole session: summary figures, then a timeline with one lane per agent including subagents and a side session

You don't run it yourself. It installs as a plugin and skill for both tools, and you ask your agent to "profile this session". It runs the helper, opens the report and tells you what took the time.

The pattern I keep seeing

After the merge surprise, I measured the last 150 of my own Claude Code sessions. For each prompt, I looked at how much of its time went to its single longest step. The same shape kept coming back:

  • 47 of 49 minutes: one full test-suite run after a merge (96%).
  • 33 of 35 minutes: one background job capturing mobile screenshots.
  • 23 of 31 minutes: one "run the full check suite" command.
  • Nearly 8 of 10 minutes: one foreground "run the full checks" call.

In each case, the work I thought of as "the task" took a minute or two. One command took the rest, usually a test suite or a build the agent kicked off and then waited on.

That changed how I work with agents more than any prompt tweak:

  • I ask for the relevant subset of tests while iterating, and the full suite only once at the end.
  • When a full run is unavoidable, I give the agent something else to do while it runs, instead of letting it wait.
  • I check what's still running in the background before assuming the agent is "thinking".

What was harder than it looked

Reading the logs is the easy part. Getting honest numbers out of them took most of the work.

A turn isn't the same as work. A turn runs from your prompt until your next one, so the obvious measure counts everything: the agent waiting for you to answer a question, or sitting idle until a side session reports back. The profiler treats messages the app injects (a side session finishing, a message from another session) as wake-ups, so the gap before them shows up as a wait, not as the agent working.

Background jobs end later than their calls. When an agent starts a command in the background, its tool call returns at once. The real end is a separate completion notice that arrives later. The tricky case is a job the app kills days later when it cleans up: one of mine showed up as a 75-hour job. Now the notice's wording decides. "Stopped by the user" or "reached its time limit" is a real end. "Didn't finish before the session ended", or a kill with no reason long after the session went quiet, gives an unknown end instead of a made-up one.

Codex logs only start-up time for many commands. In my Codex history, about 64% of commands are recorded as taking under a millisecond, because the log captures only how long they took to start. Showing them as "0 ms" would hide where the time went. When a command is the only thing its exec script ran, the profiler times it by that script call; when it shares the script with other calls, its duration is shown as unknown.

Side sessions aren't linked in the transcripts. When the Claude desktop app starts a side session, nothing in either transcript says which session started which. The link exists only in the app's own session records, so the profiler reads those to nest side sessions under their parent, and falls back to showing them separately if the records change.

Try it

In Claude Code:

/plugin marketplace add draconnn/session-profiler
/plugin install session-profiler@session-profiler

In Codex:

codex plugin marketplace add draconnn/session-profiler
codex plugin add session-profiler@session-profiler

Then ask your agent to "profile this session".

It's read-only: it never changes your logs. The report is served on 127.0.0.1 and nothing is uploaded. It needs only Python 3.11+, with no other dependencies, and runs on macOS and Linux. It's MIT licensed.

One caveat: the log formats it reads aren't documented, so a future app update can break parts of it. There are tests against a synthetic session to catch that early.

I'd love to hear what it shows on your sessions, especially long or multi-agent ones: github.com/draconnn/session-profiler

πŸ“° Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.