Skip to content

Messages in Protocol Buffers — Complete Guide

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Messages in Protocol Buffers. We cover key concepts, practical examples, and best practices to help you master this topic.

Messages are the core data structure in Protocol Buffers. Each message defines a set of typed fields that can include scalars, enums, other messages, repeated lists, maps, and oneof groups. Messages can be nested for logical organization.

What You'll Learn

  • Message definition with typed fields
  • Repeated fields for arrays/lists
  • Map fields for key-value pairs
  • Oneof for mutually exclusive fields
  • Nested message types

Why It Matters

Messages define the shape of all data exchanged in gRPC. Well-structured messages reduce parsing errors, improve schema readability, and enable efficient Serialization.

Real-World Use

Google's pub/sub API uses messages with oneof for different delivery types. gRPC health checking uses a simple message with a serving status enum. Kubernetes uses deeply nested messages for resource specifications.

flowchart TD
    Message[Message Definition] --> Scalar[Scalar Fields]
    Message --> Repeated[Repeated Fields: list]
    Message --> Map[Map Fields: key-value]
    Message --> Oneof[Oneof: mutually exclusive]
    Message --> Nested[Nested Messages]
    Repeated --> Element[Element type: string, int32, Message]
    Map --> Key[Key type: string, int32]
    Map --> Value[Value type: any type]

Teacher Mindset

Design messages to be self-contained and reusable. Use nested messages for logical grouping. Use oneof to represent variant data. Use maps sparingly as they cannot be repeated in proto3.

Code Examples

// Example 1: Message with all field types
message Product {
  string id = 1;
  string name = 2;
  repeated string tags = 3;
  map<string, string> attributes = 4;
  oneof price_model {
    double fixed_price = 5;
    double starting_bid = 6;
    string contact_for_price = 7;
  }
  Category category = 8;
}
// Example 2: Nested messages
message Customer {
  string id = 1;
  string name = 2;

  message Address {
    string street = 1;
    string city = 2;
    string zip = 3;
    string country = 4;
  }

  repeated Address addresses = 3;

  message Preferences {
    bool newsletter = 1;
    string currency = 2;
  }

  Preferences preferences = 4;
}
// Example 3: Messages with imports
import "common/price.proto";
import "common/media.proto";

message Listing {
  string id = 1;
  string title = 2;
  Price price = 3;
  repeated Media images = 4;
  string description = 5;
}

Common Mistakes

  • Nesting messages too deeply, making Code Generation verbose
  • Using map when a repeated message field with key-value semantics is more flexible
  • Making messages too large with many optional fields
  • Forgetting that map fields cannot be repeated or have proto3 required semantics
  • Not separating large messages into smaller, reusable units

Practice

  1. Create a message with scalar, repeated, map, and oneof fields.
  2. Define a nested Address message inside a Customer message.
  3. Use oneof for a payment method that can be card, paypal, or crypto.
  4. Create a message that imports another message from a different file.
  5. Challenge: Design a deeply nested Order message with Customer, LineItem, Shipping, and Payment sub-messages.

FAQ

What is the maximum number of fields in a message?

A message can have up to 2^29 - 1 fields (about 536 million), but practical limits are much lower due to code size.

Can I have a repeated field of maps?

No. proto3 does not support repeated map fields. Use a repeated message field with key and value fields instead.

What is the difference between nested and top-level messages?

Nested messages are scoped within another message. Top-level messages are globally accessible. Choose based on whether the type is used elsewhere.

How do oneof fields work?

Only one field in a oneof group can be set at a time. Setting any field clears all others. This is useful for union-like patterns.

Can messages contain themselves recursively?

Yes. Messages can reference themselves for tree-like structures, but use a nested type or forward declaration.

Mini Project

Design a complete set of messages for an order management system: Customer (with nested Address), Product, OrderItem, Payment (with oneof for payment methods), and Order (combining all with repeated items).

What's Next

Next, you will learn about nested types and how to organize complex message hierarchies.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro