Making getting to results fast: Map Intelligence
How NeighbourFit made Map Intelligence faster by moving slow work out of the postcode lookup path, with measured before-and-after results.
What this page answers
Map Intelligence got faster by removing Police.uk from the main lookup path, caching postcode enrichment and geography footprints, and decoupling the lookup counter write. In a local production benchmark, first-pass lookup median improved from 43.4ms to 15.5ms, while repeat same-postcode median improved from 26.7ms to 4.8ms.

The short version
A postcode lookup should not feel like it has gone away to think about its life choices.
Map Intelligence has one job at the start: take a postcode and get the renter to the useful read quickly. Crime/ASB context, map footprints, counters and repeat enrichment are useful. They are not all allowed to sit in the doorway before the first result appears.
- First-pass lookup average: 59.6ms before, 24.8ms after.
- First-pass lookup median: 43.4ms before, 15.5ms after.
- Repeat same-postcode average: 42.5ms before, 5.0ms after.
- Repeat same-postcode p95: 78.0ms before, 6.2ms after.
First-pass lookup response time
Lower is better. Local production benchmark using the same copied SQLite data snapshot.
The conservative result: first-pass median was 64.3% faster. The angry-external-API result is bigger, because Police.uk no longer blocks the postcode read at all.
Repeat checks stopped doing the same work for sport
If someone checks the same postcode twice, the second read should not rebuild the same enrichment like it has never seen the address before. Cute. Wasteful.
The new path caches normalized postcode enrichment and geography footprints for a short window. B1 2AF, b12af and B1 2AF with a trailing space now hit the same cache key.
Repeat same-postcode response time
Same postcode repeated eight times against the production build. Lower is better.
Repeat same-postcode p95 moved from 78.0ms to 6.2ms. That is 92.1% faster. The cache did its job and did not ask for applause.
Police.uk moved out of the request path
Before, a successful postcode lookup with latitude and longitude could wait on the Police.uk street-level crime endpoint. The old timeout was 5 seconds. If that external service had a moment, the whole postcode read had a moment.
Now the main lookup returns first. Crime/ASB context loads separately through GET /api/area-data/crime-context with a rounded lat/lng plus month cache key, a 24 hour successful-result cache and a shorter external timeout around 1.2 seconds.
- The postcode read no longer waits on Police.uk.
- Crime/ASB context has its own loading/unavailable state.
- The UI says the data is still loading separately. It does not joke about crime itself.
Footprints stopped being redrawn like artisanal nonsense
The map footprint builder can inspect thousands of postcode rows for an LSOA, outward code or geography target and build a hull. Nice visual. Bad habit when repeated every lookup.
The speed pass added an in-memory TTL cache for footprint results and in-flight promises. Concurrent requests do not all decide to become cartographers at once.
- Cache by lsoaCode where available.
- Fall back to nationSpecificCode or postcodeOutward.
- No schema migration. No Redis. Just the right-sized fix.
The lookup counter stopped riding shotgun
The lookup counter is useful for the product. It is not useful enough to make the renter wait for a SQLite write before seeing the read.
The increment now runs after the response path is no longer blocked. The client refreshes /api/area-data/lookup-count after success. No fake optimistic +1, no scoreboard accountant holding the door.
Benchmark method
I compared the previous production build against the speed-pass build using local production builds, a copied SQLite benchmark database and the same postcode set.
Every measured lookup URL included a benchmark nonce to avoid URL-level response caching while leaving the new postcode/geography application caches eligible. The readiness probe was /api/area-data/lookup-count, not a lookup warmup.
- Before: previous production build before the speed pass.
- After: speed-pass build with lazy crime context, enrichment caching and counter decoupling.
- Postcodes: B1 2AF, CO4 3UN, W1A 1AA, CB2 1TN, BS1 4TR, M1 1AE, SW1A 1AA and E1 6AN.
- No database reset, import or bootstrap scripts were run.
Verdict
Map Intelligence now gets to the first useful answer faster.
Not because the UI pretends to be fast. Because the backend stopped making one request do four jobs before answering. One postcode. First read first. Evidence after. Fewer red flags in the plumbing.