Concepts / Handling API Rate Limits and Throttling

Handling API Rate Limits and Throttling

The reusable pattern is: check the cache, call the API only when the location is not cached, and store the new result.

  • Programming

Why Repeated Lookups Matter

Every location lookup sent to a geocoding API consumes an API call. Because most geocoding services impose a maximum number of requests during a 24-hour period, sending the same lookup more than once wastes part of the available limit. The central strategy in geoload.py is to save results locally so that a location does not need to be requested again.

Definition

A cache is local stored data that the program checks before requesting the same information from an external service. In this workflow, SQLite is the local cache for geocoding results.

Key point

The reusable pattern is: check the cache, call the API only when the location is not cached, and store the new result.

The Cache Decision

Before geoload.py calls the geocoding API, it checks the geodata.sqlite database for the current location. A cached location takes the short path: the program uses the stored result and skips the API call. An uncached location takes the longer path: the program calls the API and stores the returned geocoding result for later use.

LocationCheck SQLiteStored resultUse cached dataGeocoding APISQLiteStore new resultreadcachednot cachedresult
How does geoload.py decide whether to read a location from SQLite or send a new request to the geocoding API?
Worked example

Two Runs with Overlapping Locations

A first input contains ten locations. A second input contains those same ten locations plus five new locations.

  1. 1
    First run

    The database is empty, so each of the ten locations is sent to the API and each result is stored.

  2. 2
    Second run: original locations

    The program finds all ten original locations in SQLite and skips the API call for each one.

  3. 3
    Second run: new locations

    The five new locations are not cached, so the program sends five API calls and stores those results.

Result

Across the two runs, the second run makes five API calls instead of requesting all fifteen locations again. The source example describes this second run as five times faster than the first.

The geoload.py Workflow

The program processes locations one at a time. It reads a location from the input, checks geodata.sqlite, and then chooses between the cached path and the API path. When a new API result is obtained, it is stored locally. This means later processing, including later program runs, can reuse the result instead of repeating the external request.

Input locationsRead locationCheck cacheCached resultSkip API callAPI requestStore resultContinueprovideschecksfoundnot foundreturns resultreusesave and continue
What happens next as geoload.py reads input, checks the cache, calls the API when needed, stores results, and continues processing?
Input sourceLocationsgeoload.pygeodata.sqliteStored resultsGeocoding APIGeocoding resultlocationcheck or storecached resultuncached locationresponseprocessed data
How does location data and the resulting geocoding response move between the input source, the SQLite cache, and the external API?
Key point

The cache is not an alternative input source that replaces the program's workflow. It is a checkpoint inside the workflow: every location is checked, but only uncached locations require a new API request.

Working Within Daily Limits

For a small dataset, a single run may not reach the service's daily request limit. A dataset with thousands of locations requires a more deliberate process. geoload.py includes a counter that limits how many API calls can occur during one run. For example, the counter can be set to 100 calls per run. The program processes uncached locations until that limit is reached, stores the results, and stops.

Run 1Up to 100 new callsStored batch 1Run 2Next uncached batchStored batch 2Later runsContinue remaininglocationsstore resultsnext runstore resultsrepeat over days
How do request counters limit API calls during one run, and how does the cache reduce the number of calls in later runs?
Worked example

A Large Dataset in Batches

A dataset contains thousands of locations, and the counter is set to 100 API calls per run.

  1. 1
    Limit one run

    The program makes API calls only for uncached locations and stops after reaching the configured limit of 100 calls.

  2. 2
    Preserve progress

    The results from that batch remain in geodata.sqlite.

  3. 3
    Run again later

    On a later day, the program checks the cache, skips the locations already processed, and works on the next batch of uncached locations.

Result

The dataset is processed across multiple runs instead of requiring all API calls in one run.

Resetting the Cache

Removing the geodata.sqlite file resets the caching process. When geoload.py runs again, it does not find the existing database, creates a new one, and treats every location as uncached. The program therefore begins geocoding from scratch.

geodata.sqliteStored resultsDatabase removedProgram runCached locations skip APIcallsNew databaseEvery location is uncachedchecked duringnext run creates
What changes in the program's behavior before and after geodata.sqlite is deleted?

Mistakes to Avoid

  • Common mistake

    Assuming every input location should trigger a new API request.

    What it looks like

    A later run receives locations that were already processed during an earlier run.

    Why it fails

    The existing results are already stored in the SQLite cache, so requesting them again wastes API calls.

    Do this instead

    Check geodata.sqlite before calling the API and skip locations that are already cached.

  • Common mistake

    Trying to process a large dataset in one unrestricted run.

    What it looks like

    Thousands of locations are sent to the API without using the request counter.

    Why it fails

    Geocoding services generally impose daily request limits.

    Do this instead

    Set a per-run counter, let the program store the completed batch, and run it again over several days.

  • Common mistake

    Deleting geodata.sqlite without realizing that stored results will be lost.

    What it looks like

    The cache is removed merely to restart the program, even though the stored results are still useful.

    Why it fails

    Removing the file erases the cache and causes every location to be treated as uncached.

    Do this instead

    Reset the cache only when starting fresh is intentional, such as after suspecting incorrect data, switching services, or testing.

EASY

A first run stores results for 80 locations. A later input contains those 80 locations and 20 new locations. The request counter allows 100 calls per run. How many API calls should the later run need, assuming the cache is present and accurate? Explain which part of the workflow produces that number.

Hints
  • Separate the locations already in SQLite from the locations that are not cached.
  • Cached locations skip the API call.
  • Only the new locations consume calls during the later run.

What do you think happens?

After geodata.sqlite is deleted, what should geoload.py do when it processes a location that was previously cached?

  • Skip the API call because the program remembers the result elsewhere

  • Treat the location as uncached and request it again

  • Stop because a deleted database cannot be recreated

Reveal answer
Answer:

Treat the location as uncached and request it again.

Removing geodata.sqlite erases the stored results. On the next run, the program creates a new database and starts with every location treated as uncached.

Practical Takeaways

API rate-limit management becomes manageable when the program separates new work from completed work. SQLite records completed geocoding results, the cache check prevents redundant requests, and the counter limits the number of new API calls in one run. Multiple runs can then continue processing uncached locations. If a complete reset is required, removing geodata.sqlite clears the stored results and makes the next run begin again from an empty cache.

  1. 1
    SQLite acts as a local cache for geocoding results.
  2. 2
    geoload.py checks the cache before making an API request.
  3. 3
    A request counter limits API calls during one run, while repeated runs process later batches of uncached locations.
  4. 4
    Deleting geodata.sqlite erases the cache and causes all locations to be treated as uncached.
  5. 5
    The same check, request, store pattern applies to external data retrieval where avoiding duplicate API calls matters.

At a glance

  • Use SQLite as a local cache so previously geocoded locations do not consume new API calls.
  • The geoload.py workflow checks the cache first and calls the API only for uncached locations.
  • Use a request counter to process a large dataset in limited batches across multiple runs.
  • Remove geodata.sqlite only when intentionally resetting the process, because deletion removes all cached results.

Related concepts

More concepts starting with H