Load testing in the cloud!
It’s interesting times for running online apps!
We’ve just launched an online viral competition for the clothing company Fat Face at http://www.fatfacechristmas.co.uk/
The idea behind this application is that the more friends you get to sign up from your own entry page, the more chance you stand of winning. Therefore, with any luck, it should see a sizeable amount of traffic.
I wanted to make sure this app would behave under sufficient load, so I needed to do a bit of load testing on it. I was lucky enough to spend a few days with a performance consultant a few years back who was trying to get one of my apps to run better under load. After we were done, with a few code tweaks and a new server, it went from dealing with about 5 simultaneous users to about 5000. This experience really opened my eyes to the importance of performance testing, but in this day of rapid app development, it’s difficult to find the time.
What do you need to load test?
- A working app you already think is working well - make your car road-worthy before taking it for a drive!
- Some software to run automated tests.
- A big hammer! You need to throw a lot of data at your app.
There’s no point load testing an application on your broadband connection, because you have a limited amount of connectivity. However, with the cheap availability of on-demand serversĀ it’s now very easy, quick, and cheap to run load testing.
Here’s what I did.
- Used elastic fox to load up a Windows 2003 server on Amazon EC2.
- Install my web testing software. I used a great product from Webload… it’s free and is very easy to use. There’s also loads of other great products such as WAPT but, for the price, you can’t beat Webload.
- Record a macro of a user signing up for the competition.
- Tweak the code to get around a primary key constraint.
- Run some tests!
Most windows load testing software I’ve used has a very easy to use macro recording system (point 3). You hit record, carry out some actions on your website, and then close the browser. The actions are then saved as a script ready to be played back by your ‘virtual users’. The good thing about Webload is it saves these macros as javascript. This makes them very easy to tweak. For example, on our competition you can only sign up with a single email address once or an error will be thrown. I simply tweaked the macro I recorded to generate a random email adress.
Once I had my test script, I loaded it in to the app to run and set it up to throw 1, 10, 30, 100, 250, 500 and 1000 simultaneous virtual users at the application with a minute between each batch of users. It’s important to test a range of different user amounts and leave enough time between for the server to settle down so that you can see the point at which the application starts to slow down.
Here are my results from a single run:
| Time | Total\Load Size\Current Slice Sum (Current Value) | Total\Hits Per Second\Current Slice Sum (Current Value) | Total\Round Time\Current Slice Average (Current Value) | Total\Throughput (Bytes Per Second)\Current Slice Sum (Current Value) |
| 20 | 0.993 | 7.050 | 5.677 | 35912.700 |
| 40 | 1.000 | 6.350 | 5.838 | 28917.050 |
| 60 | 1.141 | 5.600 | 8.177 | 28493.100 |
| 80 | 10.000 | 55.650 | 6.509 | 289286.050 |
| 100 | 10.000 | 57.850 | 6.782 | 270822.850 |
| 120 | 10.160 | 59.650 | 6.879 | 278374.900 |
| 140 | 30.000 | 176.800 | 6.290 | 903521.650 |
| 160 | 30.000 | 159.950 | 6.974 | 762070.450 |
| 180 | 30.145 | 167.950 | 6.665 | 817014.350 |
| 200 | 50.000 | 255.750 | 7.194 | 1275021.150 |
| 220 | 50.000 | 268.050 | 7.402 | 1280076.650 |
| 240 | 50.007 | 257.300 | 7.467 | 1234566.800 |
| 260 | 99.764 | 417.800 | 8.802 | 2131676.200 |
| 280 | 100.000 | 385.550 | 9.192 | 1811236.050 |
| 300 | 100.000 | 385.900 | 10.279 | 1771745.250 |
| 320 | 218.330 | 398.800 | 12.851 | 2371275.050 |
| 340 | 250.000 | 424.050 | 24.664 | 1986619.250 |
| 360 | 250.000 | 280.050 | 21.153 | 1278824.000 |
| 380 | 327.717 | 488.500 | 26.478 | 2608235.900 |
| 400 | 499.907 | 398.900 | 27.305 | 2414733.850 |
| 420 | 500.000 | 211.250 | 40.119 | 759304.950 |
| 440 | 500.000 | 532.850 | 50.972 | 2575488.300 |
| 460 | 574.427 | 380.650 | 48.067 | 2009676.350 |
| 480 | 949.021 | 306.400 | 50.905 | 1530839.750 |
You can see at 320 secondswhen it jumpy from 100 users to 250 simultaneous users we get a significant delay in response time.
It’s important to check what the server is up to whilst all of this is going on. I’m quite new to running linux boxes, but two good commands for doing this are free -m to show memory usage top (hold shift-m to order by memory use). This is great for seeing at what point the pysical memory runs out and the server starts swapping.
At the point it started to slow down considerably you can also see that the data throughput doesn’t change a lot. If you convert this to megabits it’s throwing about 15 megabits per second at the server. It’s quite realistic at this point that were’re coming up against the limit of what a single server can send or receive so if we wanted to take the test further we’d actually need multiple testing servers and we might need more than a single server on the app end to increase performance.
With Amazon EC2 you can easily save the state of a server (AMI - Amazon Machine Instance) so that you can quickly access it again. This means you can keep a ‘load testing’ server and call it up whenever you need it in the future.
I didn’t need to take my load testing much further than this as I was very happy with the performance.
Here’s some simple things to consider when ensuring your app runs quickly.
- Offload static files JS, CSS, images to something like S3 or a CDN. If your server doesn’t have the throughput to serve data, it won’t make any difference how fast your app is.
- Make sure your server isn’t swapping and has enough pysical memory.
- Make sure you database server has enough query cache.
- Use something like eAccellerator to cache your PHP compiles.
- Cache output and hit your database a bit less.

Comments
Add a comment