Why Microservices Use RPC Instead of HTTP?

In a microservices architecture, services need to communicate frequently (for example, the order service calls the payment service, and the user service calls the permission service). The design characteristics of RPC (Remote Procedure Call) align perfectly with the core requirements of microservices —efficiency, simplicity, and strong contracts. Choosing RPC over simple HTTP (like RESTful) fundamentally addresses issues of efficiency, usability, and maintainability in inter-service communication, which can be understood from the following points:<span>....</span>

1. Microservices Communication Requires “Efficiency”, and RPC Pursues Efficiency

In a microservices architecture, services are split into fine-grained components (potentially dozens or even hundreds of services), and the frequency of inter-service calls is extremely high (for example, a user placing an order may trigger 5-10 cross-service calls). Communication efficiency directly impacts overall system performance. RPC has significant efficiency advantages over traditional HTTP, such as:

  • Binary protocol, which is smaller in size and faster to parse.
    • Major RPC frameworks (like gRPC, Thrift) default to using binary protocols (like Protobuf), which have a high data compression rate (the binary size of the same content is only 1/3 to 1/10 of JSON), and binary parsing does not require handling text format syntax (like JSON’s quotes and commas), resulting in much lower CPU overhead compared to text protocols.
    • In contrast, HTTP (especially HTTP/1.1) is based on text format (request headers + JSON/XML body), which not only results in larger data sizes (longer transmission times) but also consumes more computational resources during parsing.
  • Support for long connections and connection reuse. Most RPC frameworks default to using long connections (like gRPC based on HTTP/2, which supports multiplexing), avoiding the handshake overhead of establishing a TCP connection for each call in HTTP/1.1 (TCP three-way handshake and four-way handshake). In high-frequency calling scenarios (like thousands of inter-service calls per second), long connections can significantly reduce network latency and improve throughput.

2. RPC Makes Service Calls “As Simple As Local Function Calls”

One of the core goals of microservices development is to “reduce the cognitive burden of cross-service calls,” allowing developers to focus on business logic rather than network communication details. The design philosophy of RPC is precisely to “simulate local function calls,” with specific advantages as follows:

  • Strongly typed interface definitions that automatically generate code.
    • RPC typically relies on “interface definition files” (like gRPC’s<span>.proto</span> files, Thrift’s<span>.thrift</span> files), which clearly specify the function names, parameter types, and return value types (similar to function signatures in code). The framework can automatically generate client (Stub) and server (Skeleton) code based on the interface definition, so developers do not need to manually assemble request parameters or parse response data — for example, in Go using gRPC, you only need to call the generated<span>client.Pay( ctx, &req )</span>, just like calling a local function, without worrying about HTTP headers, URLs, serialization, and other details.
    • In contrast, HTTP (RESTful) requires manually constructing requests (like setting URL, Header, Body) and handling responses (parsing JSON, checking status codes), leading to redundant code that is prone to errors.
  • Built-in serialization/deserialization.
    • RPC frameworks come with efficient serialization tools (like Protobuf, Thrift), so developers do not need to manually handle the conversion of “object to byte stream” and “byte stream to object”;
    • In contrast, HTTP requires manually using JSON libraries (like<span>json.Marshal</span>/<span>json.Unmarshal</span>), and type checking and compatibility handling must be implemented by the developer.

3. RPC’s “Strong Contracts” Reduce Service Collaboration Costs

Microservices are developed collaboratively by multiple teams (for example, Team A develops the order service, and Team B develops the payment service), and the “contract consistency” of interfaces between services is key to avoiding collaboration chaos. RPC addresses this issue through “strong interface definitions”:

  1. Interface changes are traceable and verifiable.
    1. The interface definition file (like<span>.proto</span>) serves as the “contract document” between services, and all changes (like adding parameters or modifying return values) must be synchronized with this file, which can be traced through version control (Git). Some RPC frameworks (like gRPC) also support “interface compatibility checks” — if the server interface changes are incompatible with the old version (like deleting required parameters), errors can be reported at compile time, preventing runtime failures due to interface mismatches.
    2. In contrast, the interface contracts of HTTP (RESTful) typically rely on documentation (like Swagger), which often suffers from issues of untimely updates and manual maintenance omissions, and interface compatibility can only be discovered through online testing.
  2. Built-in service governance capabilities. Microservices communication requires not only “calls” but also “governance” (like load balancing, timeout retries, circuit breaking, monitoring, and tracing). Major RPC frameworks (like Dubbo, gRPC) have these capabilities built-in:
  • Load balancing: automatically distributing requests to multiple service instances (like round-robin, consistent hashing);
  • Circuit breaking: quickly returning default results when a service is unavailable to avoid cascading failures;
  • Monitoring and tracing: integrating link tracing (like Jaeger, Zipkin) to identify performance bottlenecks in cross-service calls. If using HTTP, these capabilities require additional components (like Nginx for load balancing, Sentinel for circuit breaking), leading to high integration costs and complex maintenance.

4. Microservices “Internal Communication” Requires RPC Features More

Microservices communication scenarios can be divided into two categories: internal service communication (like order → payment, user → permission) and external service communication (like front-end → back-end API, third-party calls to open interfaces).

  • External communication: needs to be compatible with different languages and platforms (like front-end using JavaScript, third-party using Python), emphasizing “universality,” thus more suitable for HTTP (RESTful/GraphQL) — because HTTP is a universal protocol that can be easily parsed by any language.
  • Internal communication: services are developed independently by teams (usually using a unified language, like all Go/Java), focusing more on “efficiency, usability, and maintainability,” where the advantages of RPC can be maximized, making it the preferred choice.

In summary, efficiency, simplicity, and strong contracts provide inherent advantages for extensive microservices development, which is why RPC is almost universally adopted in microservices.

Leave a Comment