Real-world performance of the Play framework on EC2

Recently there have been discussions about the performance of the play framework, after a large collection of web framework test results has been posted on TechEmpower.

Play does well on these tests, but it’s not exceptionally fast. In the article, simple JSON responses are tested on an EC2 large instance, one of Amazon’s faster virtual servers. According to the authors,

  • Play serves ~9000 requests/sec
  • PHP serves ~4000 requests/sec
  • Netty serves ~40000 (!) requests/sec

… just to name a few of the tested frameworks.

Netty was the fastest “framework” in the test, but it’s actually more a web server than a web framework. As a side note, Play uses Netty for serving HTTP requests.

But how how does that compare to a real-world scenario?

Testing what users (and their browsers) really do

Since we’re also using the play framework (2.1.1-scala) in production, we wanted to see how many pages per second we can really serve in our Amazon EC2 environment.

In contrast to the above article, the following results are obtained by load-testing complete pages that we use in production. This means that we download not only the HTML from the server, but also all images, CSS, Javascripts, like normal browsers do.

There were 3 different tests, run on EC2 micro and large instances. (Look how much you can do with a micro instance!)

Test 1 – Small page with database access

A small page with CSS, Javascript, and a picture. It also selects data from a MySQL database, but it’s a simple indexed query. We use Slick for database access.

  • Total page size: 30 kb
  • Total # of requests per page: 4 (Html, Css, Javascript, Png-Image)
  • EC2 Micro Instance result: 30 pages/sec  (120 requests/sec)
  • EC2 Large Instance result: 600 pages/sec (2400 requests/sec)
  • Bottleneck: CPU

Test 2 – Page with lots of content

A larger page with CSS, Javascript and lots of pictures. No database query here. The page is multi-language and uses Play’s Internationalization feature.

  • Total page size: 900 kb
  • Total # of requests per page: 15 (Html, Css, Javascript, 10 Png-Images)
  • EC2 Micro Instance result: 8 pages/sec  (120 requests/sec)
  • EC2 Large Instance result: 90 pages/sec (1350 requests/sec)
  • Bottleneck: Disk/Bandwidth

Test 3 – On-the-fly server-side image resizing

In this test, just one request is made. The server loads a JPEG image from an Amazon S3 bucket, resizes it from 800×600 to a 300×225 thumbnail, and sends it again JPEG-encoded to the client.

  • Total response size: 12 kb
  • Total # of requests: 1 (JPEG-Image)
  • EC2 Micro Instance result: 4 requests /sec
  • EC2 Large Instance result: 160 requests /sec
  • Bottleneck: CPU (the image rescaling algorithm)

: We can serve quite a lot of users with the play framework, using its default settings. Because we did not optimize our code for the benchmarks, we could not serve as many requests as in the article on TechEmpower; but the results are in the same ballpark.

Surprising EC2 micro instance performance

The EC2 micro instances can actually sustain quite a high number of requests per second. If you need to serve 30 full page requests per second (like in Test 1) during peak hours, you’ll probably serve an average of 8 requests per second during the day (4 times less). That’s about 20 GB of data per day, which means you will actually pay an order of magnitude more for the traffic than for the virtual server itself.

(However, running a production server on a micro instance may not be your thing. AWS allows only around 16% of sustained CPU usage on these instances, meaning it’s trivial to DoS-attack your server.)

From an economic perspective, play’s performance means you will be able to focus on other issues, such as saving bandwidth ;-)

This entry was posted in Play framework and tagged , . Bookmark the permalink.
  • Zafer Mohamed

    Hi Chris,

    What is the library you use in play for image processing

    • Christian Papauschek

      Hi there, we use ImgScalr ( )
      Its not the fastest image scaling method out there, but easy to implement.

      • Zafer Mohamed

        Thanks I am using the same one, but was wondering if you have a better one as the thumbnails created by imgscalr from large images look to be very sharpened and altered.

        • Christian Papauschek

          True, with the default settings the pictures tend to look too sharpened. We managed to get OK results using Scalr.Method.QUALITY. If they still look too sharp, maybe try the ULTRA_QUALITY setting.

          Still, the quality could be better.

          • Zafer Mohamed

            Thanks will try that.

  • ajay vasudevan

    Dear Chris,

    Was disappointed with Play 2.2 performance metric compared to Tomcat 6.

    Any idea to boost play 2.2 application ? Do i need to tweak application.conf ?

    Play metric

    —- Response Time Distribution ————————————————

    > t 800 ms < t t > 1200 ms 646 ( 71%)
    > failed 0 ( 0%)
    and for Tomcat 6

    —- Response Time Distribution ————————————————

    > t 800 ms < t t > 1200 ms 0 ( 0%)
    > failed 0 ( 0%)

    • Christian Papauschek

      Impossible to say what needs to be tweaked, just from this data. What does your play controller do, compared to your servlet code? Is there database access involved? Did you run those tests with parallel requests?

    • Maximilian Eberl

      It would be interesting to see the make-up of Your test,
      e.g. the code of the app.
      Did You deploy a Play-1.2.war on tomcat or did You
      implement the app in Servlet API ?