Server preview latency spike (2026-11-07)
This page records the server-preview latency spike. The older full-render and GPU frame session baselines are in performance.md. This spike measured the existingrender paths that a future preview request
would reuse. It did not implement preview. The goal was the server-preview
gate: 000002 at 384x384, warm cache, p95 under 300 ms.
Environment: Windows 11, Ryzen 5 5500 (6C/12T), 47.9 GB RAM, GTX 1650 SUPER
4 GB, release blockscope 0.4.1, client jar 26.2-Fabric.jar, 12 threads,
384x384, supersample 1, views=[45], elevation=30. serve used
--cache 1 --force-limits; warm cases used streamMesh=off, streaming cases
used streamMesh=on. Peak working set was read from
GetProcessMemoryInfo(PeakWorkingSetSize).
Warm, cold, and streamed paths
000002 has 39.82M triangles; 000001 has 128.63M. The small fixture has
11,478 triangles and 2,079 blocks. Warm p50/p95 use 20 requests for 000002
and the small fixture, and 10 requests for 000001; streamed rows use 5
requests. The cold column is the first request in a fresh worker; it includes
parse, mesh build, and the first texture snapshot.
Resolution scaling on 000002
Warm cache, full mesh, 5 requests per size and backend:
The render is geometry-bound, not fill-bound: dropping from 384x384 to
128x128 changes CPU render time by about 5%. Lowering the preview resolution
does not rescue the stateless design.
GPU and resident-session context
The ordinary GPU render path is slower than CPU at these sizes:000002 took
2.52-3.16 s and 000001 took 16.0-17.2 s wall on the GTX 1650 SUPER. It
repeats setup/upload work for each request.
A textured GpuFrameSession was measured with the client jar. 000002 at
128x128 failed before rendering:
000001 textured was not attempted; its
color-only instance table already needs about 7.27 GB, above the same 1.29 GB
budget. Textured 000002 therefore needs roughly a 6-8 GB card, with 8 GB
safe; 000001 needs more still. The 4 GB reference card cannot do it.
Run the diagnostic with:
sphere_fit: true, 60 yaw frames, and two warm-up frames.
The color-only resident session is much smaller: a fresh 12-frame 256x256 run
measured 325 ms (about 27 ms/frame) with 201.9 MB resident, and the animate
CLI measured 60 color-only frames at 128x128 in 2,989 ms (about 50 ms/frame).
The 12-frame table in performance.md reports loop totals
for both columns; 413.5 ms is not a per-frame value.
Color-only blockout preview
The color-block catalog removes the client-jar model detail. The000002
color mesh has 2.30M quads (182 MiB heap) versus 39.84M quads for the textured
mesh; 000001 still has 87.88M color quads (6.48 GiB). Mesh budget decisions
use quads and heap bytes; render statistics report visible triangles, which is
why those counts look similar after backface culling.
000002 color-only meets the 300 ms gate at 384x384 on the CPU, with no client
jar and no GPU. Its color mesh heap is 191,246,592 bytes (182 MiB), within the
256 MiB cold-mesh budget; the measured peak process working set is 334 MB.
000001 does not meet the gate, and its color mesh heap is 6,955,659,792 bytes
(6.48 GiB), far above the budget. 000002 also has 8,959,516 unknown block
states (17.7% of visited blocks), which the color catalog renders with its
magenta fallback; the blockout preview is a geometry/framing aid, not a
color-accurate preview. The color-only session is an optional latency
optimization for 000002-class structures; it is not required to meet the
gate.
Verdict
- Textured preview is not viable at 384x384 on the 4 GB reference host:
stateless p95 is 1.77-1.82 s; the resident session returns
BACKEND_UNAVAILABLEfor000002because the textured instance table needs 3.66 GB against a 1.29 GB budget. A larger GPU is required for textured000002;000001needs more still. - Color-only blockout preview meets the 300 ms gate for
000002at 384x384 (p95 234-265 ms, 334 MB peak) on the CPU. It does not show textures, so it is a framing/rotation preview, not a final-look preview. 000001remains non-interactive in every mode measured: 4.8-5.0 s color-only, 9.4-10.5 s textured.- Recommended direction: a color-only blockout preview with a hard color-mesh
geometry budget.
000002-class structures work;000001-class structures are rejected. A resident session at 256x256 is an optional lower-latency mode; textured preview is opt-in only on hardware with enough VRAM, and000001-class structures stay batch--draft.
out/preview-spike/results.json and
out/preview-spike/resolution.json. Reproduction scripts:
out/preview-spike/measure.py, resolution.py, color_preview.py, and
color_000001.py.