I am working on a Java Web Application, using the following frameworks : Spring 3.1, JSF 2.1.26 and RichFaces 4.3.3.
The whole app is running in the Amazon Cloud under medium.m1 instances (2 - 2.4 Ghz single core), with a Tomcat 7.
My customer asked questions about the performances of the web application, and about the poor number of concurrent users that can be handled on the same server.
He gave me a report showing that a servlet with about the same hardware than the Amazon medium one is able to serve about 800-1000 requests per seconds (40KB page) :
I then decided to execute some tests on my application.
I removed the database, all filters (security, etc.) and keep a classic list page (header/footer + data table + sort/search/filters/data scroller...) with 20 visible rows.
The page takes about 300 ms to be loaded, without any load.
When I executed the load test for my application, I realize that it can only serve 20 requests per second before the request/response time exceeds the 1000 ms.
Can you tell me if this is a normal behavior?
I can understand a JSF page is longer to build than a simple servlet one, but not being able to serve more than 20 requests, while the servlet serve 1 000 seems quite strange.
Is there any standard benchmark for a typical JSF application?
If you think I have optimization problem, can you tell me where I can search?
Thanks in advance for your answer!
If it is "normal" is defined by so many factors, it is impossible to give any kind of answer to that. What I can answer is if it is acceptable: HELL NO.
I would do some tests by taking Richfaces out of the loop and in stead going for Primefaces; that improved my personal experience with JSF a whole lot already especially in the memory footprint but also to take down the overall page rendering time. JSF in itself is quite processing heavy (although that gets better with each new version, JSF 2.2 adds stateless support for example), I wouldn't expect the same kind of processing performance from it as you may get from the far more lightweight web frameworks.
PS: be sure that the performance problem is not somewhere else. If you for example have a hefty database query that is fired 3 times (once for each JSF lifecycle phase to render the page), then you're just doing it wrong yourself. JSF itself requires that you know how it ticks under the hood, unfortunately.
Thanks for your answer!
When you said 20 req/sec is not acceptable, can you give me a value that is acceptable for you?
I my tests, I removed the database access and have only dummy values in memory to minimize ORM impact.
For the memory, I also applied configuration values like:
Running Yourkit profiler gives me 1MB per session. I started my app with 700MB, so I assumed memory is not the problem:
In my load tests, I run 20 threads (20 sessions) making one request every seconds. The response time is about 1300ms.
I tried stateless views in JSF 2.2.4, and if it reduce the session memory to 10KB, it still give me about the same response time.
As I said, it depends on many factors. You can demand 200 concurrent users on a database driven web application, but if you then stick MySQL 3.0 under it, you can forget it. If users will be generating large PDFs very often using iReport, performance as a whole will suffer. If you have a very complex data model and you use an ORM package to query that model which results in hundreds of lazy fetches per request, you can forget it.
But I will work till my fingers bleed to at least guarantee 50 concurrent users operating smoothly, which may require investing in hardware and doing complicated optimization work such as implementing caching. For a normal website-ish application I would be ashamed if the application cannot handle 200 concurrent requests.
That's my personal opinion. It is useless to you and your situation. What's your opinion I wonder?