gRPC Metadata — Complete Guide
In this tutorial, you will learn about grpc metadata. We cover key concepts, practical examples, and best practices to help you master this topic.
gRPC metadata consists of key-value pairs transmitted as HTTP/2 headers with each RPC call. Metadata carries auxiliary information like authentication tokens, tracing IDs, request IDs, and content type hints separate from the main request message.
What You'll Learn
- Creating and sending metadata from clients
- Reading metadata on the server
- Initial metadata vs trailing metadata
- Metadata in streaming RPCs
- Common metadata keys and conventions
Why It Matters
Metadata separates control plane information from data plane payloads. This keeps request messages clean and enables cross-cutting concerns to be handled transparently by interceptors.
Real-World Use
Google Cloud APIs use metadata for API keys, quotas, and request tracing. Envoy proxy injects metadata for traffic routing. OpenTelemetry uses gRPC metadata for trace context propagation.
flowchart LR
Client[Client] -->|Send RPC + Metadata| Server[Server]
Metadata --> Auth[Authorization: Bearer token]
Metadata --> Trace[Trace ID]
Metadata --> RequestID[Request ID]
Server -->|Response + Trailing Metadata| Client
Trailing --> RateLimit[Rate Limit Info]
Trailing --> ServerTiming[Server Timing]
Teacher Mindset
Use metadata for data that does not belong in the request body. Authentication tokens, trace IDs, and request metadata are standard use cases. Keep metadata values small and string-based.
Code Examples
// Example 1: Client sending metadata
const grpc = require('@grpc/grpc-js');
const metadata = new grpc.Metadata();
metadata.set('authorization', 'Bearer eyJhbGciOiJIUzI1NiJ9');
metadata.set('x-request-id', uuid.v4());
metadata.set('x-trace-id', 'abc123');
client.getOrder(
{ order_id: '123' },
metadata,
(err, order) => {
const trailingMetadata = order.getTrailers();
console.log('Rate limit:', trailingMetadata.get('x-rate-limit-remaining'));
}
);
// Example 2: Server reading and setting metadata
server.addService(OrderService, {
getOrder: (call, callback) => {
const auth = call.metadata.get('authorization');
const traceId = call.metadata.get('x-trace-id');
console.log(`Trace: ${traceId}, Auth: ${auth}`);
// Set trailing metadata
const trailingMetadata = new grpc.Metadata();
trailingMetadata.set('x-rate-limit-remaining', '95');
trailingMetadata.set('x-processing-time', '42ms');
callback(null, order, trailingMetadata);
}
});
// Example 3: Metadata in streaming calls
client.subscribeOrders({}, (metadata) => {
// Initial metadata received before first message
console.log('Connected:', metadata.get('x-server-id'));
});
const call = client.subscribeOrders({});
call.on('metadata', (metadata) => {
console.log('Initial metadata:', metadata.get('x-server-id'));
});
call.on('data', (order) => console.log('Order update:', order));
call.on('status', (status) => {
console.log('Final status:', status.code);
console.log('Trailers:', status.metadata.get('x-orders-processed'));
});
Common Mistakes
- Using metadata for large payloads (keep under a few KB)
- Using non-ASCII characters in metadata values
- Forgetting that metadata keys are case-insensitive per HTTP/2 spec
- Not handling missing metadata keys gracefully
- Mixing initial metadata and trailing metadata in streaming calls
Practice
- Send an authorization token in metadata from a client.
- Read and validate the token on the server side.
- Add a request ID to metadata for tracing.
- Send trailing metadata with processing stats.
- Challenge: Implement a metadata-based correlation ID that propagates across three gRPC services.
FAQ
Mini Project
Implement a metadata propagation system for your order service. Add request ID generation on the client, pass it through metadata, log it on each server, and return processing duration in trailing metadata.
What's Next
Next, you will learn about gRPC Load Balancing strategies for distributing traffic across server instances.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro