The problem: You want to know which businesses in a market just opened, which just closed, which moved, and which rebranded. So you run a Google Maps scraper, get a few thousand rows, and stare at them looking for the openings and closures. They're not there. They can't be. A scrape is a single photograph, and you cannot spot change in one photograph, there's nothing behind it to compare against. The signal you actually want lives in the difference between two captures of the same market, and a scrape gives you neither the second capture nor a reliable way to line the two up.
I publish actors on the Apify Store as ryanclinton, including ones in the local business data space, so this isn't a pitch against scraping. Scraping a map is fine for "what's near me right now." But "track openings and closures" is a fundamentally different request, and almost every tutorial answering it quietly assumes a problem you don't actually have solved: that you can tell whether the row you saw in March is the same real-world business as the row you see in June. Without that, change tracking is impossible, and a raw scrape can't give it to you.
If your problem is already "I need a feed of openings, closures, moves, and rebrands across a territory," that's the job the Business Data Enricher actor's territory/event mode was built for, but read on for why change tracking is a category, not a script you write over a weekend.
What is business change tracking? Business change tracking is the practice of detecting openings, closures, relocations, and rebrands by capturing the same places, identified the same way, at two or more points in time and surfacing what changed between them.
Why it matters: Local business data decays roughly 20-30% per year as businesses move, close, rebrand, or change hands. The openings and closures inside that churn are the highest-value signal in local data, and a one-time snapshot is blind to all of it.
Use it when: You're monitoring a territory for new entrants, tracking competitor closures, watching a franchise or brand expand or contract, or maintaining any place dataset where "what changed" matters more than "what exists right now."
Also known as: tracking business openings · monitoring store closures · POI lifecycle tracking · local business change detection · new-business and closure feed · territory change monitoring.
Quick answer
- What it is: detecting openings, closures, moves, and rebrands by differencing two stable-identity captures of the same market over time.
- When you need it: territory monitoring, competitor watch, franchise/brand expansion tracking, keeping a place dataset current.
- When you don't: one-off "what's here right now" lookups where you'll never re-check the same area.
- Why a scrape can't do it: a single snapshot has nothing to compare against, and scraped listings have no stable identity to line two captures up by.
- Main tradeoff: a change feed costs more to run than a one-time scrape, but it produces typed events (new, closed, moved, rebranded) a scrape structurally cannot.
In this article: What it is · Why change is the signal · The identity problem · Alternatives · Best practices · Mistakes · FAQ
Key takeaways
- A single scrape cannot surface openings or closures because change is a property of the difference between two captures, and a snapshot is one capture (the underlying decay problem is well documented).
- Differencing two captures only works if each place carries a stable identity across both, Google's
place_idis explicitly documented as subject to change, so it's an unreliable join key over time. - Local business data decays at roughly 20-30% per year, and the openings, closures, moves, and rebrands inside that churn are the events most teams actually want to act on.
- Open place datasets like Overture Maps ship persistent identifiers (GERS) and a CDLA Permissive 2.0 license, which is the legal posture you need to build a change feed you can keep and reuse.
- A typed change feed emits discrete events,
opened,closed,moved,rebranded, brandexpanded/contracted, instead of leaving you to eyeball two spreadsheets side by side.
Snapshot vs change feed, in concrete terms
| You want to know | What a single Maps scrape gives you | What change tracking gives you |
|---|---|---|
| Which businesses opened this quarter | A list with no "before" to compare against | A typed opened event per new location |
| Which competitors closed | No way to tell a closure from a row that just didn't match this run | A closed event keyed to a stable ID |
| Which businesses moved | A new address with no link to the old one | A moved event linking old and new location |
| Which rebranded | A different name that looks like a brand-new business | A rebranded event preserving the identity |
| Whether a chain is expanding | Two unlinked snapshots you'd diff by hand | expanded/contracted events across the brand |
What is business change tracking, and why can't a scrape do it?
Definition (short version): Business change tracking is detecting openings, closures, relocations, and rebrands by capturing the same places, identified the same way, at two or more points in time and differencing the captures into typed change events.
A scrape answers "what's here right now." Change tracking answers "what's different since last time." Those are not the same question, and you cannot derive the second from a single answer to the first. To see that a business opened, you need a capture where it was absent and a later one where it's present. To see that one closed, you need it present then absent. A snapshot has no "then." It is, by definition, one moment.
There are broadly three things a change-tracking system has to do that a scrape doesn't. It has to capture the same scope twice (same places, not just whatever the search happened to return that day). It has to give every place a stable identity that survives between captures. And it has to difference the two into events you can act on. A raw scrape does none of these, which is why "I scraped the city twice" doesn't get you a closure feed, it gets you two unaligned lists and a manual reconciliation problem.
Why are openings and closures the highest-value signal in local data?
Openings and closures are the highest-value signal in local business data because they're the moments when money, market share, and intent change hands. A new opening is a fresh prospect, a new competitor, or a sign a market is heating up. A closure is a freed-up customer base, a vendor displacement opportunity, or a risk flag. Static "this place exists" data is commodity; the events are where decisions get made.
Think about who actually pays for this. SDR and sales teams want new entrants the day they appear, before every other team's monthly export catches them. Competitive-intelligence teams want competitor closures and relocations. Franchise and PE scouts want to watch a brand expand or contract across a region. Commercial real estate, suppliers, and local-services platforms all run on the same currency: not the snapshot, the change. And every one of those use cases is invisible in a row of name-plus-phone-plus-rating scraped once.
This is the same argument the pillar makes in Google Maps Scraping Isn't a Data Strategy: a scrape is a tactic, not a foundation. Change tracking is one of the clearest places that distinction bites, because the entire value is in the dimension a snapshot doesn't have, time.
Why stable identity is the whole ballgame
You can't track change across two captures unless you can tell, for every place, whether the row in capture B is the same real-world business as a row in capture A. That matching problem is the whole ballgame. Get it wrong and a business that simply didn't match this run looks like a closure; a business that moved looks like one closure plus one opening; a rebrand looks like a death and a birth.
Here's the trap with scraped Google Maps data. Google's place_id is documented as subject to change, search ordering shifts run to run, and Maps scrapers cap at roughly 500 results per query, so the "same" query can return a different slice of the market each time. There's no durable join key. You're left matching on name and address strings, which break the moment a business does the exact things you're trying to detect, moves (address changes) or rebrands (name changes).
Persistent identifiers solve this. Overture Maps assigns each place a GERS ID designed to stay stable as the underlying record updates, so the same place keeps the same key across captures. That's the difference between "these two lists overlap somehow" and "this exact place was open in March and closed in June." Stable identity is what turns two snapshots into a change feed instead of a reconciliation headache.
How a change feed produces typed events
A change feed works by holding resolved, stably-identified records of a defined territory and surfacing what's different when the same territory is captured again. Instead of handing you two spreadsheets to diff, it emits discrete, typed events, one per change, so a downstream system can route them without a human eyeballing rows.
The events are the product. A new location that wasn't there before becomes an opened event. A place that was present and is now gone becomes closed. A place whose location changed becomes moved, with the old and new linked so it doesn't read as a death-and-birth. A name or branding change becomes rebranded, preserving the identity underneath. And rolled up across a brand, the feed shows expanded and contracted, a chain adding or shedding locations across a region.
Those events trace the lifecycle of a single place over time:
Opened
↓
Operating
↓
Moved / Rebranded (identity preserved through the change)
↓
Closed
Here's the shape of what a typed change feed emits, as output (not a recipe, this is what you get back, not how it's built):
{
"events": [
{
"type": "opened",
"placeId": "gers:08f2a9d4c1b3...",
"name": "Harbour Roasters",
"category": "cafe",
"location": { "lat": 53.4084, "lon": -2.9916 },
"detectedBetween": ["2026-03-01", "2026-06-01"]
},
{
"type": "closed",
"placeId": "gers:08f2a9d4c1aa...",
"name": "The Old Mill Bakery",
"lastSeen": "2026-03-01",
"detectedBetween": ["2026-03-01", "2026-06-01"]
},
{
"type": "rebranded",
"placeId": "gers:08f2a9d4c19f...",
"from": "Citywide Print & Copy",
"to": "Citywide Studio",
"detectedBetween": ["2026-03-01", "2026-06-01"]
}
]
}
The point of showing the output and not the method: each event already carries a stable placeId, so it joins back to your CRM or territory map on a key that survives the next capture. That's the part you can't reconstruct by hand from two scrapes.
Rolled up across a brand, the same feed emits expansion and contraction, the signal a franchise scout or PE analyst reads first:
{
"type": "expanded",
"brand": "Costa Coffee",
"territory": "Liverpool",
"netNewLocations": 4,
"detectedBetween": ["2026-03-01", "2026-06-01"]
}
What are the alternatives for tracking business openings and closures?
There are a few honest ways to approach this, and they trade off on cost, identity, and how much you end up owning. None of the DIY routes are wrong, they just inherit work that a resolved change feed has already absorbed.
-
Diffing two raw scrapes yourself. Scrape the market in March, scrape it again in June, line the two up. This is the obvious instinct, and it's where most people start. The problem is the alignment: with shifting place IDs and run-to-run ordering changes, you own the entire identity-matching problem, name/address fuzzy matching, move-vs-close disambiguation, rebrand detection, and the false closures that come from a row simply not appearing this run. Best for: nobody at scale; it's a science-fair version of the real thing.
-
Government and registry filings. Business registries, licensing boards, and bankruptcy records do record some openings and closures. They're authoritative where they exist. But coverage is patchy, latency is high (a registry update can lag a real closure by months), formats differ by jurisdiction, and a storefront closing rarely files anything at all. Best for: regulated formal entities, not the long tail of local businesses.
-
Commercial data vendors. Firms like Dun & Bradstreet and large local-data providers sell business-status data with some change signal. It's real, and for enterprise budgets it's a fine answer. The trade-offs are price, opaque update cadence, licensing limits on what you can redistribute, and you don't control the territory or refresh schedule. Best for: enterprises that want a vendor relationship, not a runnable feed.
-
A resolved change feed on open data. Hold canonical, stably-identified records of a territory and emit typed events when the same territory is captured again, built on a resale-permissive open dataset. This is the Business Data Enricher actor's territory/event mode: openings, closures, moves, rebrands, and brand expansion/contraction over Overture Maps under CDLA Permissive 2.0. Best for: teams that want the events as data they can route and reuse, without owning the identity-matching machinery.
Each approach trades off on cost, coverage, latency, identity stability, and licensing. The right choice depends on your budget, how much of the long tail you need, and whether you want to own the matching logic or consume events. For most teams tracking a defined territory continuously, the resolved feed is one of the best fits because it removes the part that breaks, identity.
| Approach | Catches the long tail? | Stable identity across captures | Resale-safe license | You own the matching logic |
|---|---|---|---|---|
| Diff two raw scrapes | Partially (capped per query) | No (shifting IDs) | No | Yes, all of it |
| Registry / gov filings | Formal entities only | Varies by jurisdiction | Usually yes | Some |
| Commercial vendor | Broad | Vendor-internal | Restricted | No |
| Resolved change feed (Overture) | Yes | Yes (GERS) | Yes (CDLA 2.0) | No |
Pricing and features based on publicly available information as of June 2026 and may change.
Best practices for tracking business change
- Define the territory before you define the query. Change tracking needs a fixed scope you re-capture, not a search that drifts. Pin the geography and category set so capture B covers the same ground as capture A.
- Join on a persistent identifier, never on name or address. Those are the two fields that change when a business moves or rebrands, the exact events you're trying to detect.
- Pick a re-capture cadence that matches the decay rate. At 20-30% annual churn, monthly or quarterly captures surface meaningful change; daily mostly surfaces noise.
- Treat a non-match as "unknown," not "closed," until confirmed. A row that didn't appear this run isn't necessarily gone. Conflating the two is the single biggest source of false closures.
- Keep moves and rebrands as their own event types. Folding them into open/close double-counts and corrupts your churn math.
- Build on a resale-permissive dataset if you'll keep the feed. A scrape you can't legally retain isn't a foundation for an ongoing feed. Overture under CDLA 2.0 is built for this.
- Route events, don't store them in a sheet. The value of a typed event is that a system can act on it, send the opening to the SDR queue, flag the closure to CI, without a human reading rows.
Common mistakes when tracking openings and closures
- Diffing two scrapes by name and address. This breaks on exactly the events you care about. A move changes the address; a rebrand changes the name. You'll log them as closures-plus-openings and never see the real story.
- Trusting
place_idas a stable key. It's documented as subject to change. Build a join on it and your March-to-June match silently rots. - Reading a non-match as a closure. Because a scrape returns only a shifting slice of the market run to run, a business can simply fall out of this run's results. Treating that as a closure inflates your churn and burns your CI team's trust.
- Capturing different scopes each run. If capture B's query returns a different area than A's, every edge difference looks like change. Lock the territory.
- Ignoring licensing until you've shipped. Tracking openings/closures implies you're keeping and reusing data over time. Scraped Google content is bound by the Maps Platform Terms; a retained, reused feed needs a license that permits exactly that.
A concrete before/after
Before: A franchise-development team wanted to know where a competing coffee chain was expanding across the North West. Their analyst scraped Google Maps for "coffee" in the region every month, dumped each run into a tab, and tried to spot new locations by eye. Three problems showed up fast: the 500-cap meant each run returned a different subset, so "new" rows were often just rows that fell out last month; rebrands of existing cafés looked like brand-new competitors; and a relocated branch showed up as one closure and one opening 400 metres away. The team stopped trusting the analysis after two months.
After: The same territory, captured as resolved, GERS-identified records and differenced into typed events. New competitor locations came through as opened events with stable IDs that joined straight to the dev pipeline. A rebrand stayed one identity instead of reading as churn. The relocated branch came through as a single moved event linking old and new. The analyst went from a day a month of manual reconciliation to reviewing a feed of discrete events, and the closure count finally matched reality instead of the scrape's blind spots.
These numbers reflect one team's workflow on one region. Results vary with territory size, category, capture cadence, and how much manual reconciliation you were doing before.
Implementation checklist
- Define the territory: fixed geography plus category set you'll re-capture identically.
- Choose a place source with persistent identifiers and a resale-permissive license (e.g. Overture Maps).
- Resolve your scope into canonical, stably-identified records, the baseline capture.
- Set a re-capture cadence matched to the churn rate (monthly/quarterly for most local markets).
- Difference each new capture against the baseline into typed events, not by hand, via a feed that emits
opened/closed/moved/rebranded. - Route events to where decisions happen: openings to sales, closures to CI, brand expansion to scouting.
- Confirm ambiguous non-matches before calling them closures.
For teams that don't want to own steps 3 and 5, the Business Data Enricher actor's territory/event mode handles the resolution and the differencing, and emits the typed feed directly. ApifyForge tracks it on the Google Maps scraper comparison alongside extraction-only tools so you can see where the line sits.
Limitations
- A change feed costs more to run than a one-time scrape. You're capturing a territory repeatedly and resolving it each time. For a single disposable lookup, that's overkill, a scrape is the right tool.
- Detection latency is bounded by capture cadence. If you re-capture quarterly, an opening that happens the day after a capture won't surface for up to three months. Tighter cadence costs more.
- Open place data isn't omniscient. Overture is broad and improving, but the very newest openings and the smallest informal businesses can lag. No source catches every change the instant it happens.
- Some events are inherently ambiguous. A business that goes dark could be closed, seasonal, or temporarily delisted. A good feed flags these rather than guessing, which means some events need human confirmation.
- It answers "what changed," not "why." The feed tells you a competitor closed; it doesn't tell you whether it was bankruptcy, a lease dispute, or a relocation you haven't captured yet. That context is a separate enrichment job.
Key facts about business change tracking
- Change is a property of the difference between two captures; a single snapshot cannot contain it.
- Tracking requires the same scope captured at two points in time and a stable identity to align them.
- Google's
place_idis documented as subject to change, making it an unreliable join key across captures. - Local business data decays at roughly 20-30% per year; openings and closures are the highest-value events inside that churn.
- Overture Maps provides persistent GERS identifiers and a CDLA Permissive 2.0 license suited to a retained, reusable feed.
- A typed change feed emits discrete
opened,closed,moved,rebranded, and brandexpanded/contractedevents rather than two spreadsheets to diff.
Glossary
- Change feed, a stream of typed events describing what changed between two captures of the same territory.
- Persistent identifier, a key (like Overture's GERS ID) designed to stay stable as a place's record updates, so the same place is recognisable across captures.
- Entity resolution, matching a listing to a canonical ground-truth record so two captures can be aligned by identity rather than by name/address strings.
- Territory, a fixed geography plus category scope you re-capture identically over time.
- Churn / decay, the rate at which place records go stale as businesses move, close, rebrand, or change hands.
- Typed event, a single, machine-routable change record (
opened,closed,moved,rebranded) rather than a raw row.
Where these patterns apply beyond local business data
The structure here isn't specific to cafés and storefronts. Any time you want to track change in a real-world dataset, the same principles hold:
- Change lives in the difference, not the snapshot, true for prices, job postings, product catalogues, and regulatory filings as much as for businesses.
- Stable identity is the prerequisite for differencing, without a durable key, you can't tell "changed" from "different record."
- Non-match isn't deletion, in any change feed, a missing row needs confirmation before it's read as a removal.
- Scope must be held constant, comparing two differently-scoped captures manufactures fake change.
- Licensing determines whether a feed is keepable, a snapshot you can't retain can't become a longitudinal feed.
When you need this
You probably need business change tracking if:
- You monitor a territory or market on a recurring basis.
- You want new openings as fresh prospects before competitors catch them.
- You track competitor closures, relocations, or rebrands.
- You're watching a brand or franchise expand or contract across a region.
- You maintain a place dataset that has to stay current, not just exist once.
You probably don't need this if:
- You only need a one-off "what's near here right now" lookup.
- You'll never re-check the same area.
- The list is disposable and you don't care what changes after today.
Frequently asked questions
Can I track business closures with a Google Maps scraper?
Not from a single scrape, a snapshot has no "before" to compare against, so a closure is invisible. You'd need two captures of the same market over time plus a stable way to match places between them. Scraped data lacks a durable join key (place_id is subject to change), so even two scrapes don't reliably align into a closure signal.
How do I know if a business actually closed or just didn't show up in my scrape?
That's the core trap. Google Maps scrapers cap at roughly 500 results per query and reorder run to run, so a business can fall out of a run's slice without closing. The only reliable way to tell is stable-identity capture: if a place with a persistent ID is present in one capture and absent in the next, that's a real signal, a string that didn't match is not.
What's the difference between a scrape and a change feed?
A scrape is one capture of what exists now. A change feed holds stably-identified records of a territory and emits typed events, opened, closed, moved, rebranded, when the same territory is re-captured. The scrape answers "what's here"; the feed answers "what changed." You cannot derive the second from a single instance of the first.
Why can't I just diff two spreadsheets?
Because the rows don't carry a stable identity, so you can't reliably tell which row in sheet B is the same business as a row in sheet A. The events you most want to detect, moves and rebrands, are exactly the ones that change the name and address you'd be matching on. You'd log them as false closures and false openings.
Is Overture Maps data legal to build a tracking product on?
Overture Maps data is released under CDLA Permissive 2.0, a license built for redistribution and product-building. That's the opposite posture to scraped Google content, which is bound by the Maps Platform Terms restricting caching and resale. For a feed you keep and reuse over time, the licensing matters as much as the data.
How often should I re-capture a territory to catch openings and closures?
Match the cadence to the decay rate. Local business data churns at roughly 20-30% per year, so monthly or quarterly captures surface meaningful change without drowning you in noise. Daily re-capture mostly adds cost and false signal. Tighter cadence lowers detection latency but raises the run cost, so pick based on how time-sensitive your openings and closures actually are.
Ryan Clinton publishes Apify actors and MCP servers as ryanclinton and builds developer tools at ApifyForge.
Last updated: June 2026
This guide focuses on Google Maps and Overture place data, but the same change-tracking patterns, stable identity, held scope, difference-not-snapshot, apply broadly to any real-world dataset you need to keep current.