Retries, hedging and service config

gRPC · Expert · 15 min

Well-tuned retries hide transient failures; badly tuned ones cause outages.

gRPC distinguishes two kinds of retry:

  • Transparent retries: when the library knows the request never reached the server application (e.g. the stream was refused), it retries automatically. Always safe.
  • Configured retries: a retry policy in the service config for specific methods: maxAttempts, initialBackoff, maxBackoff, backoffMultiplier and retryableStatusCodes (usually just UNAVAILABLE). Only retry idempotent methods.

Hedging is the aggressive cousin: send the same request to several backends after hedgingDelay without waiting for failure, and use the first response. It cuts tail latency for idempotent reads at the cost of extra load. A method can have a retry policy or a hedging policy, not both.

Safety valves:

  • Retry throttling (retryThrottling with maxTokens and tokenRatio) stops retries when failure rates rise, preventing retry storms.
  • The call deadline bounds all attempts together.
  • Servers can push back with grpc-retry-pushback-ms metadata.

The service config can come from the client (grpc.service_config channel option) or from the name resolver (DNS TXT records or xDS), letting operators tune policies without redeploying clients. It also sets per-method timeouts (timeout), waitForReady and load-balancing policy.

Example

// Service config JSON, passed as the grpc.service_config channel option
const serviceConfig = {
  loadBalancingConfig: [{ round_robin: {} }],
  methodConfig: [
    {
      name: [{ service: "hello.v1.Greeter", method: "SayHello" }],
      timeout: "0.5s",                // default deadline per call
      retryPolicy: {
        maxAttempts: 4,
        initialBackoff: "0.1s",
        maxBackoff: "1s",
        backoffMultiplier: 2,
        retryableStatusCodes: ["UNAVAILABLE"],
      },
    },
  ],
  retryThrottling: { maxTokens: 10, tokenRatio: 0.1 },
};
const options = { "grpc.service_config": JSON.stringify(serviceConfig) };
console.log(Object.keys(options)); // [ 'grpc.service_config' ]
// new hello.v1.Greeter(target, credentials, options)

Remember

  • Transparent retries are automatic and always safe
  • Retry policies belong in service config, for idempotent methods only
  • Hedging trades extra load for lower tail latency
  • Retry throttling prevents retry storms

Watch out for

  • Retrying non-idempotent methods like ChargeCard on UNAVAILABLE, causing duplicate charges.

Check yourself

  1. What does retryThrottling protect against?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: grpc.io/docs/guides/retry/

Builds on

Unlocks

Nothing builds on this yet.