Java vs GO. Testing a large number of users

Motivation


Microservice architecture allows you to choose between technologies and programming languages ​​when writing REST api services. Which language is better to choose to write a REST api application to provide a greater number of simultaneous users with a fast and stable response on the same hardware? To answer this question it would be nice to see the difference in the performance of the same application written in Java and GO.

Disclaimer


All results presented in this experiment are a particular example of using Java and GO and should not be used to describe the performance of these languages ​​in other conditions.

Conditions / Restrictions


  • No additional settings to increase performance. The frameworks and libraries should be used with default settings.
  • No ORM frameworks. Only database drivers and the same requests in both applications.

Plan


  1. Create two simple REST api applications in Java and GO with PostgreSQL database
  2. Create load tests with Jmeter
  3. Run each application, database, and tests on separate AWS instances.
  4. Run the tests and collect the results

Test application


As a system for testing, I created two applications: bank-java and bank-go . This is probably the easiest bank application in the world. All that it knows how to do is create new clients with an initial balance, transfer funds from one client to another and show the balance.
API:

  • Post / client / new / {balance} - creates a client with an initial balance
  • Post / transaction - transfers funds from one client to another
  • Get / client / {id} / balance - shows balance

Libraries and Libraries


When choosing those stacks, I used the newest, most popular and simple frameworks and libraries to implement the necessary functionality as quickly as possible.
Bank-java: Java 11, spring boot 2.0.4, spring-web 5.0.8, PostgreSQL JDBC 4.2.4
Bank-go: Go 1.8, gorilla / mux, github.com/lib/pq

Test environment


AWS was used as a test environment.

The following EC2 instances were created:

  1. Bank-go t2.micro (Variable ECUs, 1 vCPUs, 2.5 GHz, Intel Xeon Family, 1 GiB memory, EBS only)
  2. Bank-java t2.micro (Variable ECUs, 1 vCPUs, 2.5 GHz, Intel Xeon Family, 1 GiB memory, EBS only)
  3. Postgres d2.xlarge (14 ECUs, 4 vCPUs, 2.4 GHz, Intel Xeon E52676v3, 30.5 GiB memory, 3 x 2048 GiB Storage Capacity)
  4. Bank-test t2.2xlarge (Variable ECUs, 8 vCPUs, 2.3 GHz, Intel Broadwell E5-2686v4, 32 GiB memory, EBS only)

All instances use Ubuntu Server 18.04 LTS (HVM), SSD Volume Type



Test project


The Jmeter test calls each API from the list above, checks that the response status is 200, and the response body contains the id. For each application I launched it with the number of simultaneous users 1000, 2000, etc. up to 10,000.

The full log of results can be found here .

Aggregated results








Description of Results


Both applications work perfectly with the number of users 1000. Starting from 2000 GO, the application starts to lose significantly in performance and slightly in stability. In Java, this milestone starts at 3000.

Conclusion


Using the same REST api hardware, a Java application can support twice * more concurrent users than a GO application with a PostgreSQL database.

* This figure is correct only when using the same test conditions as in this experiment.

Also popular now: