Monitor your key's usage before you hit a limit
Watching your quota headers as you go tells you when a limit is approaching, well before a request actually gets rejected.
Geocoding the same address twice in a week is a common pattern, and a cache is the obvious fix. The part that trips people up is forgetting that a cache hit and a cache miss look identical to your application but very different to your quota.
A geocoded address rarely changes, so caching the full result of a forward or reverse lookup, keyed on the normalized input, is safe for a long time, weeks or months depending on how much churn your address data has. An IP lookup result is safe to cache for shorter periods, since ranges do occasionally get reassigned. A timezone lookup's identifier is stable, but its utc_offset shifts with daylight saving, so cache the identifier and recompute the offset rather than caching the whole response indefinitely.
A cache hit means you never called the API at all for that request, so nothing changes in X-Quota-Used or your credit balance. That is the entire point of caching, but it also means a cache hit will not appear anywhere in the quota headers, which only reflect calls that actually reached the API. Do not try to reconcile your own request counters against quota headers unless you are also tracking cache hits separately.
cache_key = "forward:" + normalize("221B Baker Street, London")Normalize by lowercasing, trimming whitespace, and collapsing repeated spaces before hashing, so trivial formatting differences in the input do not create needless cache misses.
If half your incoming addresses are repeats within a caching window, your effective request count against the free allowance and any prepaid credit is roughly half your raw address volume. That is worth knowing before you decide whether you need to upgrade past the 2,500 free requests a day included with every key, since the real number hitting the API may be much lower than your raw traffic suggests.
Skip the cache for anything where a stale result is actively wrong, such as re-verifying an address a customer just corrected. A single fresh lookup costs one request either way, so bypassing the cache for a specific correction is cheap insurance against serving a known-bad cached result.
Caching well is mostly about knowing which fields are stable and which are not, rather than caching everything or nothing. See the forward geocoding docs for the fields that make good cache keys.