Hibernate Validator Performance


 Posted on September 30, 2023

Recently I was investigating a performance problem in a Spring Boot application using Spring Data and Postgres. A request to load a list of items took half a minute. I quickly realized that loading 1'600 items issued 20'000 database requests. After a quick optimization that brought down the number of queries to less than 200 the request still took 15 seconds. I decided that it was time to use a profiler and was surprised to see that almost all time was spent in methods of the Hibernate Validator.

The items were nested and there might be something like 20 annotations in the tree but most of them were just NotNull. I would never have expected this to be so slow.

Experiment

I created a small example application to validate the behavior in a fresh and barely empty application.

There are three classes.

  • City that contains a list of buildings
  • Building that contains a list of residents
  • Person with a name that shouldn’t be null

I once used the Java Bean Validation Annotations and also made a simple custom implementation. Then I measured the execution time twice (first time might have some warmup included) with a small graph containing about 20 objects and a large graph containing about 100'000 objects.

The measurements:

Technology # objects first run second run
Java Bean Validation 20 63ms 1ms
Custom 20 0ms 0ms
Java Bean Validation 100'000 1258ms 647ms
Custom 100'000 39ms 4ms

Hardware: Dell XPS 13 9343 with 8 GiB memory and a core i7-5500U.

Technology: Spring Boot 3.1.4 with Hibernate Validator 8.0.1.

I am aware that this is just a very simple benchmark but I think it is enough to prove the point.

Conclusion

The hibernate validator was easily 150 times slower than a custom implementation. Even for a rather small object graph and only validating one nested constraint it took more than half a second while a custom implementation took less than 10 milliseconds. In real life this might be the difference between having a customer or losing him.

It’s always good to remember that even tough it is nice to just use a bunch of annotations to validate everything, there might be quite some performance hit doing that.