Should DEADLINE_EXCEEDED be retried for non-idempotent Google Cloud client library calls?
0 reputation · 13 Sept 2020, 21:32 UTC
0 reputation · 13 Sept 2020, 21:32 UTC
Google Cloud client libraries built on gRPC expose layered timeout controls: a total timeout, a per-RPC attempt deadline, and retry settings that can be overridden per call. By default, idempotent RPCs are typically retried on codes such as UNAVAILABLE and DEADLINE_EXCEEDED, while non-idempotent operations such as resource creation are often excluded from default retry sets to avoid duplicate side effects. Exact defaults vary by language and library generation, so the generated retry configuration for the specific service and version governs.
The open decision is how to treat DEADLINE_EXCEEDED on a non-idempotent call. A client deadline expiring only means the caller stopped waiting; the server may still have applied the change, so a blind retry can create duplicates, while never retrying can drop work that never reached the server. Cancelling the caller's context mid-call is likewise best-effort and does not confirm that server-side processing stopped.
Which retry policy should apply to DEADLINE_EXCEEDED for non-idempotent Google Cloud RPCs, and how can a caller distinguish a request that was never processed from one that completed after the deadline? Should per-call retry settings be used mainly to tighten deadlines on latency-sensitive paths rather than to add retries?
29775 reputation · 13 Sept 2020, 23:12 UTC
By default, non‑idempotent RPCs are not retried when they return DEADLINE_EXCEEDED. The generated retry configuration for most Google Cloud client libraries excludes this code for methods that can alter state (e.g., create, delete, update).
DEADLINE_EXCEEDED for non‑idempotent methods, ensuring a uniform developer experience.MyServiceSettings settings = MyServiceSettings.newBuilder()
.setRetryableCodes(MyServiceSettings.getDefaultRetryableCodes())
.build();
System.out.println(settings.getRetryableCodes());
Look for the presence of DEADLINE_EXCEEDED in the returned set for the method you are calling.
DEADLINE_EXCEEDED and does not retry automatically, the default policy is in effect.
from google.api_core import retry
retry_policy = retry.Retry(
predicate=retry.if_exception_type(),
deadline=60.0, # seconds
initial=1.0,
maximum=10.0,
multiplier=2.0,
)
client.create_resource(request, retry=retry_policy)
Ensure the service provides an idempotency key or transaction ID that can be reused.
If the service exposes a mechanism (e.g., an X-Request-ID header or a transaction token) that lets you detect whether the operation was applied, you can safely retry a DEADLINE_EXCEEDED by adding that guard to your retry logic. Otherwise, keep the default non‑retry behavior to avoid duplicate side effects.
Does the service you are calling provide an explicit way to confirm whether the operation completed (such as an idempotency key, a status endpoint, or a transaction ID)? If so, you can safely enable a retry on DEADLINE_EXCEEDED by incorporating that guard into your client code.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.