packagemain.tech

packagemain.tech

Performance Benchmarking: gRPC+Protobuf vs. HTTP+JSON

A fair benchmark with Go examples to compare Protocol Buffers over gRPC vs. JSON over HTTP/1 and HTTP/2.

Alex Pliutau's avatar
Alex Pliutau
Jun 17, 2024
∙ Paid

While human-readable JSON over HTTP remains a popular choice for service communication due to its simplicity and familiarity, in Microservices architectures gRPC is emerging as a popular choice for communication.

It is mainly because in the case of internal services, the structured formats, such as Protocol Buffers, are a better choice than JSON for encoding data.

So we wanted to experiment with performance benchmarking of 2 types of communication in Go. It's important to note that results might vary across languages due to implementation specifics.

Comparing Apples to Apples

To isolate the performance impact of data transport and serialization protocols, we designed both the gRPC and HTTP endpoints to avoid any extraneous operations like database calls or memory-intensive computations. By minimizing the function's footprint, we ensure that the benchmark primarily reflects the performance differences between Protobuf over gRPC and JSON over HTTP.

It’s important to note that this benchmark was conducted on my local machine, providing a relative comparison of gRPC and HTTP performance. Real-world performance may vary depending on hardware, network conditions, and specific workloads.

Also this benchmark is a starting point for exploration and is only valid for this tiny example.

gRPC Service

Our gRPC service will have a single procedure CreateUser that accepts user information as input and returns some generic response. We will mimic the same format in our HTTP+JSON server as well.

grpc/users.proto

syntax = "proto3";

option go_package = "grpc/gen";

service Users {
  rpc CreateUser(User) returns (CreateUserResponse) {}
}

message User {
  string id = 1;
  string email = 2;
  string name = 3;
}

message CreateUserResponse {
  string message = 1;
  uint64 code = 2;
  User user = 3;
}

Now, let's use the protoc command to create the building blocks for our service. This includes generating the Go code for both the server (unimplemented) and the client from our users.proto file.

protoc -I./grpc --go_out=. --go-grpc_out=. users.proto
User's avatar

Continue reading this post for free, courtesy of Alex Pliutau.

Or purchase a paid subscription.
© 2026 Aliaksandr Pliutau · Privacy ∙ Terms ∙ Collection notice
Start your SubstackGet the app
Substack is the home for great culture