Skip to main content

Web SDK Performance Guide

In soundtrace.js, raising ray count, depth, source count, and geometry/BVH settings can improve path stability and spatial impression. The same settings also raise propagation time, memory use, main-thread frame time, and AudioWorklet load.

This guide is the reference an SDK integrator uses when choosing options. The presets below are starting points; the recommended source counts and platform-specific limits will be replaced with measured tables once measurement is complete.

Fixed runtime contract

ItemCurrent contract
Listener1 per scene
Realtime outputStereo/binaural, 2ch
Audio render pathWASM AudioWorkletProcessor on both ST and MT
Multi-source audiosource.play(input, 2) per source (facade) / createWorkletNode() for ST direct-native
Native source cap16 sources (EXA_MAX_SOUNDSOURCE)
Ray depth ceiling16 (EXA_MAX_DEPTH)
Default quality presetquality: 'balanced' = listener rays 24 x 24, depth 8

16 is the native cap — the maximum number of sources that can exist in one scene at a time. The realtime source count you recommend to customers has to be measured separately within that cap, per platform, geometry size, ray budget, BVH, and ST/MT mode.

The listener ray grid and depth set by each quality preset:

PresetListener raysDepth
fast16 x 164
balanced (default)24 x 248
quality32 x 3212

Key options and trade-offs

OptionQuality effectPerformance effect
Listener ray width/heightBetter path discovery and directional stability at the listenerPropagation cost grows with the ray grid area
Listener depthAllows deeper reflection/diffraction/reverb pathsMore path search and cache pressure
Source reverb ray width/heightBetter source-side late reverb coverage and material response stabilityCost grows with source count and ray grid area
Source reverb depthDeeper source-side late reverb tracingPath search and cache pressure grow with depth
Source countMore simultaneously spatialized emittersHigher propagation and AudioWorklet mixer cost
BVH typeChanges traversal/build characteristicsBuild/refit/traversal cost varies with geometry and update style
BVH max depthControls tree depthToo shallow wastes traversal; too deep costs build time and memory
Prims per leafControls triangles per leafThe traversal/build balance point depends on scene structure
Animated/refit geometryReflects moving collidersHigher refit/rebuild cost; measure separately as a stress item
Thread modeMT can distribute propagation jobs across worker threadsRequires cross-origin isolation; adds thread/memory overhead

Reverb ray budget

Reverb rays are not a copy of the listener rays. Source-side late reverb costs scale as source count × width × height × depth, so production defaults are raised per scene separately from the listener rays. The QA sweep uses sources [4, 8, 12, 16], general and reverb rays each stepping through 4 x 4 x 3, 8 x 8 x 7, 16 x 16 x 11, 32 x 32 x 16, and path cache [256, 512, 1024].

Starting presets

Until the measured tables are filled in, use these as starting points and adjust against your target FPS and perceived quality.

PresetThreadListener raysReverb raysDepthBVHUse forMeasurement status
Mobile conservativeST16 x 164 x 4 or 8 x 84LBVH or platform defaultMobile minimum baselineMeasurement pending
Desktop balancedST or MT24 x 248 x 88LBVH_SIMD8Desktop default baselineMeasurement pending
Desktop qualityMT32 x 3216 x 1612LBVH_SIMD8Quality-first desktopMeasurement pending
Stress onlyMT32 x 3232 x 327..16BVH matrixLimit measurement onlyNot a realtime default

The MT gain is unmeasured and is not automatically faster. The speed gain of the MT presets above is still Measurement pending. MT distributes propagation jobs to a worker, so the gain shows up when the ray budget and source count are large (high ray grid/depth, many sources); in small scenes the worker round trip and memory overhead can make ST simpler and faster. MT also carries the deployment cost of cross-origin isolation (COOP/COEP). Start small scenes and simple pages on ST, and choose MT only after measuring ST vs MT on a scene with a large budget.

If the spatial impression is weak, do not raise the source count first. Raise the listener rays and the source reverb ray count/depth separately, in steps. Measure source-count increases last.

Metrics to measure

When publishing numbers in customer documentation, repeat the same scenario under the same duration/warmup conditions and publish summaries only, never raw logs.

GroupMetrics
Browser frameAverage FPS, frame time p50/p95/p99, worst frame, dropped frame count
Main-thread stallPerformanceObserver longtask count/total/worst, where supported
Engine propagationscene.tick() + scene.updatePropagation() time p50/p95/p99/worst
Native job timingPropagation job timing frames, worker distribution/wait time
Path qualityValid path count average/max, listening notes on material/path changes
AudioAudioContext.sampleRate, baseLatency, outputLatency, state, setup time
MemoryNative memory trace snapshot, JS heap snapshot
Manual observationDrop-outs, weak localization, thermals, fan noise, perceived battery drain

Browser JavaScript alone cannot reliably produce cross-platform power and thermal numbers. Do not treat power and thermals as automatic measurements — separate them into manual observation or dedicated instrumentation.

Measurement matrix

MatrixValues
Baseline1 source on ST and MT each, listener 16 x 16 x 3, source 16 x 8 x 3, static small geometry
Quality scaleListener 16 x 16, 32 x 32; source reverb 4 x 4, 8 x 8, 16 x 16, 32 x 32; depth 3, 7, 11, 16
Source scale1, 2, 4, 8, 12, 16 sources (native cap 16)
Reverb ray scaleSources [4, 8, 12, 16], general ray steps 4 x 4 x 38 x 8 x 716 x 16 x 1132 x 32 x 16, reverb rays on the same steps, path cache [256, 512, 1024]
Geometry/BVHSmall/medium/large geometry, HKDtree, LBVH, LBVH_SIMD4/8/16, LBVH_NWAY4/8/16
Stress onlyAnimated/refit, rebuild-heavy, native source cap, high ray budget

Publication rules

ItemRule
Measured valuesPublish with platform, browser, SDK commit, STCoreV2 commit, and scenario
Unmeasured valuesDo not estimate a number; mark it Measurement pending
Source capKeep the native cap 16 separate from the recommended source count
Stress resultsPresent as limit/regression detection, not as realtime recommendations
Raw logsNever paste into customer docs; publish summary tables and interpretation