Programming · free software · the open webSubscribe via RSS

How Can a Protocol Specify Retry Behavior?

From the earlier reference collection. Read the current software blog.

A retry contract should say which failures are temporary, how clients should wait, and how to avoid repeating side effects.

Name retryable conditions

“Retry on failure” is too broad for a protocol. Some failures are temporary, such as a service being busy; others are durable, such as a malformed request or a permission denial. Define retryability by error code or response class, and say what clients should do when the condition is unknown. A client that retries every failure can waste capacity and obscure a problem that requires a corrected request.

For example, a response might classify SERVICE_BUSY as retryable and INVALID_ARGUMENT as non-retryable. The client can safely wait and try again for the first condition, while displaying a useful explanation for the second. Make clear whether the classification applies to the whole operation or only to a sub-operation.

Specify the waiting rule

A retryable response should provide useful delay guidance where possible. The protocol can define a retry-after field as a duration or timestamp, its units and format, and how long the value remains relevant. If no delay is supplied, specify a client fallback such as exponential backoff: wait briefly, increase the interval after each failed attempt, and add random jitter so many clients do not retry together.

Set a maximum interval and a policy for exhausting attempts. A client might make a small number of attempts over a bounded period, then return a visible failure instead of retrying indefinitely. The protocol should say whether clients may retry immediately after a connection failure, since the server may have completed work even if the response was lost.

Protect operations with side effects

Retries can duplicate effects. If a request charges a card, creates a job, or sends a notification, a lost response leaves the client unsure whether the action happened. Define an idempotency mechanism, such as a client-generated operation key whose scope and retention period are documented. Repeating the same request with the same key should return the original outcome or a clearly defined status, not perform the effect again.

For example, a client submitting a report can assign key report-8472. If the connection drops, it retries with that key. The server can associate it with the original submission and return the existing result. Explain what happens if the same key is reused with different request content; rejecting the mismatch is easier to reason about than silently choosing one version.

Make the contract testable

A complete retry section should connect failure classes, timing guidance, attempt limits, and duplicate protection. Include examples for a temporary service error, a permanent validation error, and a timeout with an uncertain outcome. This gives implementers enough information to build clients that recover from temporary interruptions without turning a transient problem into a flood of repeated work.

Suggest a correction · All posts