Migration

Comparing batch and bulk support across providers

Bulk geocoding needs, processing a spreadsheet of a few thousand addresses at once, or geocoding an entire customer database as a one-time cleanup project, show up differently across providers, and the differences matter more than they might seem to at first glance when planning a migration.

Some providers offer a dedicated web interface for bulk work: upload a CSV, wait for processing, download the results with new columns appended. This suits non-technical users, an operations or marketing team member who needs addresses geocoded once and does not want to write any code, but it is a separate product surface from the programmatic API and needs its own migration plan if you rely on it.

Other providers expect bulk geocoding to be handled entirely through the programmatic API, sending many individual requests, often with some concurrency, and assembling the results yourself. This puts more control in the hands of the calling application, including deciding on retry behavior, concurrency limits, and how to handle partial failures within a large batch.

A few genuinely provider-independent lessons apply regardless of which approach a given provider takes:

  • Always build in retry logic for individual failed requests within a larger batch, since a batch job that fails entirely because one address out of ten thousand returned an error is a fragile design regardless of provider
  • Respect whatever rate limit or quota structure the API documents, since a naive loop firing requests as fast as possible is the most common way a bulk job runs into throttling or unexpected costs
  • Log enough detail per request, not just per batch, that a failed subset can be identified and reprocessed without rerunning the entire job from scratch

My Geocode's approach to bulk work follows the programmatic pattern: requests go through the same endpoints as any other lookup, with the same authentication options (an X-API-Key header, Authorization: Bearer, HTTP Basic auth, or a query parameter) and the same quota visibility through response headers like X-Quota-Used and X-Quota-Free-Remaining on every single request, documented at /docs/rate-limits/. For a large one-time bulk job, this quota visibility is genuinely useful for pacing a job automatically, since a script can check X-Quota-Free-Remaining on each response and throttle itself accordingly rather than guessing at a safe request rate.

Because pricing is flat across every endpoint, prepaid credit at €0.0001 per request or an Unlimited key at €50 a month, a large bulk job's cost is a simple multiplication once you know how many addresses need processing, without a separate bulk pricing tier to negotiate or compare against your ongoing per-request usage. For teams migrating a recurring bulk workflow, whether that is a monthly customer list cleanup or a one-time data migration project, that flat and predictable per-request cost tends to make budgeting the easiest part of the whole move.