Using gRPC in microservices communication and performance results between different languages

Ümit Çebitürk
Trendyol Tech
Published in
4 min readJan 29, 2023

Hello everybody,

In this article, I will talk about the work that we have done to improve communication performance between services, in a project that was developed with microservice architecture by the TDesk team in Trendyol.

TDesk is an application that was located behind an API gateway and has so many domain services that developed different languages. The communication is provided with REST architecture and HTTP way between API gateway and services.

After some investigation to improve communication performance, we decided to make a POC about gRPC and we would like to share our experience about this process.

In many sources on the internet, we can see that the gRPC method provides a significant performance gain compared to REST. At this point, we would like to find answers to following questions in our minds:

  • Can we communicate with gRPC between services that developed different languages?
  • What is the performance impact of using gRPC between services that developed different languages?
  • How are performance results affected under the high traffic load?

During our work, we will implement REST API, gRPC Client and gRPC Server to Java and .Net languages. Also we will use the Unary method for gRPC communication because it’s more suitable for our scenario. For example, for a Category entity, An API Gateway that was developed with REST architecture will connect with a domain service that works for CRUD processes. Afterwards we will observe the performance effect of this communication for the same and different languages too.

.NET Protofile implementation

First of all, let’s create a common proto project to use in .NET gRPC Client and gRPC Server projects.

Let’s add our category.proto file.

.NET gRPC Server implementation

Let’s create an ASP.NET Core project for gRPC Server and add our gRPC proto project to the project references.

Let’s create the CategoryServer class, which is inherited from the CategoryService.CategoryServiceBase class that we generated with the Protofile. This class will assume the gRPC Server role here.

Finally, let’s define our services and middlewares in the Program.cs file.

.NET gRPC Client implementation

Let’s create an ASP.NET Core project for gRPC Client and add our gRPC proto project to the project references.

Let’s create the CategoryController class to provide REST communications. In here, we inject CategoryService.CategoryServiceClient for the gRPC Client role.

Finally, let’s define our services and middlewares in the Program.cs file.

Java Protofile implementation

First of all, let’s create a common proto project to use in Java gRPC Client and gRPC Server projects.

Let’s add our category.proto file.

Java gRPC Server implementation

Let’s create a Java Spring Boot project for gRPC Server that uses the grpc-server-spring-boot-starter library and add our gRPC proto project to the project references.

Let’s create the CategoryServer class, which is extended from the CategoryServiceGrpc.CategoryServiceImplBase class that we generated with the Protofile. This class will assume the gRPC Server role here.

Java gRPC Client implementation

Let’s create a Java Spring Boot Web project for gRPC Client that uses the grpc-client-spring-boot-starter library and add our gRPC proto project to the project references.

Let’s create CategoryService class for gRPC Client implementation. We inject CategoryServiceGrpc.CategoryServiceBlockingStub class for the gRPC Client role.

Let’s create the CategoryController class to provide REST communications.

After completing the implementations, let’s start our tests.

We used Apache JMeter to test our services. We ran all of our applications in a local development environment. Then we created a test scenario that will do requests with 100k per/min throughput for each endpoint as concurrent and tested with the below following scenarios. After all, we got these results.

Scenario-1:

  • An API Gateway built with Java Spring Boot (gRPC Client)
  • A domain service built with Asp.Net Core (gRPC Server)
Java to .Net

Scenario-2:

  • An API Gateway built with Java Spring Boot (gRPC Client)
  • A domain service built with Java Spring Boot (gRPC Server)
Java to Java

Scenario-3:

  • An API Gateway built with Asp.Net Core (gRPC Client)
  • A domain service built with Java Spring Boot (gRPC Server)
.Net to Java

Scenario-4:

  • An API Gateway built with Asp.Net Core (gRPC Client)
  • A domain service built with Asp.Net Core (gRPC Server)
.Net to .Net

After our tests, we see that:

  • It’s possible to establish a healthy communication using gRPC between microservices that are developed in different programming languages.
  • By the tests for Java and .Net languages, there isn’t any performance loss in communication using gRPC between microservices that are developed in different programming languages.
  • Our endpoints can respond in less than 0 ms on average in our tests for 100k per/min throughput.

As a result, you can prefer gRPC as an alternative to REST that is mostly used in communication between services . In this way, more efficient communication can be achieved between services. Also, it can be used smoothly between services that are developed in different languages.

--

--