# Deadlines and Cancellation — gRPC

Source: https://www.skillbyai.com/en/grpc/r-deadlines

> Always set a deadline.

## Bounded waiting across services

gRPC has no default deadline in many implementations, so a call can wait indefinitely. Set a **deadline** (or timeout) on every call; it travels to the server in the `grpc-timeout` header, and when it expires the call fails with `DEADLINE_EXCEEDED` on the client and is **cancelled** on the server. Servers should propagate the remaining deadline to downstream calls and stop work when the context is cancelled, so a slow chain does not keep doing useless work.

## Failing well

Deadlines bound waiting, status codes describe failures, and retries recover from transient ones.

![Three ideas: deadlines and cancellation, status codes, retries.](assets/figures/grpc/section-5-map.svg) — Figure 5.1 — Deadlines, status codes and retries.

## Deadlines in Go

Propagating context through calls (a sketch).

```go
func (s *checkoutServer) PlaceOrder(ctx context.Context, req *pb.PlaceOrderRequest) (*pb.Order, error) {
    // ctx already carries the caller's deadline; downstream calls inherit it
    stock, err := s.inventory.Reserve(ctx, &invpb.ReserveRequest{Items: req.Items})
    if err != nil {
        return nil, err
    }
    _ = stock
    // ...
    return order, nil
}

// client side: set a deadline for the whole operation
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
order, err := client.PlaceOrder(ctx, req)
```

## Budget deadlines through the call chain

If the edge allows 2 seconds, downstream services must finish well within that; propagating the context does this automatically.

**Quiz:** What status does a client get when its deadline expires?

- [ ] NOT_FOUND
- [x] DEADLINE_EXCEEDED
- [ ] OK
- [ ] UNIMPLEMENTED

*Answer:* DEADLINE_EXCEEDED. The server-side call is cancelled too.
