---
title: "Set a deadline on every gRPC call and pass · Agent Wranglers"
url: https://agentwranglers.se/playbook/api-design/graphql-and-grpc/grpc-deadlines
id: API-89
level: Recommended
updated: 2026-10-22
tokens: 850
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Set a deadline on every gRPC call and pass it on

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [GraphQL and gRPC](https://agentwranglers.se/playbook/api-design/graphql-and-grpc.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-22.

- ID: API-89
- Level: Recommended
- Chapter: [GraphQL and gRPC](https://agentwranglers.se/playbook/api-design/graphql-and-grpc.md)
- Rule: Give every gRPC call a deadline in the client. A server that calls other services passes the remaining time on, and stops work when the deadline has passed.
- Check: A test calls each method against a server stub that never answers. The call fails with `DEADLINE_EXCEEDED` within its deadline plus 1 second. A lint or code search finds no client call without a deadline or timeout.
- How: gRPC sets no deadline by default, so a stuck server holds the caller's thread and connection forever. gRPC sends the deadline as a time left, so clocks on two machines need not agree. Java and Go pass an incoming deadline to outgoing calls by default, and C++ does not. Pick the value as [set timeouts on every call](https://agentwranglers.se/playbook/api-design/reliability/timeouts.md) says. A call that ends with `DEADLINE_EXCEEDED` may still have succeeded on the server. Retry writes only with an idempotency key, as [accept idempotency keys on POST](https://agentwranglers.se/playbook/api-design/reliability/idempotency-keys.md) says.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### Go example

```go
ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
defer cancel()
invoice, err := client.GetInvoice(ctx, &pb.GetInvoiceRequest{Id: id})
if status.Code(err) == codes.DeadlineExceeded {
	return nil, fmt.Errorf("invoice service too slow: %w", err)
}
```

### Python example

```python
try:
    invoice = stub.GetInvoice(GetInvoiceRequest(id=invoice_id), timeout=2.0)
except grpc.RpcError as error:
    if error.code() == grpc.StatusCode.DEADLINE_EXCEEDED:
        raise InvoiceServiceSlow(invoice_id) from error
    raise
```

## Sources

- [gRPC, Deadlines](https://grpc.io/docs/guides/deadlines/)

## Related rules

- API-35 [Set timeouts on every call](https://agentwranglers.se/playbook/api-design/reliability/timeouts.md) in API design
- API-32 [Accept idempotency keys on POST](https://agentwranglers.se/playbook/api-design/reliability/idempotency-keys.md) in API design

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/api-design/graphql-and-grpc/grpc-deadlines">Agent Wranglers API design playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Check every schema change for breaking changes in CI](https://agentwranglers.se/playbook/api-design/graphql-and-grpc/schema-breaking-checks.md)
- Next: [Answer with the standard gRPC status codes](https://agentwranglers.se/playbook/api-design/graphql-and-grpc/grpc-status-codes.md)
- [GraphQL and gRPC](https://agentwranglers.se/playbook/api-design/graphql-and-grpc.md)
