Optimizing gRPC Performance
1. Tuning Message Size
| Option | Default | Detail |
|---|---|---|
MaxRecvMsgSize | 4 MB | Increase for large payloads |
MaxSendMsgSize | ~math.MaxInt32 | Cap to prevent OOM |
| Chunked streaming | — | Prefer over single huge message |
2. Tuning Window Size
Example: HTTP/2 windows
srv := grpc.NewServer(
grpc.InitialWindowSize(1<<20), // 1 MiB stream
grpc.InitialConnWindowSize(1<<24), // 16 MiB connection
)
| Window | Detail |
|---|---|
| BDP estimation | Default; auto-tunes |
| Manual tuning | For high BDP networks |
3. Using Connection Pooling
| Pattern | Detail |
|---|---|
| One conn per service | HTTP/2 multiplexes streams — usually enough |
| Pool of N conns | For very high concurrency on single peer |
| SETTINGS_MAX_CONCURRENT_STREAMS | Often 100 default — pool around it |
4. Enabling Multiplexing
| Detail | Note |
|---|---|
| HTTP/2 multiplexing | Many RPCs share one TCP conn |
| No head-of-line at L7 | Streams interleave |
| L4 still blocks | TCP loss stalls — consider QUIC/HTTP/3 future |
5. Optimizing Message Encoding
| Tip | Detail |
|---|---|
| Reuse messages | Pool via sync.Pool |
Avoid any.Any | Double encoding cost |
| Smaller field numbers | 1–15 use 1-byte tag |
| packed repeated | Default in proto3 for scalars |
6. Reducing Allocations
| Technique | Detail |
|---|---|
| vtprotobuf codec | Faster marshal, fewer allocs |
| Reuse response objects | Reset and refill in streaming hot paths |
| Avoid string→[]byte conversions | Use unsafe carefully |
7. Implementing Caching
| Layer | Detail |
|---|---|
| In-memory LRU | For hot reads |
| Distributed (Redis) | Shared across replicas |
| Singleflight | Dedupe concurrent identical requests |
8. Batching Requests
| Approach | Detail |
|---|---|
| Server batches DB | Coalesce within short window |
| Client batch RPC | Repeated request field; one call returns N results |
| Stream of items | Avoid round-trip per item |
9. Using Streaming for Bulk Data
| Pattern | Detail |
|---|---|
| Server streaming | Large result sets — chunk & flush |
| Client streaming | Uploads in chunks (64–256 KB) |
| Backpressure | Flow control via HTTP/2 windows handles it |
10. Tuning Thread Pool
| Language | Detail |
|---|---|
| Go | Each RPC = goroutine; tune GOMAXPROCS |
| Java | Set executor on ServerBuilder |
| Python | ThreadPoolExecutor(max_workers=N) on server |
11. Profiling gRPC Performance
| Step | Detail |
|---|---|
| CPU pprof | Identify hot marshal/handler paths |
| Block profile | Find lock contention |
| Trace exporter | End-to-end latency breakdown |
12. Optimizing Network Usage
| Lever | Detail |
|---|---|
| gzip compression | For text-heavy payloads |
| Keep-alive pings | Catch dead conns early |
| Co-locate | Same zone/region to cut latency |
| HTTP/3 (experimental) | QUIC avoids TCP HOL |