Caching
Identical Python re-runs produce byte-identical DAGs (the DAG node IDs are content hashes). The SDK and CADbuildr’s hosted render service exploit this with several layers of cache, so a popular storefront default doesn’t pay a fresh kernel render per visitor.
You don’t configure most of this — it’s handled for you. What you do control is how cache-friendly your parameters are. This page explains the layers so you can get the highest hit rate.
Server-side render cache
CADbuildr’s render service caches rendered meshes keyed on the canonicalized DAG plus the kernel version. Because identical parameter values produce an identical DAG, two visitors who land on the same configuration share a single render — the second one gets the cached mesh response.
- Survives JSON round-trips and emitter changes — the cache key is computed from a canonical serialization of the DAG, not its raw bytes.
- Automatically invalidates on kernel upgrades — the kernel version is part of the key, so a redeploy re-keys the cache with no action on your side.
- Automatically invalidates on project changes — editing your parameter schema or template DAG changes the canonical DAG, so the next render misses and refills under the new key.
A 1000-visitor configurator on a 5-parameter grid typically sees a high cache hit rate after the first hour — most visitors land on the project defaults or a small number of common configurations.
Client-side mesh-hash cache
@cadbuildr/cad-kernel-r3f keeps an in-browser geometry cache keyed on
the per-mesh hash field of the render response. Two benefits:
- Within a single render — repeated meshes (the same brick at many
positions) share one
BufferGeometryinstead of uploading duplicates to the GPU. - Across renders in the same provider — already-uploaded meshes are reused, so nudging a slider only re-uploads the meshes that actually changed.
The SDK also sends the hashes it already has on each request, and the
render service omits those mesh blobs from the response. This keeps
the per-render network payload small even for scenes with hundreds of
parts. Re-use a single <CadbuildrProvider> at the page level so this
cache is shared across all your viewers.
Discretization — the one thing you control
The single biggest hit-rate predictor is parameter discretization.
The SDK’s parameter form snaps sliders to your declared step, and the
render cache keys on the resulting quantized value. If you ship a slider
as Float("size", step=0.001), every visitor’s nudge lands on a
distinct value and misses the cache. Pick the smallest step that
produces visually distinct geometry — usually 0.1 or 1.0 for
millimeters.
Common hit-rate killers, in order:
- Slider step too small (effectively continuous float values).
- A parameter with high cardinality but low visual impact (e.g. a
free-picker
Colorthat should be a smallEnumover named choices).
Observing cache behaviour
The onRender callback on <CadbuildrViewer> fires on every successful
render with metadata you can log or send to your own analytics — mesh
hashes, byte sizes, and kernel render time:
<CadbuildrViewer
dag={dag}
onRender={(meta) => console.info("rendered", meta)}
/>A render that resolves quickly and returns few mesh blobs (most omitted because you already hold their hashes) is a cache-friendly one. If renders are consistently slow with full payloads, revisit your slider steps and parameter cardinality above.