watch() runs and shares it for the life of the process, so every call a client makes lands in the same session.
Why sessions matter
Two of the most useful metrics are questions about a conversation rather than about a call:- Retries and first-call success are detected within one session. Two calls to the same tool in different sessions are two people, not one struggling model.
- Cost per session is what your server costs someone for one conversation, which is the figure an author can actually act on.
McpServer is built per request, the SDK deliberately shares one session per process for exactly this reason.
Counted by start time, never summed per day
Sessions get their own table rather than a daily counter, because a session can cross midnight. A session that opens at 23:50 and closes at 00:10 is one session. Summing daily session counts would make it two — and would halve cost per session, the number an author is most likely to quote back. So sessions are counted bystarted_at across the whole range, which is correct at any range length.
What is stored per session
The API returns totals plus the most recent sessions — up to 500, defaulting to 100 — each with its bytes converted to tokens and dollars.
Sessions have no tool dimension — but they do have a client
A session belongs to the server, not to a tool. Under a tool filter the sessions figure, calls per session and cost per session all come backnull rather than as unfiltered numbers sitting in a filtered row. Scoping a session to a tool is not a harder query; it is a meaningless one.
A client filter is different: sessions.client_name has always existed, so “sessions, for Cursor” is a real question and it narrows.
Depth is shown in bands, not as an average
The average of one 40-call session and nine single-call ones is 4.9, and 4.9 describes none of the ten. So the overview draws a distribution: even bands of three —1–3, 4–6, … 19–21, then 22+ left open.
Even, deliberately. The bands were uneven once — 1, 2, 3, 4, 5–9, 10–14, 15–24, 25+ — on the reasoning that the shallow end is where the finding is. That is a fair read of the data and a poor axis: bar widths going 1,1,1,1,5,5,10,∞ cannot be compared to each other, because a taller bar may only mean a wider bucket.
single_call_share is counted from the sessions themselves, not from the first band. It read the first band’s count while that band happened to be exactly 1; at a width of three the same line would have reported the share making one, two or three calls under a name saying otherwise, and nothing on screen would have looked wrong.