Case 01 / Clinical imaging / 2026

The measurement that isn’t allowed to be wrong

A multi-tenant viewer for orthodontic DICOM and photogrammetry volumes. 31.2 MB per study, a browser tab, and one rule: no number the system can’t stand behind.

Role
Architecture, API, viewer
Stack
FastAPI · vtk.js · S3 · Terraform
Volume
256 × 256 × 125 float32
Window
March 2026 — present

01 / The constraint

Every thumbnail asked for the whole volume.

Clinical reviewers need to look at a 3D volume plane by plane. The volume is one C-ordered float32 array: 256 × 256 × 125, about 31.2 MB. The viewer loads a strip of thumbnails before the reviewer touches anything.

The storage layer had just stopped being a local directory. Every one of those thumbnails asked for the whole object. On a laptop that's a file read. Over a bucket it's a network transfer, repeated, on the hot path. The request path saturated and the API started returning 504s.

02 / The call

The planes are contiguous. Ask for one.

In a C-ordered (nz, ny, nx) array, plane k starts at k × nx × ny × 4 and runs for nx × ny × 4 bytes. One plane is 256 KB. So the API stopped downloading volumes.

Storage.get_range(ref, offset, length) seeks on a local file and sends an S3 Range header on a bucket. The viewer asks for one plane at a time.

Byte-range read · 256 × 256 × 125 plane 63 / 124
nz 125 · C-ORDERED (nz, ny, nx) PLANE 63
Range request
256 KB
Offset
15.75 MB
Whole object
31.25 MB

Verified byte-identical to the whole-array slice on the real volume. That's 99.2% less transferred per request, and it removes the 504s because the hot path no longer contains a 31 MB transfer.

A short range raises 416 instead of returning fewer bytes. Returning a short plane would reshape into a wrong-sized image and draw the wrong anatomy. A failed request is better than a plausible wrong one.

03 / The invariant

A number is a claim about the world.

Photogrammetry poses can be solved without a verified scale. A viewer that ignores that will happily measure a jaw in millimetres that mean nothing. The API exposes scale.verified. When it's false, the measurement is withheld.

Caliper · mesiodistal 42.7 mm scale.verified: true

The value is absent from the payload, so there's nothing for a client to render by mistake. A test pins the rule, and that test is why you can trust the toggle above.

04 / What broke

Three things that cost real time.

01

The first range implementation returned fewer bytes. bytes[start:start+length] is silently short at the end of an object. The shorter buffer reshaped into a wrong-sized plane. Fixed by raising 416.

02

Four suppress(...) blocks swallowed storage errors. A bucket outage made jobs look fine in memory while never persisting, with nothing in any log. Suppressed failures are logged now.

03

The dev object store is apps/api/.data. Deleting it wipes every uploaded source. It's not obvious, and it costs an afternoon the first time.

05 / Evidence

What's measured, and what isn't.

ClaimMethodState
31.25 MB whole object256 × 256 × 125 × 4 bytes● measured
256 KB per planenx × ny × 4 bytes● measured
99.2% less transferredByte-compared against the whole-array slice● measured
416 on a short rangeRegression test● measured
168 API and invariant testsSuite run● measured
Real segmentation over a real CTThe pipeline is deployed; the model hasn't been run over a study○ unverified

The last row stays on the page because the rule applies to this site too. The plumbing isn't the result.