Send us the source
Brief 01 What was hard 02 How it works 03 Numbers 04 Outcome 05 All cases → Send us the source

Atoms / Data extraction / Cases / DoorDash

Delivery — running since 2024

DoorDash — coverage means an address grid.

On a delivery platform nothing exists in the abstract. What you can see — which restaurants, which menu, which fees — depends entirely on the address you ask from. So coverage is not a list of URLs to walk; it is a geographic sampling problem, and the density of the grid is simultaneously the quality of the data and most of the cost. New merchants are found by the grid itself, within a day of opening.

The source is named because it is public; the client is not. Every figure on this page is a measured production number the client agreed to publish. Have a source of your own? Send it over, whatever its size — you get an answer within 24 hours.

Case filedoordashIn production
SourceDoorDash, national
ClientRestaurant pricing & market share
Running since2024
DeliveryBigQuery, daily
Grid46k address points
Merchants640k
Reach → Read → Reconcile → DeliverRecounted daily
26B

menu-item records since 2024

14B

a year

98.2%

measured coverage

640k

merchants tracked

SourceDoorDash
VerticalDelivery
Running since2024 — without a rebuild
The brief01 / 05

What the client actually needed.

Not more rows. Every one of these projects started with somebody who already had data and could not use it for the decision in front of them.

The problem

Where it started

The client sells pricing and market-share intelligence to restaurant groups, whose questions are about their own trade areas: what do comparable restaurants charge within delivery range of this location, what does the platform add on top, and how has that moved. Answering it requires seeing the platform the way a customer at that address sees it — which is the whole problem.

Fixed on day one

What we committed to

Merchants visible from the grid, against an independent recount98% floor
Menu-level prices and platform fees captured, not just merchant listingsEvery merchant
Trade areas resolvable at the level of a single restaurant's catchmentRequired
Grid dense enough to be complete and sparse enough to be affordableDesign input

Every one of these is measured continuously and reported on the same dashboard the client watches. A commitment nobody measures is a sentence in a proposal.

What was hard02 / 05

Four things that beat the previous attempt.

None of these is solved by better headers or a bigger proxy pool. Each needs a different piece of engineering, and working out which one you are actually facing is most of the job.

01 — GeographyGeography

Everything is bound to an address

There is no national view to collect. Each address sees its own set of merchants, its own delivery fees and sometimes its own prices, so a URL list is not merely incomplete — it does not exist.

What we doA grid of synthetic delivery addresses, with density derived from measured merchant overlap between neighbouring points rather than guessed. Dense where cities are dense, sparse where nothing changes.

02 — DensityDensity

The grid is the cost

Double the grid density and you roughly double the bill; halve it and you silently lose merchants at the edges of catchments. There is no safe default, and both errors are invisible from inside the data.

What we doDensity is tuned per market against a ground-truth sample: we measure what a denser grid would have found and stop tightening when the marginal point stops finding anything new.

03 — MenusMenus

The menu is not the listing

Merchant listings are cheap; menus, item modifiers, availability windows and per-item price variation are where the client's questions actually live, and they cost an order of magnitude more to collect.

What we doMenus are refreshed on a schedule driven by observed volatility per merchant, so the busy independents get frequent reads and the chains with stable national menus do not.

04 — FeesFees

The price a customer pays is assembled

Delivery fee, service fee, small-order fee and promotional discount are computed per address and per basket, so the headline item price is not what anybody actually pays.

What we doFee components are captured separately and stored alongside the item price, so the client can reconstruct the real cost to a customer at a given address rather than comparing menu prices that nobody is charged.

How it works03 / 05

Five decisions the pipeline is built on.

The architecture is not interesting; every extraction system has a queue, a fetcher and a parser. These are the decisions that made this one work where the last one did not.

01

Derive the grid, do not guess it

Grid density is set by measurement: for each market we test whether a denser grid finds merchants the current one misses, and tighten only where it does. This is the difference between a national sweep that is affordable and one that is not.

02

Refresh menus by volatility

A national chain's menu changes quarterly; an independent's changes weekly and its availability changes hourly. Refresh cadence follows the observed rate of change per merchant rather than a single global schedule.

03

Capture the fee stack separately

Delivery, service, small-order and promotional components are separate fields. Collapsing them into a total makes the data unusable for exactly the comparisons the client sells.

04

Resolve merchants across the grid

The same restaurant is seen from many grid points with different fees and sometimes different menus. Those observations are resolved to one merchant with the variation retained, not deduplicated into a single arbitrary reading.

05

Recount from outside the grid

Coverage is measured by sampling addresses that are not on the grid and checking whether what they see is already known. That number is the coverage figure, and it is the only honest way to state it.

The numbers04 / 05

What it does on an ordinary day.

Production figures, not a benchmark run. Coverage is recounted daily against an independent sample of the live source rather than asserted, which is why the numbers are not round.

Daily profile

Where the volume goes

Menu-item records a day38M
Requests a day1.6M
Merchants tracked640k
Menus refreshed a day260k
Off-grid recount discrepancy1.8%

A menu page returns the whole menu, so 260 000 menu refreshes plus 1.3 million grid queries — each of the 46 000 points swept across categories and pages — come to 1.6 million requests a day, nineteen a second, and yield 38 million item records: 1.1 billion a month, 14 billion a year, 26 billion since 2024. Refreshing all 640 000 menus daily rather than 260 000 would triple the bill and add nothing, because national chains do not change weekly and the tiering knows which ones do.

Headline

The four that are contractual

Collected since 2024
26B records
Coverage
98.2 %
Merchants
640k
Grid points
46k

These four sit in the support agreement. When one of them drifts outside its band, we are alerted within fifteen minutes and fixing it is routine work under the monthly arrangement, not a change request.

What changed05 / 05

Before, and after.

The columns are the client's own numbers from before the rebuild and the measured ones from production today. The left column is the part most vendors would rather not put on a page.

MetricBeforeToday

Coverage basis

A list of known merchants

A measured 46k-point address grid

Price comparability

Menu price only

Menu price plus the full fee stack

Trade-area questions

Answerable at city level

Answerable per restaurant catchment

New merchants

Added when somebody noticed

Discovered by the grid within a day

Restaurant groups had been comparing menu prices, which nobody pays. Splitting the fee stack out changed what the product could credibly claim.

Start here

Have a source of your own? Two lines are enough.

Send the source, the fields you need and roughly how often. You get a straight answer within 24 hours: whether it can be done, what makes it hard, what coverage is achievable and roughly what it costs to build and to run. Whatever the size.

Direct

NDA before technical detail, as always. If it isn't our kind of work, we say so in the first reply.