Performance Analysis of /search and /reverse on macOS #4008
div-dev123
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
1. Setup Issues on macOS (Apple Silicon)
The README covers installation steps well, but macOS (especially Apple Silicon / ARM64) has a few pitfalls that will affect mac users
1.1 ICU4C is keg-only on Homebrew
Nominatim depends on
pyicu, which requires the ICU library headers. On macOS with Homebrew, ICU (icu4c) is installed as keg-only (not symlinked into/opt/homebrew/), sopip installof the Nominatim packages fails with:Fix — Export the pkg-config path before installing:
1.2 PostGIS availability is tied to a specific PostgreSQL major version
Homebrew's PostGIS formula only builds against one or two PostgreSQL major versions at a time. At the time of writing,
postgisis built for PostgreSQL 17 and 18. If you have PostgreSQL 15 or 16 from an older install,CREATE EXTENSION postgiswill fail with:Fix — Install the matching PostgreSQL version:
1.3 The
www-dataPostgreSQL role doesn't exist on macOSThe Nominatim import expects a
www-dataPostgreSQL user (common on Linux where the web server runs aswww-data). On macOS this user doesn't exist, causing:Fix:
1.4
wgetis not available by defaultThe README examples use
wgetto download OSM data extracts. macOS does not ship withwget.Fix — Use
curlinstead:or use Brew install wget
2. Profiling Approach
Instead of just timing HTTP responses manually, I built a small profiling setup with two layers.
A. Internal Profiling (cProfile)
cProfileThis helps identify whether time is spent in:
B. HTTP-Level Benchmarking
/searchand/reverserequestsThis reflects real-world API performance.
3. Query Generation
To avoid hardcoded test queries, I added a small script that:
placexThis makes testing:
4. Profiling Results
4.1 Monaco (Small Dataset — 2.3MB PBF)
Import time: ~16 seconds
Database size: ~5,700 indexed places
Queries: 30 search + 20 reverse, 1 repetition (library), 1 repetition (HTTP)
Library Profiling
HTTP Profiling (first run — cold caches)
Key Observations — Monaco
yaml.safe_loadto parseicu_tokenizer.yamlwhich includes 31+ sub-files. This single operation accounts for ~510ms of cumulative time — it happens once but dominates the first-query latency.4.2 North-Eastern India (Medium Dataset — 96MB PBF)
Import time: ~4.3 minutes (259 seconds)
Database size: ~270,000 indexed places (18M nodes, 2M ways, 3.9K relations)
Queries: 50 search + 30 reverse, 3 repetitions each
Coverage: 8 states — Assam, Arunachal Pradesh, Manipur, Meghalaya, Mizoram, Nagaland, Sikkim, Tripura
Library Profiling
HTTP Profiling (warm server)
Key Observations — North-Eastern India
4.3 Comparison: Monaco vs North-Eastern India (warm, steady-state)
The larger dataset appears faster in steady-state because:
5. Top Performance Bottlenecks Identified (cProfile)
Looking at the cProfile output for both datasets, the same functions show up at the top each time:
kqueue.control/selectors.selectyaml.safe_load→compose_nodeplace_search.lookupreverse.lookup_countryreverse._find_closest_street_or_poisicu_tokenizer.analyze_querygeocoder.build_searchesgreenlet.switch6. Screenshots from Implementation
AI Usage: Used for generating a structured .md report and to understand the requirements and some errors that popped along the way
All reactions