Performance Concern: High Latency and Low Throughput in gRPC Java Setup

233 views
Skip to first unread message

Mansoor Shaik

unread,
Oct 16, 2025, 9:10:21 AMOct 16
to grpc.io

Hello gRPC Team,


I hope you are doing well.

I am currently working on evaluating gRPC Java performance as part of a sample setup, and I wanted to share an issue I’m facing that seems performance-related.

 

I have implemented a minimal gRPC server and client setup using Java + Maven, following the official example provided on the gRPC Java documentation site( https://grpc.io/docs/languages/java/quickstart/The build and execution both complete successfully — however, the observed performance is much lower than expected.

 

When I run the server and client locally on the same machine, I notice that in one second, the client can only perform around 200–500 gRPC synchronous calls using synchronous stubs. I expected much higher throughput, given that gRPC is designed to provide significant performance benefits compared to RMI-based APIs.

 

As a comparison, when I tested a Java RMI-based setup under similar conditions, benchmark results it achieved 7,684 calls per second

 

I’ve ensured that the implementation strictly follows the example code, including .proto generation and Maven dependency configuration.

Below are the technical details and the steps I’ve already verified:

 

 Environment Details

  • Language: Java
  • Build Tool: Maven
  • Framework: gRPC Java (sample from official documentation)
  • Java Version: 24
  • Operating System: Windows 11
  • Hardware: 8 GB RAM, Intel i5 Processor

Kannan Jayaprakasam

unread,
Oct 22, 2025, 2:16:13 AMOct 22
to grpc.io
Are you reusing the ManagedChannel for making all the RPC's or recreating it for each RPC? Reusing the channel is the way to go since the connections don't need to be reestablished.

Mansoor Shaik

unread,
Oct 22, 2025, 10:13:55 AMOct 22
to grpc.io

Dear gRPC Team,

I hope you are doing well.

I am testing gRPC Java performance using the official HelloWorld example (Maven-based) from the gRPC GitHub repository:

🔗 https://grpc.io/docs/languages/java/quickstart/

The project runs correctly, and I made a small modification in the client code to measure how many RPC calls can be executed within 1 second — just to check the performance benchmark.

 

Setup Details

  • Language: Java
  • Java Version: 24
  • Build Tool: Maven
  • IDE: Spring Tool Suite (STS)
  • Operating System: Windows 11
  • Memory Allocation: 64 MB each (client and server)
  • Connection: localhost

 

Modification

I modified the client to run a simple loop that repeatedly calls sayHello() for 1 second and counts the total number of RPCs executed.

Below is the modified section of the code in the client:

 

long startTime = System.currentTimeMillis();
int callCount = 0;

while (System.currentTimeMillis() - startTime < 1000) {
    blockingStub.sayHello(request);
    callCount++;
}

long maxMem = Runtime.getRuntime().maxMemory() / (1024 * 1024);
System.out.println("In 1 second, gRPC method called " + callCount +
                   " times, allocated memory = " + maxMem + " MB");

Everything else in the project (server and client) is the same as the official gRPC example.

 

Result

  • gRPC Java: 200–500 calls/second


I have attached performance client file, please review it.. HelloWorldPerformaceClient

Mohammad Emran

unread,
Oct 23, 2025, 12:33:42 AMOct 23
to Mansoor Shaik, grpc.io
Hi,
What is the benchmark result by ghz benchmark tool? 


On 22 Oct, 2025, at 8:13 PM, Mansoor Shaik <shaikman...@gmail.com> wrote:


--
You received this message because you are subscribed to the Google Groups "grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email to grpc-io+u...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/grpc-io/c8c7daf8-d3fd-45c1-9ae2-6bc79baa973fn%40googlegroups.com.

Adam Lazur

unread,
Oct 24, 2025, 11:59:49 AMOct 24
to grpc.io
The JVM needs time to warm up. 1 second is hilariously short for a performance test. In some not-so-serous benchmarking I warm up the JVM for 120s, then run a few minutes of load to let things normalize.

You could probably use multiple connections from client to server, unless you're looking for a blocking single connection test?

There are probably other things to tweak or tune, but posting code snippets isn't a great way to allow someone to help. I'd recommend posting a full example to github.

.laz

Empowering the world to design
We're hiring, apply hereCheck out the latest news and learnings from our team on the Canva Newsroom.
  https://www.linkedin.com/company/canva https://instagram.com/canva

Shubham Raj

unread,
Nov 13, 2025, 10:43:00 AMNov 13
to grpc.io
You are making the sync call. Is is possible for you to try ClientCalls.asyncUnaryCall and share the result. I anticipate the result will be much better.

 Also instead of 1sec, can we do for 10 second and then divide the result by 10. I would be happy to discuss with you further on these details.

Thanks,
Shubham Raj

Mansoor Shaik

unread,
Nov 14, 2025, 11:22:18 AMNov 14
to grpc.io

Hi Team,

Thanks for taking a look. I ran a practical benchmark comparing gRPC (Java) and Java RMI in my environment and I’m seeing an unexpectedly large gap in synchronous call throughput. I’d appreciate your thoughts — whether I’ve missed something in the setup, or if there’s anything I should change in the client/server configuration or test approach.

 

What I ran (attachments)

I’ve attached two test projects (each contains a README with build/run instructions):

  • grpc.helloworld.example.7z — sample gRPC server + client
    • I am using the same channel and stub for making synchronous gRPC calls to the server.
    • In my production environment there is no possibility for warm up.
  • JavaRmi.7z — sample Java RMI server + client

Both are simple sync-call examples intended to reproduce real-world synchronous RPC behavior.

 

Environment

  • Language: Java (JDK 24.0.1)
  • Build tool: Maven 3.9.10+
  • OS: Windows 11
  • Hardware: Intel i5, 8 GB RAM
  • Both server and client were run locally on the same machine during tests.

 

What I expected

gRPC is generally positioned to provide high-throughput RPCs; I expected synchronous gRPC stubs to be able to achieve much higher calls/sec when server and client run locally.

 

What I observed

  • gRPC (synchronous stubs): ~200–500 calls/sec (per-second window during my run)
  • Java RMI (similar test) : 7,684 calls/sec

This large difference surprised me — the RMI result is an order of magnitude higher than the gRPC synchronous result on the same machine and roughly the same test semantics.

 

I expected gRPC to perform much better based on official benchmarks. You can refer to the gRPC benchmark results here:

🔗 https://grafana-dot-grpc-testing.appspot.com/?orgId=1

 
I’ve shared the gRPC and RMI project folders through the links below. Please review them and let me know your observations.

grpc.helloworld.example.7z:   https://drive.google.com/file/d/1adgUszOWfKd-dIEh_rc9q0ApSQb_jUjI/view?usp=drive_link


JavaRmi.7z : https://drive.google.com/file/d/1bf5AR1ZcZcCI_T4NY15h-i3EU6xJnaQL/view?usp=drive_link



I have already verified the setup and followed the official gRPC Java example. Could you please check if there’s anything wrong in my setup or suggest how I can improve the synchronous call performance?

 

Best regards,

Mansoor

Mansoor Shaik

unread,
Dec 1, 2025, 11:50:56 AM (2 days ago) Dec 1
to grpc.io

Hi Shubham,

 

As per your suggestion, I updated the implementation to use ClientCalls.asyncUnaryCall and also tested the execution for 10 seconds instead of 1 second.

 

Below are the results:

Server

  • The server compiles and runs successfully.
  • No issues were observed on the server side after switching to async calls.
  • Server logs confirm it is operating normally:
    “Server started, listening on 50051…”

 

Client Issue – OutOfMemoryError

When running the async performance client, I am consistently getting the following error:

java.lang.OutOfMemoryError: Java heap space

 

 

What I Observed

  • The async client is generating a very large number of requests in a short period of time.
  • This leads to the creation of many threads, causing memory usage to continuously increase.
  • After some time, the JVM runs out of heap space and throws the OutOfMemoryError.

 

Detailed Findings

  1. I had to increase the heap size on both the server and client from 64MB → 512MB to run the async client for 1 second without failure.
    • With this configuration, the 1-second async test completed successfully and processed around 182527 calls.
  2. For the 10-second test, even after increasing memory to 1024MB, the client still ran out of memory.
  3. I noticed that the gRPC server sends final notifications only after the client shuts down the channel.
    I had to tune termination settings to get a stable 1-second test, e.g.:

    channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
  4. When load increases, both memory configuration and termination timing become critical.
    This also raises questions about how garbage collection behaves under heavy asynchronous load.


    I have also attached the Running version folder for your view.
    https://drive.google.com/file/d/1NHcp2TjKBw9h8z4TXiuS4jSrc5Mr0cam/view?usp=sharing

 

 

Thanks,

Mansoor

Reply all
Reply to author
Forward
0 new messages