# rpc error: code = Unavailable desc = rate limit exceeded: retry after 30 seconds

- **ID:** `go/grpc-unavailable-rate-limit`
- **Domain:** go
- **Category:** resource_error
- **Verification:** ai_generated
- **Fix Rate:** 80%

## Root Cause

The client has sent too many requests in a short period, exceeding the server's rate limit.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| 1.0 | active | — | — |
| 1.1 | active | — | — |

## Workarounds

1. **Honor the retry-after duration and implement backoff.** (90% success)
   ```
   for {
    resp, err := client.SomeRPC(ctx, req)
    if err == nil { return resp }
    if st, ok := status.FromError(err); ok && st.Code() == codes.Unavailable {
        // Extract retry-after from metadata or message
        time.Sleep(30 * time.Second)
        continue
    }
    return err
}
   ```
2. **Implement client-side rate limiting to avoid hitting server limits.** (85% success)
   ```
   limiter := rate.NewLimiter(rate.Limit(10), 1) // 10 requests per second
for {
    err := limiter.Wait(ctx)
    if err != nil { return err }
    resp, err := client.SomeRPC(ctx, req)
    if err == nil { return resp }
}
   ```

## Dead Ends

- **Ignore the retry-after header and keep sending requests.** — The server will continue to reject requests until the rate limit resets. (100% fail)
- **Increase the rate limit on the client side only.** — Rate limiting is enforced by the server; client-side changes don't affect it. (95% fail)
