Skip to content

STT time-to-first-partial metric (speech onset → first interim), the STT analog of ttft/ttfb #6533

Description

@mahimairaja

Feature Type

Would make my life easier

Feature Description

STT has no head-latency metric. LLMMetrics has ttft and TTSMetrics has ttfb, but STTMetrics exposes only duration (0.0 for streaming), audio_duration, and streamed. There is no equivalent for "how fast did the first word come back."

Two different STT latencies exist, and only the tail is measurable today:

Interval Meaning Status
end-of-speech → FINAL transcript EOUMetrics.transcription_delay exists (includes endpointing)
audio-end → FINAL transcript proposed in #5063 / PR #4966 in review
speech onset → first INTERIM first-partial responsiveness missing

The head metric is the one that predicts barge-in and perceived snappiness, and it is endpointing-free. transcription_delay cannot stand in for it: it is dominated by the endpointing/EOU wait, so it moves when you tune silence thresholds even if the STT's first-word speed never changed.

Both operands are already present in AudioRecognition._on_stt_event: the VAD-backdated onset self._speech_start_time, and the INTERIM_TRANSCRIPT branch. The metric is a wall-clock subtraction there, no provider timestamps involved:

# AudioRecognition._on_stt_event, INTERIM_TRANSCRIPT branch
elif ev.type == stt.SpeechEventType.INTERIM_TRANSCRIPT:
    if self._first_interim_at is None and self._speech_start_time is not None:
        first_interim_delay = time.time() - self._speech_start_time

Proposed carrier (leaning EOUMetrics, since that is where it is computed and it stays symmetric with transcription_delay):

first_interim_delay: float
"""Seconds from speech onset (VAD start) to the first interim transcript.
The STT-responsiveness analog of LLMMetrics.ttft / TTSMetrics.ttfb.
Unset / 0.0 when the STT emits no interims (non-streaming or interim_results=False)."""

Alternative placement is STTMetrics.first_interim_latency, but the plugin never sees VAD onset, so it would need framework enrichment anyway. Happy to take direction on which surface you'd prefer.

Why the #5063 end_time-reliability concern does not apply here: this metric never reads a provider end_time. Onset comes from VAD; the first interim's timestamp is just its wall-clock arrival. It is unaffected by the endpointing-accuracy objection that blocks the tail metric.

Workarounds / Alternatives

  • EOUMetrics.transcription_delay: measurable today, but it is the tail (end-of-speech → FINAL) and folds in endpointing, so it conflates STT speed with EOU tuning.
  • Timing user_input_transcribed at the AgentSession layer: works downstream but adds the session emit hop on top of the real STT latency, so it overstates it and drifts with unrelated scheduling.
  • Both are proxies. The value already exists one layer down in _on_stt_event; surfacing it removes the guesswork.

Additional Context

This thread was first started at Livekit Community

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions