Skip to content

Versioning Grpc

DodaTech 2 min read

title: "Versioning gRPC APIs — Protocol Buffer Compatibility and Evolution" description: "gRPC API versioning follows Protocol Buffer compatibility rules, using field numbers, reserved keywords, and package names to evolve service definitions safely." date: 2026-06-28 lastmod: 2026-06-28 weight: 25 tags: [apis, versioning] }

gRPC API versioning leverages Protocol Buffer's built-in compatibility rules: never reuse field numbers, use reserved keywords, and organize services by package or version.

What You'll Learn

  • Protobuf compatibility rules
  • gRPC service versioning
  • Package-based versioning

Why It Matters

gRPC's strict schema contracts make breaking changes costly. Understanding Protobuf's backward compatibility rules prevents accidental breakage.

Code Examples

// User service v1
syntax = "proto3";
package users.v1;

message User {
  int32 id = 1;
  string name = 2;
  reserved 3;  // email was removed
  reserved "email";
  // Add new fields with new numbers
  string email_address = 4;
}

service UserService {
  rpc GetUser (GetUserRequest) returns (User);
  rpc ListUsers (ListUsersRequest) returns (ListUsersResponse);
}

// User service v2 - new package
syntax = "proto3";
package users.v2;

message User {
  int32 id = 1;
  string name = 2;
  string email_address = 3;  // Available since v1 reserved 3
  string created_at = 4;     // New field
}

// Add to existing service or create new
service UserService {
  rpc GetUser (GetUserRequest) returns (User);
  rpc ListUsers (ListUsersRequest) returns (ListUsersResponse);
  // New RPC
  rpc SearchUsers (SearchUsersRequest) returns (ListUsersResponse);
}
# gRPC version handling in Python
import grpc
from users.v1 import user_pb2, user_pb2_grpc
from users.v2 import user_pb2 as user_v2_pb2

# Server supporting multiple versions
class MultiVersionUserService(user_pb2_grpc.UserServiceServicer):
    def GetUser(self, request, context):
        user_data = fetch_user(request.id)

        # Check client version from metadata
        metadata = dict(context.invocation_metadata())
        version = metadata.get('api-version', 'v1')

        if version == 'v1':
            return user_pb2.User(
                id=user_data.id,
                name=user_data.name
            )
        else:
            return user_v2_pb2.User(
                id=user_data.id,
                name=user_data.name,
                email_address=user_data.email,
                created_at=user_data.created_at
            )

Common Mistakes

1. Reusing Field Numbers

Once a field number is used, never reuse it. Mark it reserved.

2. Changing Field Types

Protobuf field types must never change after deployment.

3. Removing Fields Without Reserved

Removed fields must be marked reserved to prevent reuse.

4. No Package or Version in Namespace

Use package users.v1 to allow parallel versions.

5. Breaking Wire Format Compatibility

Adding required fields or changing optional to required breaks compatibility.

Practice Questions

  1. What happens if you reuse a field number in Protobuf?
  2. How do you mark removed fields in Protobuf?
  3. How does gRPC handle multiple versions?
  4. What is the recommended package naming for gRPC versions?
  5. Is adding a new field backward compatible in Protobuf?

Answers:

  1. Old clients may decode data incorrectly, causing corruption.
  2. Use the reserved keyword for both field numbers and names.
  3. Through separate packages or services with versioned names.
  4. package company.product.v1, package company.product.v2.
  5. Yes, as long as the field number hasn't been used before.

Challenge: Define gRPC service versions v1 and v2 using Protobuf packages. Implement a gateway that routes to the correct version.

FAQ

Can I run v1 and v2 gRPC services simultaneously?

: Yes. Deploy them on different ports or use a gRPC gateway.

Is gRPC versioning easier than REST?

: Different. Protobuf's strict rules prevent mistakes but require careful planning.

What is the wire format compatibility in Protobuf?

: Field presence, types, and numbers must be backward compatible at the wire level.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro