# audio_latency

> The audio output's base latency from AudioContext.baseLatency, read only in Safari and on Android. Nothing is played; not in either id.

Source: https://whiskerjs.com/signals/audio-latency/ (last updated 2026-10-26)

**audio_latency at a glance (from the library code, signalsVersion 9)**

| Field | Value |
| --- | --- |
| Component name | `audio_latency` |
| In the visitorId | no (reported, kept out of both ids) |
| structuredId group | none |
| Hashing | plain value; a digest only when longer than 128 characters or not printable ASCII |
| Excluded under | no browser class |
| Inner timeout | 1000 ms |
| Added in | [signalsVersion 3](https://whiskerjs.com/whats-new/) |

> **In plain words:**
>
> Every audio output adds a small delay between a sound being made and it being heard. Browsers report a base value for that delay, which depends on the audio hardware and system. WhiskerJS reads it only where that is quiet (Safari and Android browsers), never plays anything, and keeps it out of the identifiers because it follows whatever output device is in use.

## What it reads

`AudioContext.baseLatency` (or the `webkitAudioContext` form), in seconds.

## How the technique works

1. If the browser class is not `safari` and the user agent does not contain `Android`, the component reports `unavailable` with ruleId `skipped` and creates nothing.
2. Otherwise it creates an `AudioContext`, reads `baseLatency` and closes the context immediately in a `finally` block (errors while closing are ignored).
3. The number is rounded to six decimals.

## Why it helps

The value follows the audio stack and output device, which differs between phone models and Mac setups. It gives your server extra context where many other values are the same, for example among iPhones.

It is deliberately limited to places where reading it is silent for the user and the console. That choice follows the library’s rules: no console output, no sound, nothing that a careful site owner would notice as a side effect.

## Stability

Medium: it changes with the output device (speaker, headphones, Bluetooth). That is why it is outside both ids.

## Browser support and what blocks it

| Where | Result |
| --- | --- |
| [Safari on macOS](https://whiskerjs.com/browsers/safari-macos/), [Safari and every iOS browser](https://whiskerjs.com/browsers/safari-ios/) (all classed `safari`) | read |
| Android browsers: [Chrome Android](https://whiskerjs.com/browsers/chrome-android/), [Samsung Internet](https://whiskerjs.com/browsers/samsung-internet/), Firefox on Android | read |
| Desktop [Chrome](https://whiskerjs.com/browsers/chrome-desktop/), [Edge](https://whiskerjs.com/browsers/edge/), [Brave](https://whiskerjs.com/browsers/brave/), [Firefox](https://whiskerjs.com/browsers/firefox/) | `unavailable` / `skipped` |

No browser class excludes it through the exclusion table; the skip is the collector’s own rule.

## Privacy

A latency figure says little more than “this kind of audio hardware”. No sound is played, no microphone is touched and no audio device is opened for recording.

## How WhiskerJS handles noise and failures

| Status | ruleId | When |
| --- | --- | --- |
| `ok` |   | seconds, up to six decimals |
| `unavailable` | `skipped` | not Safari and not Android |
| `unavailable` | `no_api` | no `AudioContext` |
| `unavailable` | `no_value` | `baseLatency` is not a finite number |
| `blocked` | `threw`, `security_error` | creating the context throws |
| `excluded` | `caller_excluded` | you excluded it |
| `timed_out` | `timeout`, `aborted` | budget or abort |

## Example value

In the container test, headless WebKit (classed `safari`) reported `0.002902`; headless Chromium and Firefox reported `unavailable` / `skipped`.

## Questions and answers

### Why is audio_latency skipped in Chrome on my computer?

Creating an AudioContext outside a user gesture makes desktop Chromium and Firefox print an autoplay warning in the console, and WhiskerJS writes nothing to the console. So it reports unavailable with ruleId skipped there. Nothing is wrong with the browser.

### Does it play a sound?

No. It creates an AudioContext, reads one property and closes the context at once.

## Related pages

- [audio](https://whiskerjs.com/signals/audio/): The offline audio render, in the id.
- [Safari on macOS](https://whiskerjs.com/browsers/safari-macos/): One of the places it is read.
- [Chrome on Android](https://whiskerjs.com/browsers/chrome-android/): Android browsers are the other.
