Bird
Raised Fist0
Microservicessystem_design~25 mins

gRPC for internal communication in Microservices - System Design Exercise

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Design: Microservices Internal Communication using gRPC
Design focuses on internal communication between microservices using gRPC. Out of scope are external client communication, UI design, and persistent storage details.
Functional Requirements
FR1: Enable efficient communication between multiple microservices within the same infrastructure
FR2: Support synchronous request-response calls with low latency
FR3: Allow definition of clear service contracts with strong typing
FR4: Support multiple programming languages for microservices
FR5: Ensure secure communication between services
FR6: Handle service discovery and load balancing internally
FR7: Provide error handling and retries for transient failures
Non-Functional Requirements
NFR1: Must handle up to 10,000 requests per second across services
NFR2: End-to-end latency for internal calls should be under 50ms p99
NFR3: Availability target of 99.9% uptime for internal communication
NFR4: Use existing infrastructure without adding heavy new components
NFR5: Minimize network overhead and serialization costs
Think Before You Design
Questions to Ask
❓ Question 1
❓ Question 2
❓ Question 3
❓ Question 4
❓ Question 5
❓ Question 6
Key Components
gRPC server and client stubs generated from protobuf definitions
Service registry or discovery mechanism
Load balancer for distributing requests
TLS for secure communication
Monitoring and logging tools for tracing calls
Retry and timeout configurations
Design Patterns
API Gateway pattern for routing
Circuit Breaker pattern for fault tolerance
Client-side load balancing
Service mesh integration for observability and security
Protobuf schema versioning for backward compatibility
Reference Architecture
  +----------------+       +----------------+       +----------------+
  |  Microservice  | <---> |  gRPC Server   | <---> |  Microservice  |
  |     A          |       |  (Service B)   |       |     B          |
  +----------------+       +----------------+       +----------------+
          |                        |                        |
          | gRPC Client            | gRPC Server            | gRPC Client
          |                        |                        |
  +---------------------------------------------------------------+
  |                    Service Discovery & Load Balancer          |
  +---------------------------------------------------------------+
                              |
                              | TLS Secured gRPC Communication
                              |
                      +------------------+
                      | Monitoring & Logs |
                      +------------------+
Components
gRPC Server
gRPC with Protocol Buffers
Expose service APIs with strongly typed contracts for other microservices to call
gRPC Client
gRPC with Protocol Buffers
Invoke remote service APIs efficiently with low latency
Service Discovery
Consul / etcd / Kubernetes DNS
Enable clients to find available service instances dynamically
Load Balancer
Client-side or Envoy proxy
Distribute requests evenly across service instances
TLS Encryption
mTLS (mutual TLS)
Secure communication between microservices
Monitoring & Logging
Prometheus, Jaeger, Fluentd
Trace requests, monitor latency, and log errors
Request Flow
1. 1. Microservice A wants to call Microservice B's API.
2. 2. Microservice A's gRPC client queries the service discovery to get available instances of Microservice B.
3. 3. The client selects an instance using load balancing strategy.
4. 4. The client establishes a secure (mTLS) gRPC connection to Microservice B's gRPC server.
5. 5. Microservice A sends a request message defined by protobuf to Microservice B.
6. 6. Microservice B processes the request and sends back a response message.
7. 7. Microservice A receives the response and continues processing.
8. 8. Monitoring tools collect metrics and traces for this call.
Database Schema
Not applicable as this design focuses on communication protocols and infrastructure rather than data storage.
Scaling Discussion
Bottlenecks
Service discovery becoming a single point of failure under high load
Load balancer overwhelmed by large number of requests
Network bandwidth limits causing latency spikes
TLS handshake overhead impacting latency
gRPC server CPU or memory saturation
Solutions
Use highly available and distributed service discovery systems with caching
Implement client-side load balancing to reduce central load balancer pressure
Optimize network infrastructure and use compression for gRPC messages
Reuse TLS connections and enable session resumption to reduce handshake cost
Scale out gRPC servers horizontally and use autoscaling based on metrics
Interview Tips
Time: Spend 10 minutes clarifying requirements and constraints, 20 minutes designing the architecture and data flow, 10 minutes discussing scaling and trade-offs, and 5 minutes summarizing.
Explain why gRPC is suitable for internal microservice communication (performance, strong typing)
Discuss how service discovery and load balancing work together
Highlight security with mTLS for internal calls
Describe monitoring and observability importance
Address scaling challenges and practical solutions

Practice

(1/5)
1. What is the main advantage of using gRPC for internal communication between microservices?
easy
A. It requires no predefined message formats.
B. It provides fast, efficient, and strongly typed communication.
C. It only works with services written in the same language.
D. It uses plain text messages for easy debugging.

Solution

  1. Step 1: Understand gRPC communication benefits

    gRPC uses Protocol Buffers which are compact and strongly typed, making communication fast and reliable.
  2. Step 2: Compare with other options

    Options B, C, and D are incorrect because gRPC requires predefined message formats, supports multiple languages, and uses binary messages, not plain text.
  3. Final Answer:

    It provides fast, efficient, and strongly typed communication. -> Option B
  4. Quick Check:

    gRPC speed and typing [OK]
Hint: gRPC is fast and typed, unlike plain text or language-specific methods [OK]
Common Mistakes:
  • Thinking gRPC uses plain text messages
  • Assuming gRPC works only with one language
  • Believing gRPC needs no message definitions
2. Which of the following is the correct way to define a gRPC service method in a .proto file?
easy
A. method GetUser returns UserResponse(UserRequest);
B. service GetUser { rpc UserRequest returns UserResponse; }
C. rpc GetUser (UserRequest) returns (UserResponse);
D. function GetUser(UserRequest): UserResponse;

Solution

  1. Step 1: Recall gRPC .proto syntax

    In .proto files, service methods are defined using the syntax: rpc MethodName (RequestType) returns (ResponseType);
  2. Step 2: Validate options

    rpc GetUser (UserRequest) returns (UserResponse); matches the correct syntax. Options B, C, and D do not follow the .proto syntax for defining rpc methods.
  3. Final Answer:

    rpc GetUser (UserRequest) returns (UserResponse); -> Option C
  4. Quick Check:

    .proto rpc syntax [OK]
Hint: Remember: rpc Method(Request) returns (Response); in .proto files [OK]
Common Mistakes:
  • Using 'service' keyword incorrectly for methods
  • Confusing method syntax with programming language functions
  • Omitting parentheses around request and response types
3. Given the following gRPC client call in Python, what will be the output if the server returns a UserResponse with name='Alice' and age=30?
response = stub.GetUser(UserRequest(id=123))
print(f"Name: {response.name}, Age: {response.age}")
medium
A. Name: Alice, Age: 30
B. Name: 123, Age: 0
C. Name: , Age:
D. Error: stub.GetUser is not a function

Solution

  1. Step 1: Understand the client call and server response

    The client calls GetUser with id=123. The server responds with UserResponse containing name='Alice' and age=30.
  2. Step 2: Analyze the print statement output

    The print statement accesses response.name and response.age, so it will output the values returned by the server.
  3. Final Answer:

    Name: Alice, Age: 30 -> Option A
  4. Quick Check:

    Client prints server response fields [OK]
Hint: Client prints server response fields directly as returned [OK]
Common Mistakes:
  • Assuming client sends back request data instead of server response
  • Confusing method call syntax causing errors
  • Expecting empty or default values without server response
4. A developer wrote this gRPC service definition but the client fails to connect:
service UserService {
  rpc GetUser UserRequest returns UserResponse;
}
What is the error in this definition?
medium
A. Missing parentheses around request and response types.
B. Service name should be lowercase.
C. rpc keyword should be capitalized as RPC.
D. UserRequest and UserResponse must be strings.

Solution

  1. Step 1: Check gRPC method syntax in .proto

    The correct syntax requires parentheses around request and response types: rpc MethodName (RequestType) returns (ResponseType);
  2. Step 2: Identify the error in the given code

    The code misses parentheses around UserRequest and UserResponse, causing client connection failure.
  3. Final Answer:

    Missing parentheses around request and response types. -> Option A
  4. Quick Check:

    Parentheses required in rpc method signature [OK]
Hint: Always use parentheses around request and response in rpc methods [OK]
Common Mistakes:
  • Ignoring parentheses in rpc method definitions
  • Thinking service names must be lowercase
  • Misunderstanding rpc keyword casing rules
5. You have multiple microservices written in different languages that need to communicate internally with low latency and strict message contracts. Which approach best fits this scenario?
hard
A. Use REST APIs with JSON for all communication.
B. Use message queues with XML messages.
C. Use plain TCP sockets with custom binary protocol.
D. Use gRPC with Protocol Buffers for internal communication.

Solution

  1. Step 1: Analyze requirements for low latency and strict contracts

    Low latency and strict message contracts require efficient, strongly typed communication.
  2. Step 2: Evaluate communication options

    REST with JSON is flexible but slower and less strict. Plain TCP with custom protocol is complex and error-prone. Message queues add latency and XML is verbose. gRPC with Protocol Buffers is designed for efficient, strongly typed, multi-language communication.
  3. Final Answer:

    Use gRPC with Protocol Buffers for internal communication. -> Option D
  4. Quick Check:

    Low latency + strict contracts = gRPC [OK]
Hint: gRPC + Protobuf = fast, typed, multi-language communication [OK]
Common Mistakes:
  • Choosing REST despite latency and typing needs
  • Using custom protocols without standard tooling
  • Ignoring message size and parsing overhead