Nodejs vs Play for Front-End Apps

by Subbu Allamaraju on March 26, 2011 · 156 comments

Mar 29, 2011: The source used for these tests is now available at https://github.com/s3u/ebay-srp-nodejs and https://github.com/s3u/ebay-srp-play.

Mar 27, 2011: I updated the charts based on new runs and some feedback. If you have any tips for improving numbers for either Nodejs or Play, please leave a comment, and I will rerun the tests.

We often see “hello world” style apps used for benchmarking servers. A “hello world” app can produce low-latency responses under several thousands of concurrent connections, but such tests do not help make choices for building real world apps. Here is a test I did at eBay recently comparing a front-end app built using two different stacks:

  1. nodejs (version 0.4.3) as the HTTP server, using Express (with NODE_ENV=production) as the web framework with EJS templates and cluster for launching node instances (cluster launches 8 instances of nodejs for the machine I used for testing)

  2. Play framework (version 1.1.1) as the web framework in production mode on Java 1.6.0_20.

The intent behind my choice of the Play framework is to pick up a stack that uses rails-style controller and view templates for front-end apps, but runs on the JVM. The Java-land is littered with a large number of complex legacy frameworks that don’t even get HTTP right, but I found Play easy to work with. I spent nearly equal amounts of time (under two hours) to build the same app on nodejs and Play.

The test app is purpose built. It includes a single search results page that renders search results fetched from a backend source. The flow is simple – the user submits some text, the front-end fires off a request to the backend, the backend responds with JSON, the front end parses it, and renders the results using a set of HTML templates. The idea of this app is to represent front-end apps that produce markup with/without backend IO.

In my test setup, the average result from backend is about 150k – it is JSON formatted and not compressed. The results page consists of 8 templates – each for different parts of the page like header, footer, sidebar etc. The sizes of the template files range from 250 bytes to under 2k. In order to ensure that backend latency does not influence testing, search requests are proxied through Apache Traffic Server acting as a forward proxy. The cache is tuned to always generate a hit. Such a high cache hit is not realistic, but it helped me isolate the cost of having to go through uncontrolled public Internet to get search results for my testing.

Note that the test environment is not the most ideal – the test client, the server, and the cache were all running on the same box. The box is a quad-core Xeon with 12GB of RAM running Fedora 14 (2.6.35.6-45.fc14.x86_64 kernel).

I ran the tests using ab.

ab -k -c 300 -n 200000 {URI}

The tests include the following configurations

  • Render – No IO: Render the page without any IO – this configuration generates HTML from the templates with empty results.
  • IO + Render: Render the page with results.
  • IO – No Render: Fetch results but don’t render – this is an unrealistic case, but it helps highlight the cost of IO vs cost of template processing.

The charts below show requests per second and mean response time.

From these, you can see that Nodejs beats Play on performance as well as throughput. However, in the pure IO case, I would not discount non-blocking IO on the JVM. I plan to post more results dealing with IO + computation scenarios.

The charts below show the percentage of requests completed within a certain amount of time in msec. The shorter the bars the better. Also less variance as you read from left to right on each chart is better – I would ignore the last set of bars on the right (time to complete 100% of the requests) as they may contain outliers.

When the workload involves generating HTML from templates off the file system without performing any other IO, nodejs does twice better than JVM based Play. As we introduce IO, performance across the board suffers, but more so with blocking IO on Play. But Play is able to catchup with non-blocking IO (via continuations).

I’m unable to make the source code for the test apps available publicly at this time. But I plan to create and post some new tests on github soon.

{ 148 comments… read them below or add one }

Shantanu Kumar (@kumarshantanu) March 26, 2011 at 11:12 pm

RT @sallamar: On the blog – "Nodejs vs Play for Front-End Apps" http://www.subbu.org/blog/2011/03/nodejs-vs-play-for-front-end-apps

Reply

neal (@nsample) March 26, 2011 at 11:41 pm

RT @sallamar: On the blog – "Nodejs vs Play for Front-End Apps" http://www.subbu.org/blog/2011/03/nodejs-vs-play-for-front-end-apps

Reply

Ioannis Cherouvim March 27, 2011 at 1:51 am

Nice article. Thanks for the insight.

Could you elaborate more on the “legacy frameworks that don’t even get HTTP right” part? How do they get HTTP wrong?

thanks

Reply

François-G. Ribreau (@FGRibreau) March 27, 2011 at 2:30 am

Nodejs vs Play for Front-End Apps http://bit.ly/g8soXM

Reply

Leif Singer  (@lsinger) March 27, 2011 at 3:12 am

Nodejs vs Play for Front-End Apps by @sallamar http://bit.ly/fODdnP

Reply

JP Wesselink (@jp10k) March 27, 2011 at 4:34 am

RT @lsinger: Nodejs vs Play for Front-End Apps by @sallamar http://bit.ly/fODdnP

Reply

Loic Descotte (@loic_d) March 27, 2011 at 5:03 am

Encore une preuve que play déchire tout! “@rmat0n: Nodejs vs Play for Front-End Apps http://t.co/cCqyEOr #nodejs #play”

Reply

Philippe Charrière (@k33g_org) March 27, 2011 at 6:34 am

RT @FabienAMICO: #Nodejs vs #Playframework for Front-End Apps – http://goo.gl/oPeMS

Reply

Matthieu Guillermin (@mguillermin) March 27, 2011 at 7:19 am

RT @naholyr: Nodejs vs Play for Front-End Apps http://goo.gl/G2wwM

Reply

TJ March 27, 2011 at 8:03 am

how many cluster workers? NODE_ENV=production? seems like lots of information is missing… I can get better numbers than this on my machine, but if you leave NODE_ENV to development with Express view rendering will be much much slower

Reply

Subbu Allamaraju March 27, 2011 at 8:16 am

Cluster starts 8 instances. Good tip about “NODE_ENV=production” – will look into that.

Reply

Subbu Allamaraju March 27, 2011 at 9:38 am

I updated the charts with NODE_ENV=production. You’re right about production mode. V8 seems to take a lot of strain (particularly CPU) when production mode is not enabled.

Reply

Ile March 27, 2011 at 2:49 pm

Was Play in dev or production mode, application.mode=dev or prod?

Reply

TJ March 27, 2011 at 2:50 pm

NODE_ENV is not production, express will re-compile the template on every request, so this will slow it down greatly

Reply

Subbu Allamaraju March 27, 2011 at 2:54 pm

@TJ: That’s what I though by looking at the CPU activity without NODE_ENV=production.

@Ile: Play is run with “application.mode=prod”

Reply

Ile March 27, 2011 at 3:34 pm

Yes, I think I missed that in the article. Nice work.

nicolasleroux (@nicolasleroux) March 27, 2011 at 8:08 am

RT @sylvain_mathieu: #nodejs vs #playframework for Front-End Apps http://bit.ly/eB4EvP

Reply

Nicolas Labrot (@nicolaslabrot) March 27, 2011 at 9:21 am

RT @sylvain_mathieu: #nodejs vs #playframework for Front-End Apps http://bit.ly/eB4EvP

Reply

develsas (@develsas) March 27, 2011 at 10:21 am

empezó la pelea! #nodejs vs #playframework for Front-End Apps http://bit.ly/eB4EvP

Reply

who_knows (@who_knows) March 27, 2011 at 11:59 am

RT @sylvain_mathieu: #nodejs vs #playframework for Front-End Apps http://bit.ly/eB4EvP

Reply

Alexandre Saudate (@alesaudate) March 27, 2011 at 12:46 pm

RT @sylvain_mathieu: #nodejs vs #playframework for Front-End Apps http://bit.ly/eB4EvP

Reply

Ryan Dahl March 27, 2011 at 1:54 pm

What version of Node are you using?

Reply

Subbu Allamaraju March 27, 2011 at 2:15 pm

Node v0.4.3

Reply

Murat Aktihanoglu (@muratny) March 27, 2011 at 2:35 pm

"Node.js" performs twice better than JVM MVC Framework "Play" for Front-End Apps http://goo.gl/GqT4P – V8 will only improve from here.

Reply

Kalimba HN (@kalimbahn) March 27, 2011 at 3:16 pm

Nodejs vs Play for Front-End Apps http://goo.gl/fb/hQeXx #hackernews #kalimba

Reply

News Feed MS (@mstache_news) March 27, 2011 at 4:00 pm

Nodejs vs Play for Front-End Apps http://goo.gl/fb/oX7sT

Reply

Mike Cantelon March 27, 2011 at 5:13 pm

Looking forward to seeing a benchmark with source. Showing results without source code is less useful.

Reply

Subbu Allamaraju March 29, 2011 at 9:56 am

Mike – the source is now github. See the links at the top of this post.

Reply

Charleno Pires (@charlenopires) March 27, 2011 at 5:20 pm

RT @tek_news: HNews: Nodejs vs Play for Front-End Apps http://bit.ly/eOgzzY #nodejs #benchmark

Reply

Mikael Bjorkstam (@bjorkstam) March 27, 2011 at 5:37 pm

RT @indexzero: Node.js outperforms Java in full-stack tests at eBay: http://bit.ly/hlZKO8

Reply

rbergman (@rbergman) March 27, 2011 at 6:12 pm

RT @sallamar: Updated http://www.subbu.org/blog/2011/03/nodejs-vs-play-for-front-end-apps based on new test runs, and these numbers are better :)

Reply

Sen Xu 胥森 (@MetalMASK) March 27, 2011 at 7:28 pm

Nodejs vs Play for Front-End Apps http://bit.ly/eB4EvP

Reply

Tj March 27, 2011 at 7:48 pm

I should note as well ejs is not highly optimized due to the use of with. I don’t know of any faster for node, but it would be easy to write something like mustache that is very very fast, the restricted syntax would allow removal of the slow with(){}

Reply

Mazharul Anwar (@mazharul_anwar) March 27, 2011 at 8:12 pm

#Nodejs vs Play for Front-End Apps http://bit.ly/f4LcY0 #geek #performance #server

Reply

Javier Neira (@jneira) March 27, 2011 at 9:31 pm

RT @indexzero: Node.js outperforms Java in full-stack tests at eBay: http://bit.ly/hlZKO8

Reply

WWarlock (@w_warlock) March 27, 2011 at 10:14 pm

RT @sylvain_mathieu: #nodejs vs #playframework for Front-End Apps http://bit.ly/eB4EvP

Reply

ehsavoie (@ehsavoie) March 27, 2011 at 11:09 pm

RT @nmartignole: Nodejs est plus performant RT @sylvain_mathieu: #nodejs vs #playframework for Front-End Apps http://bit.ly/eB4EvP

Reply

de Saint Martin (@desaintmartin) March 28, 2011 at 12:32 am

RT @sallamar: On the blog – "Nodejs vs Play for Front-End Apps" http://www.subbu.org/blog/2011/03/nodejs-vs-play-for-front-end-apps

Reply

Chris Hayes (@hayesdata) March 28, 2011 at 1:32 am

RT @maboa: Some node.js benchmarking: http://www.subbu.org/blog/2011/03/nodejs-vs-play-for-front-end-apps (via @trygve_lie) Interesting.

Reply

hussein kanji (@hkanji) March 28, 2011 at 2:20 am
H. Stefan Olafsson (@mrolafsson) March 28, 2011 at 3:32 am

RT @jedisct1: NodeJS vs Play framework benchmark: http://bit.ly/fODdnP

Reply

Leo Lännenmäki (@LeoLannenmaki) March 28, 2011 at 3:53 am

RT @indexzero: Node.js outperforms Java in full-stack tests at eBay: http://bit.ly/hlZKO8

Reply

Anne Tagliaferri (@pinkvsgreen) March 28, 2011 at 5:31 am

RT @maboa: Some node.js benchmarking: http://www.subbu.org/blog/2011/03/nodejs-vs-play-for-front-end-apps (via @trygve_lie) Interesting.

Reply

Nicolas L. March 28, 2011 at 5:46 am

Great works!

Play! outperformes Node.JS without render. Play! uses Groovy for the template engine. The bottleneck may be Groovy.

Reply

Subbu Allamaraju March 28, 2011 at 6:08 am

Are you aware of alternatives? I just found about http://code.google.com/p/cambridge/ – but I’m vary of template languages that expect well-formedness.

Reply

Nicolas L. March 28, 2011 at 6:23 am

Thanks for this link! It may be an alternative to Groovy.

Reply

Frank March 28, 2011 at 6:33 am

Could you run the tests without the Groovy based templating? It would be useful to see the performance when using JSON responses based on the internal Gson library used by Play!.

Reply

Subbu Allamaraju March 28, 2011 at 7:58 am

@Frank: Other than a few conditionals, most of the processing is done using Gson. There is no intermediate model object between the backend response (JSON) and templates other than Gson. The controller passes a Gson object to the view, and view templates iterate through that.

Reply

Frank March 28, 2011 at 8:01 am

So there’s no Groovy stuff happening and explaining the slowness with rendering?

Any idea why the rendering phase is so slow compared to Node? If that was solved, Play! would be a clear winner when using NBIO.

Erdinc Yilmazel March 29, 2011 at 8:42 am

Hi,
I’m the author of Cambridge Template Engine and I wanted to clarify something. Cambridge doesn’t require your template files to be well-formed. It doesn’t use any xml parser to parse the templates, it has its own parser and it works fine with any non-xml/non well-formed template file. Here is a performance comparison of built-in play templates with Cambridge templates: http://code.google.com/p/cambridge/wiki/UsingWithPlayFramework

Reply

Subbu Allamaraju March 29, 2011 at 9:54 am

Thanks for the clarification. I will take a look. In the meantime, I’ve made the source available on github. See the top of this post for links.

Reply

Stephane Maldini (@smaldini) March 28, 2011 at 6:00 am

RT @jfarcand: Play vs NodeJS….. RT @indexzero Node.js outperforms Java in full-stack tests at eBay: http://bit.ly/hlZKO8 (via @mwessendorf)

Reply

Seb Courvoisier (@LePhasme) March 28, 2011 at 6:45 am

RT @indexzero: Node.js outperforms Java in full-stack tests at eBay: http://bit.ly/hlZKO8

Reply

Arnout Kazemier (@3rdEden) March 28, 2011 at 8:01 am

RT @perfengineering: Nodejs vs Play freamework for front-end apps: Throughput and Performance Benchmarking by @sallamar Nodejs wins. http://bit.ly/hIgvnb #perf

Reply

Subbu Allamaraju March 28, 2011 at 8:16 am

“Any idea why the rendering phase is so slow compared to Node? If that was solved, Play! would be a clear winner when using NBIO.”

@Frank: I’m going to find out this week, and try to post an independent test.

Reply

Ile March 28, 2011 at 8:39 am

BTW, what does that “IO” consist of that is referenced in the article? I think it means “backend IO” but it’s not clear (at least to me) what it means?

Reply

Subbu Allamaraju March 28, 2011 at 8:44 am

@Ile: The same – it involves making an HTTP GET request to get JSON-formatted response through a proxy cache (Traffic Server) using play.libs.WS. I chose Traffic Server because, from my experience at Yahoo!, it handles large number of concurrent connections very well.

Reply

pelegri (@pelegri) March 28, 2011 at 9:30 am

RT @jfarcand @indexzero @mwessendorf Node.js outperforms Play http://bit.ly/hlZKO8 >> Looking forward to follow-ups from the Play folks

Reply

Guillaume BRETON (@octalmind) March 28, 2011 at 11:20 am

RT @mariofusco: #Nodejs vs #Play for Front-End Apps http://www.subbu.org/blog/2011/03/nodejs-vs-play-for-front-end-apps Interesting performance comparison

Reply

Sazboom Software (@sazboom) March 28, 2011 at 12:30 pm

Nodejs vs Play for Front-End Apps http://ow.ly/4nuVr

Reply

Eli Ezeugoh (@ck1125) March 28, 2011 at 3:15 pm

Interesting numbers from the eBay guys on Node.js vs Play! – http://bit.ly/hlZKO8. server-side JS comes of age. via @smaldini

Reply

smallufo (@smallufo) March 28, 2011 at 4:50 pm

http://bit.ly/dPBbX6 記得 #playframework 幾個 core staff 之前在 maillist 捍衛內定使用 groovy template , 原因在於 view 效率不是那麼重要。現在果然被人抓來 benchmark…(雖然敗陣原因仍不明)

Reply

Bing Ran April 5, 2011 at 2:52 am

It’s hard to let go of egoism.

Reply

Alexandre Poirot (@TechnoBarje) March 28, 2011 at 10:48 pm

RT @jedisct1: NodeJS vs Play framework benchmark: http://bit.ly/fODdnP

Reply

Clement Nivolle (@cnivolle) March 29, 2011 at 12:26 am

RT @rgaidot: Nodejs vs Play for Front-End Apps http://t.co/FlWweNI #nodejs #playframework #java

Reply

dan loaiza (@papachan) March 29, 2011 at 5:56 am

Comparative: Nodejs vs Play for Front-End Apps http://bit.ly/eB4EvP

Reply

Lewis Barclay (@errumm) March 29, 2011 at 8:16 am

RT @srishivananda: #Nodejs vs #Play for Front-End Apps http://bit.ly/eB4EvP

Reply

Leave a Comment

Previous post:

Next post: