Signal · signalsVersion 14

webgpu_limits

Every limit of the WebGPU adapter and the preferred canvas format, as a digest, from the one adapter WhiskerJS requests. Reported, not in either id.

webgpu_limits at a glance (from the library code, signalsVersion 14)
Component namewebgpu_limits
In the visitorIdno (reported, kept out of both ids)
structuredId groupnone
Hashingalways a digest (first 128 bits of SHA-256)
Excluded underno browser class
Inner timeout1000 ms
Added insignalsVersion 11
Collector revision1 (reported as revision with every result)
In plain words

Before a web page can use the graphics chip through WebGPU, it asks for an “adapter”, which describes what the chip may do. The webgpu signal already reads part of that description. This one reads every maximum the adapter lists (the limits) and the colour format the browser prefers for drawing, and turns them into one short code.

What it reads

  1. The WebGPU adapter that the webgpu component requests: navigator.gpu.requestAdapter() with no options is called once per collection and shared by both components.
  2. Every numeric attribute of the adapter’s limits (a GPUSupportedLimits object), sorted by name.
  3. navigator.gpu.getPreferredCanvasFormat().

No device is requested and nothing is drawn.

How the technique works

The limits are written as name=value;... in name order, followed by canvasFormat=<format>, and the whole string is always hashed. Because it reuses the adapter of webgpu, it adds no second adapter request.

Why it helps

It is the complete limits set, where webgpu keeps only seven limits. The specification buckets the values, so the set mostly separates GPU classes and browser implementations rather than single devices. Its value for your server is consistency: a WebGPU limits set that does not fit the WebGL renderer is unusual.

Stability

Expected to be stable until a browser or driver update. Low entropy and reported outside both ids. Added in library PR #29 (2026-10-27) at signalsVersion 11: it is outside both ids, so adding it changed no id and needed no version bump.

Browser support and what blocks it

  • ok where navigator.gpu returns an adapter (secure contexts only).
  • unavailable / no_context when no adapter is returned: Chromium 153 and Chrome 155 on the GPU-less CI runner of PR #29.
  • unavailable / no_api without navigator.gpu: headless Firefox and WebKit on Linux in the same runs.
  • No browser class excludes it. Brave empties the adapter’s info fields (so webgpu is excluded there); the limits are bucketed by the specification and are still read.

Privacy

The limits describe the GPU’s capabilities in coarse buckets. They leave the library only as a digest. requestAdapter() shows no prompt.

How WhiskerJS handles noise and failures

Status ruleId When
ok a digest
unavailable no_api no navigator.gpu.requestAdapter
unavailable no_context no adapter
unavailable no_value the adapter lists no limits
unavailable no_digest no Web Crypto
blocked threw, security_error requestAdapter() rejected or a read threw
excluded caller_excluded you excluded it
timed_out timeout, aborted budget or abort

Example value

"webgpu_limits": { "status": "unavailable", "ruleId": "no_context", "durationMs": 3.2, "revision": 1 }

That is what the GPU-less CI browsers reported; on a device with a GPU the value is a digest.

Questions and answers

Does webgpu_limits create a GPU device?

No. It reads the limits of the adapter that the webgpu component already requests. requestAdapter() is called once per collection, never prompts, and no device is ever requested.

Why is it low in entropy?

The WebGPU specification lets browsers round adapter limits into a few buckets so that they reveal less. The limits therefore fall into a small number of sets.