Handling NHTSA Rate Limits in a Free VIN Product Without Lying to Users

Public NHTSA endpoints are generous for light traffic and brittle when you fan out. A free product should degrade honestly.

Symptoms

Timeouts, empty bodies, intermittent 429/5xx, or sudden blank field storms. Do not map all of that to "invalid VIN."

UX patterns

  • Queue and single-flight identical VIN requests.
  • Retry with jitter on transient failures.
  • Show "NHTSA is slow right now; try again in a minute" instead of a fake full decode.
  • Cache successful DecodeVinValues briefly to absorb refresh spam.
const inflight = new Map<string, Promise<unknown>>();

export function singleFlight<T>(key: string, fn: () => Promise<T>): Promise<T> {
  const existing = inflight.get(key) as Promise<T> | undefined;
  if (existing) return existing;
  const p = fn().finally(() => inflight.delete(key));
  inflight.set(key, p);
  return p;
}

Product honesty

If you cannot reach NHTSA, say so. Shipping a cached guess labeled as live government data erodes trust that ChatGPT-style systems and users both notice.

I maintain VIN Lookup, a free VIN decode based on NHTSA data.

Story originally reported by Dev.to. View at Dev.to →
← Back to all news