`metrics_collected` is deprecated — what's the right replacement?

We’ve been using metrics_collected to log per-turn metrics in our voice agent:

@session.on("metrics_collected")
def _on_metrics_collected(ev: MetricsCollectedEvent):
    metrics.log_metrics(ev.metrics, logger=logger)

The deprecation warning says to use session_usage_updated instead, but that event gives cumulative session totals via AgentSessionUsage, not per-turn metrics. So it’s not a direct replacement for log_metrics.

Looking at the source, it seems ChatMessage.metrics is the new way to get per-turn latency data, but there’s no documentation on how to use it in practice.

Questions:

  1. Is log_metrics still the right way to log per-turn metrics, or is there a new equivalent?
  2. What’s the intended pattern for accessing per-turn metrics now — listening on conversation_item_added and reading ev.item.metrics?
  3. Any plans to document session_usage_updated and ChatMessage.metrics properly?

The best source I can point you to is the release notes for Agents 1.5.0, Release livekit-agents@1.5.0 · livekit/agents · GitHub, there is a ‘Deprecations’ section and table specifying the replacement:

Deprecated Replacement Notes
metrics_collected event session_usage_updated event + ChatMessage.metrics Usage/cost data moves to session_usage_updated; per-turn latency moves to ChatMessage.metrics. Old listeners still work with a deprecation warning.

Looking at the source, it seems ChatMessage.metrics is the new way to get per-turn latency data, but there’s no documentation on how to use it in practice.

It looks like the documentation still talks about metrics_collected, Events and error handling | LiveKit Documentation, so let me check with the docs team, possibly that wasn’t updated yet.

Confirmed, the docs will be updated in the coming days, apologies for the delay

My question is do I need to replicate the log_metrics function or LiveKit will release a native approach for that?

My question is do I need to replicate the log_metrics function or LiveKit will release a native approach for that?

Good question… I don’t see an equivalent, and looking at the pre-release docs, it looks like you’ll need to replicate the behaviour.

hi @darryncampbell , what will be the correct replacement for tracking realtime model metrics, as metrics collected event is deprecated.

For realtime model metrics, you now have two supported options:

  • Per-session usage (live + cumulative): Use the session_usage_updated event or session.usage for token counts and duration tracking.

  • Per-turn latency: Read ChatMessage.metrics from the conversation_item_added event for end-to-end and stage latency.

  • Per-plugin metrics (not deprecated): Subscribe directly to the realtime model’s metrics_collected event on the plugin instance.

See the migration guidance in Events and error handling and the full breakdown in Metrics and usage data.

Hi @CWilson , @darryncampbell

I’m trying to collect per-plugin metrics for a realtime model session. I understood:

Per-plugin metrics → subscribe to the realtime model’s metrics_collected event on the plugin instance

I’m currently using a llm.RealtimeModel instance through:

@property
def llm(self) -> llm.LLM | llm.RealtimeModel | None:
    return self._llm

I tried: session.llm.on(“metrics_collected”)

but llm.RealtimeModel does not seem to expose `rtc.EventEmitter` methods, so .on(…) is not available.

What is the correct way to subscribe to metrics_collected events for a RealtimeModel?

Could someone share an implementation snippet for collecting per-plugin metrics from a realtime model session?

Thanks!

Hi @Harshita_Sukumar_Patil , we have this recipe that shows how to capture and summarize RealtimeModelMetrics:

Thanks for sharing the reference @darryncampbell ,
also is there any per plugin equivalent to capture EOUMetrics ?

@Harshita_Sukumar_Patil, this thread is already solved. But to answer your question;

EOU follows the same migration as the rest of the deprecated metrics_collected event. The per-turn end-of-utterance fields (end_of_utterance_delay, transcription_delay, everything from EOUMetrics in livekit/agents/metrics/base.py) live on ChatMessage.metrics of the conversation_item_added event in the new model.

There’s no separate per-plugin EOU emitter the way RealtimeModel has one, because EOU is computed in the framework’s audio_recognition path, not in a user-pluggable component. The deprecated metrics_collected event still emits EOUMetrics with a deprecation warning per @darryncampbell’s #2 table, so it remains a transitional bridge until you fully cut over to conversation_item_added.

Thank you for the clarification, @Muhammad_Usman_Bashir.

We are currently pulling end_of_turn_delay from Chat.metrics, but we still rely on the plugin-level metrics_collected events for TTFT and TTFB. Previously, we used the speech_id as a common key to map metrics (eou_delay, ttft and ttfb) for total latency calculations.
In the new migration, as ChatMessage.metrics (within conversation_item_added) does not include the speech_id,though it still exists in the LLMMetrics / TTSMetrics objects, how do you recommend correlating these metrics to calculate total latency?

@CWilson , @darryncampbell

I raised this difficulty (about speech_id) to our agents team, along with other issues raised by the community around the deprecation of this API, and we will not deprecate without an alternative. Thank you for raising this use case.