← Recipes

阅读中文版本

Trace API 429 Throttling Windows

Align 429 responses with rate-limit headers to reconstruct the client quota window and stop retries from extending the lockout.

~30 minapirate-limitdebugging

Task

Correlate 429 responses with X-RateLimit headers to reconstruct the quota window and tune client pacing.

When to use this

A sync job receives 429 in bursts and then waits much longer than expected, because retries keep resetting its own budget.

Prerequisites

  • Logs containing status codes and rate-limit headers
  • A client job you can pace
  • The provider rate-limit documentation

Steps

1. Extract quota headers alongside each 429.

grep -E 'HTTP/|x-ratelimit|retry-after' access.log | tail -20

Expected output: You can align each 429 with remaining quota and reset timestamps.

2. Pace the client to stay under the limit and drop retries on 429.

if resp.status_code == 429:
    wait = int(resp.headers.get('retry-after', '60'))
    time.sleep(wait)
    raise ClientThrottledException('pause sync')

Expected output: The job pauses for the full window instead of retrying and extending the lockout.

Troubleshooting

Problem

410 after a long pause

Solution

Some providers count retries toward quota; confirm the reset header and avoid probing during the window.

Problem

Different limits per endpoint

Solution

Track quota per route, not globally, since limits often differ.

Limitations

  • Requires providers to emit accurate rate-limit headers.
  • Does not bypass limits; it only paces the client.
  • Concurrency across multiple clients is hard to model without a coordinator.

What this recipe does

Correlate 429 responses with X-RateLimit headers to reconstruct the quota window and tune client pacing.

A sync job receives 429 in bursts and then waits much longer than expected, because retries keep resetting its own budget.

Prerequisites

  • Logs containing status codes and rate-limit headers
  • A client job you can pace
  • The provider rate-limit documentation

Procedure

  1. Extract quota headers alongside each 429.
grep -E 'HTTP/|x-ratelimit|retry-after' access.log | tail -20

Expected result: You can align each 429 with remaining quota and reset timestamps.

  1. Pace the client to stay under the limit and drop retries on 429.
if resp.status_code == 429:
    wait = int(resp.headers.get('retry-after', '60'))
    time.sleep(wait)
    raise ClientThrottledException('pause sync')

Expected result: The job pauses for the full window instead of retrying and extending the lockout.

How to confirm it worked

Run the commands above and confirm every expected result in order. If a step does not produce the stated output, use the troubleshooting notes before continuing. A passing run shows the job completes without 429 responses once paced to the reset window, and total wall time fits the quota math.

Troubleshooting

410 after a long pause — Some providers count retries toward quota; confirm the reset header and avoid probing during the window.

Different limits per endpoint — Track quota per route, not globally, since limits often differ.

Limitations

  • Requires providers to emit accurate rate-limit headers.
  • Does not bypass limits; it only paces the client.
  • Concurrency across multiple clients is hard to model without a coordinator.