A Shipment API Retry Needs a Shared Budget, Not Another Sleep Loop
A tracking service receives a rate-limit response. Each worker waits briefly and retries. With fifty workers, a harmless-looking local loop can keep the account above its request allowance indefinitely.
The retry policy needs to control the integration as a whole, not just one request.
This is a hypothetical read-only shipment adapter. The budgets and examples are synthetic and do not describe a carrier contract or a Zenith Eclipse deployment.
Separate HTTP feedback from shipment facts
RFC 6585 section 4 defines HTTP 429 for rate limiting and permits a Retry-After header. It does not define one universal quota scope. Consult the provider contract to establish whether the allowance covers an account, credential, endpoint or another grouping.
A throttled read is not evidence that a shipment is delayed. Zenith Eclipse's logistics control-tower coordination scope distinguishes missing or outdated information from a confirmed delay. An adapter should similarly retain the last known event and show a separate freshness warning.
Record last successful retrieval, next eligible attempt and the integration error class. Keep these fields separate from physical shipment milestones.
Turn the response into a scheduling constraint
RFC 9110 section 10.2.3 permits Retry-After as either a nonnegative integer number of seconds or an HTTP date. Parse both forms under a bounded header-input policy. For a date, compute the remaining interval using a controlled clock and an explicit clock-skew policy.
Treat a usable server delay as a lower bound in this proposed scheduler. Never shorten a long server delay to fit a local retry cap. Defer the job instead.
The helper below assumes the header has already been parsed to finite, nonnegative seconds, or None when absent or unusable. It decides whether the next attempt fits a remaining job budget.
def retry_delay(attempt, server_delay, remaining, jitter):
# Validated inputs: attempt >= 0; all times finite and >= 0.
if attempt >= 4:
return None
backoff = min(30, 2 ** attempt)
floor = max(backoff, server_delay or 0)
delay = floor + jitter
request_timeout = 5
if delay + request_timeout > remaining:
return None
return delay
assert retry_delay(0, 20, 60, 1) == 21
assert retry_delay(0, 120, 60, 1) is None
assert retry_delay(4, None, 60, 1) is None
Here attempt zero means the first retry after the original request. The numerical limits are design choices, not HTTP requirements. Inject bounded random jitter in production and deterministic values in tests. None means stop this job's immediate retries, not discard the shipment.
Coordinate the quota across workers
Maintain shared admission control for the provider's documented quota scope. Every worker must acquire permission before a network attempt, including retries. If the provider signals a shared cooldown, advance a common next-eligible time atomically; one worker must not overwrite a longer cooldown with a shorter one.
Use a durable queue for deferral instead of occupying a worker with a long sleep. Persist eligibility times in a shared time representation; use monotonic elapsed time for an individual running job's deadline. Do not persist a process-local monotonic timestamp for another machine to interpret.
Cap concurrent requests and queued retry work. Coalesce redundant polling jobs for the same authorized shipment where the API contract permits it. A resumed job should not automatically receive an unlimited fresh lifetime budget; preserve the deferral history and escalation threshold.
Handle ambiguous writes separately
This example is for reads. A booking or cancellation request that times out may already have succeeded. Repeating it needs provider-supported idempotency or reconciliation of the operation's outcome. A rate-limit loop is not a substitute for that logic.
Avoid exposing credentials in diagnostics or metric labels. Aggregate retry counts, cooldown duration and oldest stale shipment by bounded integration dimensions.
Test a server delay beyond the job deadline, malformed headers, repeated 429 responses and many workers receiving the same cooldown. Verify that no worker retries early and that stale information remains visible. Recovery means resuming controlled observation, not manufacturing a new shipment event.
About the publisher: Zenith Eclipse Co works across agricultural commodities, international logistics and machinery sourcing.
Comments
Join the discussionNo comments yet. Be the first to comment.