How We Built a High‑Performance Elevation API with 30 m Resolution
This article details the end‑to‑end process of replacing low‑resolution SRTM data with 30‑meter ASTER elevation data, redesigning storage and access using JuiceFS, Go, and sync.Pool, and achieving sub‑millisecond latency for 1500 QPS in a Kubernetes environment.
Background and Motivation
彩云科技 needed higher‑resolution elevation data because hikers and off‑road users experienced noticeable gaps between the provided weather information and actual terrain, especially in mountainous and plateau regions.
Previous Elevation Data
Before 2024 the service relied on the SRTM dataset, stored as PNG files. After internal processing the spatial resolution was 5 km and vertical resolution about 35 m. The whole Chinese region could be loaded into memory, and data retrieval latency was in the nanosecond range, so it was not a bottleneck.
New Elevation Data Source
At the end of 2023 the team switched to the publicly available ASTER dataset, which provides 30 m spatial and 1 m vertical resolution in GeoTIFF format. Because the files are large, they were written to the JuiceFS distributed file system for convenient use inside Kubernetes.
Storage and Access Challenges
The GeoTIFF files were first converted to NumPy npy format to enable Python mmap reads. Two problems emerged:
The global dataset is about 500 GB, but the service mainly serves China, requiring only ~30 GB. In Kubernetes the service needed a disk mount to start.
Under high concurrency the Python + mmap approach could not meet the expected throughput.
Solution for Data Placement
JuiceFS was tried to store the whole dataset. Tests showed acceptable throughput at low traffic, but under heavy load the process blocked while waiting for file reads, causing the Python service to freeze. The team therefore kept the Chinese subset on local SSD (much lower latency than network I/O) and left the overseas high‑precision data on JuiceFS for the few customers that need it. An init container was added to download data incrementally, allowing the service to start quickly and reuse previously cached SSD files.
Solution for High‑Throughput Reads
The read logic was reimplemented in Go. The original 2‑D elevation matrix was flattened into a 1‑D int16 array and stored in a binary file. For a given latitude/longitude the code computes the file offset based on the spatial resolution and reads the value with os.File.ReadAt:
data := make([]byte, dataSize)
_, err = f.ReadAt(data, offset)
if err != nil {
return 0, err
}
value := binary.LittleEndian.Uint16(data)This approach dramatically reduced file‑I/O pressure.
Performance Profiling and Further Optimizations
Using Pyroscope, the team identified that most CPU time was spent in os.File.ReadAt and in grid‑point interpolation. Although io_uring (available since Linux 5.1) could accelerate asynchronous reads, it requires privileged mode on the current Kubernetes nodes and was therefore not adopted. Instead, the focus shifted to the interpolation step, where large slice allocations caused significant overhead. By reusing slices through sync.Pool, memory‑allocation cost was cut dramatically.
Current Service Characteristics
The service now runs with 1 CPU core and 0.5 GB memory, handling 1500 QPS. The 99th‑percentile latency is around 500 µs, which meets the product’s requirements.
Reliability Verification
To validate accuracy, the team compared elevation values from the new dataset with GPS tracks collected during a 2023 company trek to Yulong Snow Mountain. The differences were negligible, as shown in the accompanying screenshots.
Conclusion
Relying heavily on NumPy + mmap hid many performance issues that became apparent only after the data upgrade. Switching to Go, using SSD for the primary region, and applying slice pooling delivered comparable or better performance at lower operational cost. The authors note that because elevation data is a simple scalar per point, other languages such as Rust could also be used.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
