The performance of a dynamic web application can be quite unpredictable when you don’t know how many People are going to use it and of course how they are going to use it. You can predict some of the users’ behaviours and do your best to prepare your application to cope with the expected load. But sometime after the launch you suddenly find yourself in a situation where the performance of your application – or at least parts of it - is poor and the customer is unhappy. In cases like this typical reasons why you didn’t find the bottlenecks while developing are:
- more users than expected
- unpredicted behaviour of users
- the amount of data stored in the production database compared to the development database
- missing indexes on database tables
- slow queries that need optimizing besides adding indexes
- inefficient code
- insufficient resources on the servers
So before using the brute force approach by throwing more hardware at the problem, the most important task to accomplish first is to find the real bottleneck. Just like in war times good intelligence is your key to winning the battle. So gather information first.
- Find out which parts are slow and under which circumstances the performance is poor. Talking to actual users of the app is a good approach to do so.
- Monitor the servers using tools like munin. CPU and Memory usage can show you which part of the architecture is stressed. In some cases the webserver idles most of the time, while the database machine is under heavy load
- Check the Database for slow queries – most databases provide tools and statistics to determine the slowest queries. This will help you find out where indexes might be missing or which queries need optimizing
- When optimizing queries first look at the explain plan. It can point you to the problem directly.
- Check the DB for the most frequently executed queries – if a query is executed very often this might be a place where the application code needs optimizing or where caching might help. Add caching wherever the same piece of infrequently changing data is shown to many users many times. A great roundup on open source Java cache implementations can be found here.
- Use a profiler to find out where in your code the application gets stuck. Chances are high that you end up locating the place where one of the slow queries is executed
Then start optimizing the parts you expect the most performance boost from. Be careful though when adding indexes on database tables with huge amounts of data – check if there is sufficient disk/table space available on the RDBMS. Indexes can also have effects on the performance of write operations.
If all this brain doesn’t solve the problem you might need to add muscle to your hardware:
- Scale vertically by adding RAM and increasing CPU
- Scale horizontally by adding machines, which is a lot easier for web servers as it is for database servers
- An excellent piece of literature on this topic is “Scalable Internet Architectures” by Theo Schlossnagle
Take care…
Alex
