Jersey 3.1.1 released – focused on performance

Jersey 2.38 (Jakarta REST 2.1 compatible release) and Jersey 3.0.9 (Jakarta REST 3.0 compatible) have been released before Christmas. Jersey 3.1.1 is aligned with these releases.

Apart from minor features (JDK 20 support, less repetitive warnings) and fixes, the big improvement, contributed by our great community, is JUnit 5 test framework being the main test framework in Jersey. This affects also Jersey Test Framework, which is used not only for our testing Jersey but also by other vendors.

Mainly, we focused on performance. This time Jersey team cooperated with the Helidon team. They made a great job with Helidon 4 which uses the new JDK virtual threads (aka project Loom) in the Helidon Nima server to reach a great server throughput. The Jersey team improved some core functions in Jersey used by Helidon to reach even better performance.

The results follow. (Please understand the presented measurements are influenced by a number of factors, such as OS and its I/O handling, and the operations performed on the background during the measurements, the JDK used. The measurements are presented to give a brief idea rather than being the exact results occurring on each configuration.) 

Jersey performance boost, Jersey 3.1.0 vs 3.1.1, JDK 11, short 40 characters-long messages sent, for JSON, Jackson is used, the average number of requests per second:

HTTP request type Jersey 3.1.0 Jersey 3.1.1 Improvements in %
GET application/json 362 968 395 705 9%
GET text/plain 382 262 436 604 14%
POST application/json 220 199 274 489 24.5%
POST text/plain 221 283 281 236 27%

For larger messages, the situation is different. The HTTP POST text/plain messages have a major improvement since both clients and server use a performance-friendlier code to wire the message.

Jersey performance boost, Jersey 3.1.0 vs 3.1.1, JDK 11, long 40 000 character-long messages sent, for JSON, Jackson is used, the average number of requests per second:

HTTP request type Jersey 3.1.0 Jersey 3.1.1 Improvements in %
GET application/json 45 671 46 912 3%
GET text/plain 131 512 137 252 4%
POST application/json 18 085 18 250 1%
POST text/plain 34 407 47 797 39%

The improvements in Jersey are not the only factor that can speed up a Jersey application. The JDK version also matters (take the latest JDK of each version, as the early version can have much worse results):

JDK performance boost, Jersey 2.38, short 40 characters-long messages sent, for JSON, Jackson is used, the average number of requests per second:

HTTP request type JDK 8 JDK 11 JDK 19 JDK 8 – 19
GET application/json 415 772 416 755 421 863 14.6%
GET text/plain 421 027 435 172 447 476 6%
POST application/json 255 102 260 114 279 314 9.5%
POST text/plain 271 722 281 850 300 715 10.5%

For client-side performance, the ability of a user to reuse initialized clients is crucial. A client is a heavy object that looks for the JDK services, instantiates, and initializes all the registered objects, starts up a client injection framework, and gathers necessary components. The following table describes the difference between reusing created WebTarget for the particular URI with registered components and preset properties, and when the WebTarget is created for each request.

Client requests per second, Jersey 3.1.1, short 40 characters-long messages sent, for JSON, Jackson is used, the average number of requests per second:

HTTP request type Recreated Client and WebTarget Reused WebTarget
GET application/json 1 313 31 672
GET text/plain 1 326 32 960
POST application/json 1 302 27 329
POST text/plain 1 319 28 322

In conclusion, we may say for maximum performance, use the latest Jersey (2.38, 3.0.9, 3.1.1), up-to-date JDK, and reuse initialized WebTargets.

This entry was posted in Jersey. Bookmark the permalink.