Out-of-Core Terrain Streaming: How a Gigabyte DEM Opens on a Laptop
A 5 cm DEM of a 2 km × 2 km site holds 1.6 billion elevations — 6.4 GB as 32-bit floats, more than most graphics cards have. Out-of-core streaming is the engineering answer: keep the whole surface on disk in a form that can be read piece by piece, and keep in memory only what the screen can show. This article walks through how STREAM does it, with the numbers behind each step.
Step 1: a tiled, multi-resolution copy
The source GeoTIFF or BigTIFF is read once and converted into a native copy: a fixed 512 × 512 tile layout with overview levels, elevation as Float32 and orthophotos as RGBA8, stored as ZSTD-compressed tiled BigTIFF. A tile table records which tiles are built, and the copy only counts as complete when every tile is.
For a 40,000 × 40,000 DEM that means 79 × 79 = 6,241 tiles at full resolution, each exactly 1 MiB as Float32. Halving down to a single tile adds seven overview levels — 8,380 tiles in all. Every tile has a fixed identity of level, x and y, which is what makes everything after this step addressable.
| Quantity | Value | How it follows |
|---|---|---|
| Tiles at full resolution | 79 × 79 = 6,241 | 40,000 ÷ 512 = 78.1, rounded up |
| Size of one Float32 tile | 1 MiB | 512 × 512 × 4 bytes |
| Levels including overviews | 8 | halving 79 tiles down to 1 |
| Tiles in the whole pyramid | 8,380 | sum over all levels |
| Screen of 1920 × 1080 | ≈ 7.9 tiles of pixels | 2.07 million ÷ 262,144 |
Step 2: ask only for what the camera sees
Every frame, the camera state produces a request set: a pinned coarse set that covers the whole view, and a detail set where you are focused. Tiles outside it are not decoded, not uploaded and not kept.
This is the line that bounds memory. A 1920 × 1080 view contains about as many pixels as eight full tiles; with a margin and a mix of levels the working set stays in the tens of tiles — tens of megabytes — whether the file is 200 MB or 20 GB.
Step 3: decode off the render thread, newest first
Decoding runs on worker threads as jobs with five priority levels, from background prediction up to critical, under a limit on how many are in flight. Each request carries a generation; when the camera moves on, older generations are cancelled instead of finishing, so a fast pan does not leave a queue of tiles nobody will see.
Upload order follows camera focus and visibility. If a fine tile is not ready, the coarser tile above it stands in — the surface is always closed, and detail sharpens as tiles arrive.
Step 4: evict without opening holes
When the GPU atlas is full, eviction prefers tiles of the same or a coarser level than the one coming in, weighs distance from the camera focus, and protects the pages that provide the coarse fallback. Freeing room for detail therefore never removes the base underneath.
Elevation and orthophoto are tracked as separate sparse page sets with their own residency, so a heavy orthophoto cannot starve the terrain of height tiles.
What streaming changes for the engineer
The cost moves to the first open, where the conversion runs once with a cancellable progress card; afterwards the same survey reopens in seconds. Several DEMs of one site are bound into a single virtual mosaic — the topmost valid pixel wins and NoData falls through — and analyses read that same mosaic the renderer draws.
None of this needs a server: conversion, streaming and rendering run on the local machine with Vulkan on the GPU, which is what lets a gigabyte survey be inspected on a site laptop without uploading it anywhere.
Frequently asked questions
What does out-of-core mean for terrain data?
The dataset stays on disk in a tiled, multi-resolution form and only the parts needed for the current view are loaded into memory. Memory is bounded by the screen, not by the size of the file.
How many tiles does a 40,000 × 40,000 DEM have?
In 512 × 512 tiles, 79 × 79 = 6,241 at full resolution, each 1 MiB as Float32, and 8,380 including the seven overview levels.
Why does the first open take longer?
Because the source is converted once into the native tiled copy with overview levels. After that the renderer reads tiles directly from the copy, so reopening takes seconds.
See terrain streaming in STREAM
Native Windows · fully offline · free beta