Skip to content
MSP
Animation of a person on a map whose saved-place pin drifts away with the old map layer and is replaced by a new pin on the new map
  • Geospatial Data Engineering
  • problem-solving
  • solution-design
  • geo-tech

The Hidden Data Dependencies a Map Migration Exposes

Mahardi Setyoso Pratomo6 min readEnglish

When Indonesia moved to GrabMaps, saved places broke before the map did. What a city-by-city map migration taught me about hidden data dependencies.

What breaks first when a map is replaced?

Not the map. When Indonesia moved onto GrabMaps in 2022, the last of Grab's markets to switch, many early complaints were not about wrong roads or missing malls. They were about places people had saved: a home, an office, a regular customer's address. The new map was live, and some of those saved places pointed at nothing.

That is the lesson of this article. A map is not one dataset you swap out. Everything that points at it has to move too, and some of those pointers belong to users.

How did the migration roll out?

The switch went city by city instead of all at once. Tier-3 cities moved first, then the large ones: Jakarta, Bandung, Medan and the rest of tier 1. Smaller cities meant fewer users exposed to any problem, and every wave produced real feedback before the cities where most bookings happen.

Migration waves from tier-3 cities to tier-1 cities, with feedback from each wave flowing back before the next wave startsOpen full size
Figure 1. City-by-city rollout: each wave's feedback shaped the next one.

My part sat in that feedback loop. I handled the map tickets coming in from each wave, and my team watched guardrail metrics with city operations: if map usage in a city fell below the floor we had agreed, or cancellations rose, we investigated with the city team before the next wave went out. Routing was a separate, later step. It moved over once the navigation app for drivers was ready, so this phase was about places, not routes.

Why did saved places stop working?

Saved places were stored as references to the previous provider's places. Our first guess was simple: find the equivalent place in our own POI data and point the saved place there. That worked for popular places. It failed for many of the places that mattered most to each user.

The clearest case came from GrabExpress. Sellers had saved their regular customers' delivery points in the app, and these were exactly the places a coverage metric never looks at: a house in a residential lane, a small shop, a side entrance. Popular places were already on our map. Personal places often were not.

So this was not a coverage problem we could fix by mapping more malls. It was a dependency problem: user data had been built on top of another provider's IDs, and there was no inventory of it before the cutover.

Animation: saved places near a mall, station and hospital find a nearby POI and are repointed; those at a house in a lane, a small shop and a side entrance find nothingOpen full size
Figure 2. Popular places found a match. The personal ones had nothing to match.

How do you migrate places that users saved themselves?

Engineers pulled the affected saved places. What came back was thin: a latitude and longitude for each point, with no name and no address. I coordinated with the GrabExpress business team to escalate the impact to engineering and product, then cross-checked the points against our internal POIs and added the ones that were missing.

Matching on coordinates alone is harder than it sounds. The diagram below shows the decision for each saved place.

Saved-place matching flow: each coordinate is compared with nearby internal POIs; one match is repointed, several candidates go to a human check, no candidate is added to the mapOpen full size
Figure 3. Three outcomes for every saved place: repoint, check, or add.
  1. One internal POI close by: treat it as a match and repoint the saved place.
  2. Several POIs close by: a mall, an apartment tower, a row of shops. Coordinates alone can't tell which one the user meant, so these need a human check.
  3. Nothing close by: the place is missing from our map. Add it, then repoint.
-- Simplified illustration of the matching logic (not production code)
with nearby as (
  select s.saved_place_id,
         p.poi_id
  from saved_places s
  left join internal_pois p
    on st_dwithin(s.geom::geography, p.geom::geography, 30)  -- small radius, in metres
)
select saved_place_id,
       count(poi_id) as candidates,
       case
         when count(poi_id) = 0 then 'missing: add to map'
         when count(poi_id) = 1 then 'match: repoint'
         else 'ambiguous: human check'
       end as action
from nearby
group by saved_place_id;

The trade-off was precision against speed. Repointing every saved place to its nearest POI would have looked finished sooner, but a saved place that quietly points to the wrong building is worse than one that is missing. A user notices a missing place and saves it again. A wrong one sends a courier to the wrong door. Clear matches could move quickly; the rest needed checking.

How do you make map feedback actionable at scale?

Tickets were the other bottleneck. A user reported a problem to a customer service agent, and the map support team received the whole conversation. Reading a long back-and-forth just to find which place, where, and what was wrong took most of the handling time.

I introduced two templates: a request form on the agent side and a response template on the map support side. The agent turned the conversation into a structured report, and the map team answered in a fixed format the agent could pass back to the user.

Before After
What map support received The full agent–user conversation A short structured form
Information captured Whatever the user happened to mention Problem, POI name needed, latitude/longitude, address
First step on each ticket Read the conversation to find the problem Go straight to the location
Reply to the agent Free text, written from scratch A response template the agent can reuse

Together with automated ticket extraction, the templates raised throughput from about 12 to 25–30 tickets resolved per day. They also had a quieter benefit: structured tickets could be grouped by problem type, so a cluster of similar complaints showed up as a pattern early, before it could turn into a public complaint.

How did we know the new map was good enough?

No single metric decided it. We looked for three signals.

  1. Critical places were covered. Malls, stations, airports and hospitals had to be complete, because that is where a missing pickup point hurts most.
  2. The type of feedback changed. Early tickets said "my saved place disappeared". Over time they became "this one place isn't on the map yet": normal map maintenance, not migration damage.
  3. The whole trip worked. The map displayed, places could be selected, the booking went through, and the driver met the passenger at the chosen point and dropped them at the right destination, even when the route differed from before.

The second signal is the one I'd watch first next time. A shift in what people complain about tells you more than the number of complaints.

What would I check first on the next migration?

Every data migration has its own version of the saved-places problem: records that other systems, or users, built on top of the old IDs. A CRM switch has saved customer filters, a catalogue change has customers' wish lists, a warehouse migration has dashboards nobody listed.

  • Inventory the references before the cutover. Ask what points at the old IDs, not only what the old system contains.
  • Expect the long tail to be personal. The places users care about most are rarely the places your coverage metric counts.
  • Prefer a missing record over a wrong one. Automate the clear matches and route the ambiguous ones to people.
  • Structure feedback before you scale it. A form that captures location and problem type turns complaints into data you can group.
  • Roll out where mistakes are cheapest first. Smaller cities taught us the lessons before Jakarta could.

The next article in this series moves from points to polygons: how small gaps between service boundaries became areas with no service at all.

FAQ

Why not migrate all cities at once?

A gradual rollout limits how many users a problem reaches and gives each wave's feedback time to shape the next. The cost is a longer period of running the old and new setup side by side.

Can you match places using coordinates only?

Partly. A single nearby candidate is usually safe. Several candidates within a few metres, such as tenants in one mall, need a name, an address or a human check.

What is a guardrail metric in a migration?

A metric that must not fall while the change rolls out, such as map usage or cancellations in a city. If it drops, you find the cause before the rollout continues.

References

Last updated: 17 November 2026.