Call metrics
Latency by stage, talk share, interruptions and cost: what every call measures about itself.
Every call measures itself as it runs: how long each stage of each turn took, how much of the talking the agent did, how it took being interrupted, and what the whole call cost. The numbers are entries of the call's own log, so they are the same in the console, the CLI and the API.
What does a call measure?#
Latency by stage#
These are LiveKit's own measures, taken on every turn and written on the turn they belong to.
| measure | on | means |
|---|---|---|
transcription_delay |
caller turn | seconds from the caller's end of speech to the final transcript |
end_of_turn_delay |
caller turn | seconds from the end of speech to the decision that the turn was over |
llm_node_ttft |
agent turn | seconds until the model returned its first token |
tts_node_ttfb |
agent turn | seconds until the voice returned its first audio, counted from the first text token |
e2e_latency |
agent turn | seconds from the caller finishing to the agent starting to answer: the number a caller feels |
dead_air |
agent turn | seconds of silence between the caller stopping and the agent starting. A reply that started before the caller stopped talked over them and is not counted |
Beside them, the log keeps every raw block LiveKit reports, as metrics.llm, metrics.stt, metrics.tts,
metrics.eou and the rest: tokens read and cached, characters synthesized, audio seconds, connection times.
Metrics lists every field.
metrics.eou'son_user_turn_completed_delayis what knowledge and memory lookups cost the caller in silence. It is usually near zero, because a lookup starts while the caller is still speaking.
Talk and interruptions#
| measure | means |
|---|---|
talk_share |
the agent's part of the time anybody spoke on the call, from 0 to 1. One value per call |
interruption_delay |
seconds from the caller starting to speak over the agent to the agent going quiet. One value per reply that was cut off |
Cost#
When a call ends, its call.summary entry says how it ended and what it used:
| field | holds |
|---|---|
reason, outcome |
why the call ended, and what came of it |
duration_s, turns |
how long it ran, and how many times the agent spoke |
usage |
every model, recognizer and voice the call used, with its counts |
cost.usd |
the total, in US dollars |
cost.rows |
one priced line each: provider, model, unit, quantity, unit price and amount |
cost.unpriced |
anything the price table has no rate for. Listed, never priced at zero |
A row's unit is one of input_tokens, cached_input_tokens, cache_creation_tokens, output_tokens,
characters, audio_seconds, requests, session_seconds or minutes (a phone leg). The model call that
writes memory at hang-up is billed with the call. What judging the call cost is separate:
judge_cost_usd on its call.score.
Where to read them#
| where | what it shows |
|---|---|
pinecall sessions <call-id> |
the outcome, duration, cost with one line per priced row, and the score |
| the console's Calls screen | each turn with its latency, the tools, the lookups, and the verdicts |
pinecall test |
the median e2e_latency, llm_node_ttft and tts_node_ttfb of each golden, when its turns reported them |
pinecall simulate |
the latency of each turn as the call happens |
pinecall eval <call-id> |
each measure's worst turn against a budget, plus talk_share and interruptions |
GET /v1/insights |
per day and vendor, for transcription_delay, llm_node_ttft and tts_node_ttfb: how many turns, the median and the 95th percentile |
pinecall eval holds a call to a budget in seconds. With none given it uses 2 s for e2e_latency, 1 s for
llm_node_ttft and 0.6 s for tts_node_ttfb; dead_air, talk_share and interruption_delay are judged
only when the budget names them. It reads the worst turn, not the median: the caller who waited four
seconds once heard four seconds. Replaying a real call has the details.
A field the measuring side could not fill is absent, never zero. A measure no turn reported is left out of a report rather than shown as 0.