ForgeGIS · Vector Engine · Scale Study

A million buildings, one immutable chain

Seven vector operations over real building footprints — and the work mix barely moves across two orders of magnitude.

Real Microsoft building footprints for Houston, run through a seven-operation chain on the ForgeGIS parallel-CPU vector engine — reproject, shape metrics, setback buffer, points-in-polygons join, classify, reproject back — entirely through immutable in-process handles, with no per-stage file I/O. Every number on this page was read from a server-side timing path, never from pixels.

124,785
features/sec at one million footprints, measured headless around each operation
2.03×
the entire spread in features/sec between 100k and 1M — near-flat across an order of magnitude
0
files written between stages. Every intermediate is an immutable in-process handle
A dense city block grid of Houston seen from above, with every building footprint filled in shades of teal and dark green over an OpenStreetMap basemap, streets and highways visible between them
One million real footprints served as vector tiles, filled straight from the class codes the engine wrote. Every visible polygon is a real building — no sampling and no decimation anywhere on this page. Scale bar reads 300 m.

What the chain does

Seven operations, run identically at every tier. Two file ingests bracket it and are disclosed separately — they are not counted as engine time.

The data

Microsoft US Building Footprints for Texas, clipped to nested bounding boxes around Houston at 10,000 / 100,000 / 1,000,000 features. Stored in EPSG:4326; the chain reprojects to UTM 15N so that buffers and areas are in honest metres, then back again.

The chain

Points to UTM, reproject to UTM, shape metrics, a 5 m setback buffer, a points-in-polygons join, classify, reproject to WGS84. Each stage hands the next an immutable in-process handle; nothing is written to disk between operations.

What “measured” means

Engine time is the per-operation elapsed time recorded server-side around each call, with one warmup and three measured runs, mean reported. Wall time including HTTP is kept beside it and never blended in. Features/sec is simply features divided by engine total.

What this page claims
That the ForgeGIS parallel-CPU vector engine runs a seven-operation chain over real building footprints at a near-flat features/sec from 100k to 1M, through immutable in-process handles with no per-stage file I/O, and that every number here was read from a server-side timing path.
What it does not claim
Any comparison to other software. No comparison to any external system is made or implied — the curve compares the engine only to itself across N.
Where it runs
This is the CPU vector surface: pure Java, parallel across worker threads, with no GPU dispatch in the chain at all. The profiler confirms it — zero bytes of video memory moved across the whole run.
The demonstration panel
The Building Stock panel shown throughout was built for this study to drive the chain interactively and read the timings back. It is a demonstration harness, not a shipping part of ForgeGIS Studio.

The curve

The official numbers come from a headless run — no server and no HTTP in the loop. The same chain through the live panel is shown alongside it, dimmed, carrying session overhead by design, so the gap between the two is on the record rather than hidden.

Features per second through the vector engine, 10k to 1M features Headless throughput rises from 107,730 features per second at 10,000 features to 253,212 at 100,000, then settles at 124,785 at one million — a 2.03 times spread across the top two tiers. The interactive panel run, carrying session overhead, tracks below it at 19,881, 56,117 and 63,857. The five million tier is memory-gated and not run. 0 100k 200k 300k 10k 100k 1M 5M 5M — memory-gated, not run gated 253,212 124,785 63,857 fixed per-op overhead at small N headless interactive panel features per tier (log scale) features / second
Headless: 107,730 → 253,212 → 124,785 features/sec. The flat right side — a 2.03× spread from 100k to 1M — is the claim. The dip at 10k is fixed per-operation overhead against too few features to amortise it, and is kept on the chart on purpose.

The same chain, live

Each tier also runs interactively through all nine stages. Every row shows the split this study stands on: engine milliseconds in bold, wall time including HTTP dimmed beside it, never blended.

Demonstration panel at the 10k tier: nine stage rows each showing engine milliseconds in bold with wall time in parentheses, totalling 503 ms engine and 19,881 features per second
10k — 503 ms engine, 655 ms wall, 19,881 f/s
The same panel at the 100k tier, the same nine stages, totalling 1.78 s engine and 56,117 features per second
100k — 1.78 s engine, 2.04 s wall, 56,117 f/s
The panel at the 1M tier, all nine stages complete, totalling 15.66 s engine and 63,857 features per second, with a three-point throughput curve below
1M — 15.66 s engine, 18.03 s wall, 63,857 f/s
Share of engine time by operation, at each tier At all three tiers the setback buffer and the points-in-polygons join together take roughly two thirds of engine time: 62.8 percent at 10,000 features, 74.7 percent at 100,000 and 68.1 percent at one million. The remaining five operations divide the rest, and the overall mix barely changes across two orders of magnitude. 10k503 ms engine total · buffer + join = 62.8% 100k1.78 s engine total · buffer + join = 74.7% 1M15.66 s engine total · buffer + join = 68.1% points → UTM reproject → UTM shape metrics setback buffer points-in-polygons join classify reproject → WGS84
Share of engine time per operation, by tier. The setback buffer and the points-in-polygons join dominate at every scale, and the shape of the mix barely moves across two orders of magnitude — which is what a near-flat throughput curve looks like from the inside.
A dark pipeline canvas holding a grid of connected operation nodes, each card showing a feature count and an elapsed time in milliseconds
The chain as canvas nodes, each carrying its own engine-time reading.

Handles, not files

Between every pair of stages the result stays in process as an immutable handle. Nothing is serialised, nothing is written to disk, and nothing is re-read. That is the whole reason the per-feature cost stays flat as N grows — there is no per-stage I/O term to grow with it.

Confirmed by the profiler

The CPU lane accounts for the full run and reports zero bytes of video memory moved. This chain never touches the GPU; the throughput above is what the parallel-CPU vector surface does on its own.

A flame-graph strip titled CPU vector lane, 14 operations, 2285 ms total, annotated with immutable in-process handles, no per-stage file I/O, and 0 B VRAM delta; the widest bars are BufferVectorOp at 634 ms and PointsInPolygonsJoinVectorOp at 696 ms
The CPU lane at 100k: the two widest bars are the buffer and the join.

On the map — two costs, never conflated

Past 150,000 features the map renders through a vector-tile route. Restyling and reclassifying look similar on screen and are completely different work, so the page separates them by request count rather than by adjective.

Ocean palette
The Houston block grid with building footprints filled in teal and dark green shades
Ember palette
The identical view and identical building shapes, repainted in oranges and browns

The restyle is free. Same tiles, same classes, repainted in the client — the request log recorded zero API calls across the click. The buildings did not change; only the paint did.

The same city view in the ember palette but with a visibly different distribution of colour across the buildings, more of them falling into the darker classes
After reclassifying on the server: the same footprints, redistributed across new class breaks.

The reclassify is engine work

Changing the class breaks recomputes the class code for every feature in the engine, mints a new immutable handle, and the map refetches tiles under a new URL. It took 2.58 s and it is labelled as engine work, because that is what it is.

Stale tiles are impossible

Because the new result is a new handle with a new tile URL, the cache flush is structural rather than a policy someone has to remember. There is no path by which the map can show tiles from a superseded classification.

The panel after both operations, showing a chip that reads 2.58 s engine recompute beneath the class-break field
The panel keeps the two costs on separate chips.
The ceiling, stated

Where the curve stops, and why

The 5M tier is memory-bound on this machine, and the system says so before reading a single byte. The 1M tier peaked at 7.9 GB of heap with intermediates freed as they were consumed; five layers of five million features do not fit in 12.9 GB. So the curve tops out at 1M and states the arithmetic instead of quietly ending. A scale curve that hides where it stops is a marketing curve.

SKIPPED tier 5m: predicted heap 45.4 GB >= 80% of max 12.9 GB (1M peak 7.9 GB). Pass --force to try anyway.

Two refusals guard two different quantities. The headless gate’s 45.4 GB is a measured extrapolation from this run’s 1M peak; the panel’s ~50 GB is a configured refusal floor set above the worst extrapolation seen across runs. The gate measures; the panel guards. A 10M tier was dropped at design time for the same reason.

The panel with the tier slider pushed to 5M, showing an amber message explaining that the tier needs about 50 GB of server heap while this server has 12.9 GB
The 5M attempt, refused before any features were read, with the arithmetic in the message.

Methodology

Every claim above traces to one of these.

Item Detail
Buildings Microsoft US Building Footprints, Texas — © Microsoft, released under the Open Database License (ODbL) 1.0. Multi-part geometries exploded at preparation; tiers are an exact first-N cap in file order.
Incident points Synthetic. Seeded, two per building at every tier — centroid plus roughly 60 m of jitter. They exist to exercise the join, not to describe Houston.
Projection Tiers stored in EPSG:4326; the chain reprojects to UTM 15N so buffers and areas are in metres, then back to WGS84 for display.
Engine time Per-operation elapsed time measured server-side around each call. Headless: one warmup, three measured, mean reported. Wall time including HTTP is reported separately and never blended in.
File ingest Excluded from engine totals and reported on its own row. Features/sec is features divided by engine total.
Hardware Intel Core 7 240H, 16 logical cores, 15.7 GB RAM. Server heap -Xmx12g (12.9 GB measured maximum), 15 worker threads. Results are specific to this stack.
Known limit The saved pipeline for this chain is a two-source graph, and the batch lane currently binds a single source — so the chain runs interactively but not in batch. That is the batch lane’s limitation, stated rather than worked around.

No comparison to any external system is made or implied. The curve compares the engine only to itself across N.

Want to see it against your data?

The per-operation timings behind every figure here, and the harness that produced them, are available to evaluators under NDA. Seaglass Foundry is happy to walk through the methodology or run the chain against a footprint set of your choosing.

rich@seaglassfoundry.com