We investigated the most efficient way to perform global lat/lon-to-utility lookups for our 2,642 configured utilities. By moving from raw GeoJSON to a Compacted H3 Binary Index, we achieved a 95% reduction in memory usage and near-instant startup times across all environments (Python, Node, Bun, and Browser).
- Total Utilities: 2,643
- Spatial Coverage: 2,642 utilities (99.9%) have valid service area maps (
map.geojson). - Missing Data: Only
ai-utilitylacks a polygon. - Lookup Bottleneck: Loading 2,600+ GeoJSON files into memory is too slow for request-time lookups and consumes excessive RAM.
We generated a global index at H3 Resolution 6 (avg. edge length ~3km).
- Raw Index Size: 1.8 million cells.
- Compacted Index Size: 306,790 cells (By leveraging H3's hierarchy to merge 7 children into 1 parent cell where coverage is identical).
- Format: A custom 3.2MB
.binfile containing a JSON header and rawu64(H3 ID) /u16(Utility Set ID) parallel arrays.
| Strategy | Lookup Speed | RAM Overhead | Load Time | Best For |
|---|---|---|---|---|
| JSON Index (Hash) | ~550k / sec | 63 - 87 MB | ~100ms | High-speed server-side |
| SQLite (B-Tree) | ~130k / sec | ~3.0 MB | < 5ms | Shared/Local DBs |
| Binary (mmap) | ~77k / sec | ~3.0 MB | < 5ms | Python microservices |
| Node.js (TypedArray) | 600k / sec | ~6.0 MB | < 5ms | Node/Bun High-throughput |
| Rust / WASM | ~1M / sec | ~3.2 MB | < 5ms | Browser / Mobile / Edge |
- Memory Efficiency: The jump from JSON strings to raw binary integers (
u64) provided a 20x - 30x memory improvement. - GC Performance: By using Memory Mapping (
mmap) in Python or TypedArrays in JS, we moved the index data off-heap. This tells the Garbage Collector to ignore the 3MB index entirely, preventing GC pauses and "jank" in high-concurrency environments. - Cross-Platform Portability: We successfully implemented a Rust/WASM engine that performs lookups in ~1 microsecond using the same 3.2MB binary file. This allows us to use the exact same lookup logic in a React frontend, a Python backend, or a Node worker.
- File Format: Use the generated
utility_map.bin(3.2MB). - Client-Side: Use the WASM lookup engine.
- Server-Side: Use the Node.js TypedArray approach or Python mmap for zero-copy, shared-memory lookups across multiple worker processes.