← SpeechRecognitionResult Timestamps (WebSpeech API)

v153 · dev trial · attribute

SpeechRecognition­Result.audio­EndTime

A nullable DOMHighResTimeStamp reporting the end of the source-audio segment that produced this recognition result, in milliseconds relative to the time origin, quantized to 2 ms precision. null when the recognition engine does not supply segment timestamps. Subtracting it from Event.timeStamp yields the recognition pipeline's processing lag — the signal behind latency-triggered backend failover. Developer trial in Chrome 153 behind the WebSpeechTimestamps flag.

Developer trial

Behind --enable-blink-features=WebSpeechTimestamps (flag experimental, not public — no chrome://flags entry, no origin trial). The defining spec change, WICG/speech-api PR #192, is open; the attribute can change in review. Detect with 'audioEndTime' in SpeechRecognitionResult.prototype. See the overview warn-block.

syntax

readonly attribute DOMHighResTimeStamp? audioEndTime;

Proposed spec text (PR #192, quoted verbatim): “A nullable DOMHighResTimeStamp representing the end of the audio segment corresponding to this recognition result, in milliseconds relative to the time origin. Returns null if the underlying recognition engine does not support audio segment end timestamps.”

The shipping Chromium IDL gates the same member on the runtime feature (speech_recognition_result.idl):

[RuntimeEnabled=WebSpeechTimestamps] readonly attribute DOMHighResTimeStamp? audioEndTime;
Source: PR #192 diff; speech_recognition_result.idl

value

TypeDOMHighResTimeStamp? (nullable double; milliseconds per High Resolution Time)
MeaningEnd of the audio segment this result was transcribed from, relative to the time origin — the same clock as performance.now() and Event.timeStamp
Null casenull when the underlying recognition engine does not support audio segment end timestamps (per spec PR) — in Chromium, when the engine's TimingInformation.audio_end_time was absent (getter returns std::nullopt)
PrecisionFloored to a multiple of 2 ms (FuzzTimestamp, kFuzzInterval = base::Milliseconds(2)) — anti-fingerprinting quantization required by the spec PR's privacy clause
Engine semanticsIn Chromium's pipeline the value originates as “elapsed processed audio from first frame after preamble” (speech_recognition.mojom) — i.e. how much audio the engine had consumed when the segment closed
Latency roleevent.timeStamp - result.audioEndTime ≈ processing lag: how long after the audio ended the result arrived. See the overview latency section
Source: PR #192; speech_recognition_result.cc; explainer

inputs

None. This is a read-only attribute: no setter, no parameters, no options. What the engine supplies is what the getter returns (after quantization); script cannot influence the value other than by choosing a recognition engine/backend that supports segment timestamps.

Source: PR #192 (readonly attribute, no associated setter or algorithm inputs)

errors

No error surface. The getter never throws: unsupported engines yield null, not an exception. Reading the attribute on a browser without the runtime flag fails earlier — the member does not exist on the prototype at all — so feature-detection ('audioEndTime' in SpeechRecognitionResult.prototype) is the correct guard, not try/catch.

Source: PR #192 (null contract); getter implementation

context and exposure

Source: speech_recognition.cc; Web Speech API

lifecycle

  1. The recognition engine emits a result with timing information (TimingInformation.audio_end_time in the mojom struct).
  2. Blink stores it on the result object at construction (SpeechRecognitionResult::Create).
  3. Each getter call returns the stored value floored to 2 ms, or null if unset. The value for a given result object does not change afterwards.
  4. Because Event.timeStamp is captured when the result event is created, the latency figure event.timeStamp - result.audioEndTime is most accurate when read promptly inside the handler; heavy handler work before reading it inflates the apparent lag.
Source: speech_recognition_result.cc; explainer — Proposed Behavior

examples

recognition.onresult = (event) => {
  const result = event.results[event.resultIndex];
  if (result.audioEndTime === null) return;  // engine without segment timing

  const lagMs = event.timeStamp - result.audioEndTime;
  latencySamples.push(lagMs);

  // Sustained lag over a sliding window → fail over to the cloud backend.
  if (median(latencySamples.slice(-20)) > 1500) {
    switchToCloudBackend();
  }
};
Source: adapted from the explainer's example usage (threshold + failover pattern); sliding-window aggregation is gendn-derived

browser compatibility

Interim table. No BCD key exists for this member (verified 2026-07-29); rows compiled from primary sources.

BrowserSupportEvidence
Chrome / Edge (Chromium)Dev trial 153 — WebSpeechTimestamps flag (experimental, not public)listing; flag record
FirefoxNo signalChromeStatus API record
SafariNo signalChromeStatus API record
Source: as linked per row

security and privacy

Source: PR #192 privacy clause; speech_recognition_result.cc

see also