Node.js Has a Bright Future
Node.js
Saturday, 24 April 2010 21:38

A while back, a coworker of mine told me about Node.js, a webserver written in JavaScript on top of V8. I was initially impressed by two strengths of Node.js.

  1. It's crazy fast
  2. It can handle tons of concurrent requests
  3. It's written in JavaScript (which means you can use the same code server side and client side...way cool)

I took a quick look at the Node.js website to get the gist of how it works and then I checked out the chat demo. After that, I thought this was cool as a novelty, but wasn't interested in digging much deeper because of a few concerns.

  1. The project was young. As such, to write a website using this, you wouldn't get much free functionality by way of libraries and plugins. And it simply isn't time tested yet.
  2. There is not much of a community yet. Sure it's gaining popularity, but how many Node.js developers do you know out there and how many sites are written in it?

Node.js Is Too Cool To Ignore

Well, as it turns out, Node.js is too cool to ignore it for practical reasons. So, eventually, I had to come back and check it out more. My first inclination was to determine if it was really all that awesome. If so, then it's worth digging into it more. The main thing I was curious to verify was if it was really all that fast. Let's look at how that went.

Node.js Benchmarks

First, I wrote an identical app in PHP and Node.js (as close as I could get anyway). The apps both return a single HTML page that contains a single sentence. PHP was running version 5.2.10 using mod_php with Apache2. I also created a static page containing comparable content served by Apache2 directly. I ran all three of these on my laptop and tested them using ab (Apache Benchmark), also on my laptop. I ran at a concurrency of 10 and a request count of 10,000. This is obviously a pretty rough test, but should show some rough trends. Here are the results:

Platform # requests/sec
PHP (via Apache) 3187.27
Static (via Apache) 2966.51
Node.js 5569.30

My first surprise was that a static file served via Apache was the slowest. My second surprise was that lightning speed of Node.js. So, why was Node.js so fast? Most HTTP servers open a socket and spawn a thread for each request, or they at least maintain a pool of threads or processes. Node.js does not do this. Instead, there is one thread running an event loop which executes callbacks. Therefore, for each request, only a small heap allocation is needed, rather than a separate thread or process. Not only is it much faster to create only a small heap allocation, it also leaves a much smaller memory footprint.

Since Node.js can handle tons of connections really well, it should be strongest when you have an app that waits around a lot and has connections piling up. So, let's see what happens when we try that out. I recreated the previous test, but added a two second sleep. I also upped the concurrency to 400 and the lowered the request count to 2000. Here are the results:

Platform # requests/sec
PHP (via Apache) 37.46
Static (via Apache) N/A
Node.js 164.30

Yup, we were right. Node.js blew PHP out of the water on this one. In the first test, Node.js beat PHP by 75%. This time it won by 339%. Obviously we have found a particularly strong suit of Node.js. So, what is it bad at? Well, let's try the opposite of our last experiment. Let's see what happens when your code is busy the whole time instead of going to sleep. It seems to me that by doing this we lean less on Node.js' strength in handing tons of connections and we are now looking more purely at language performance. Of course we'll still be handling lots of connections, so Node.js will continue to perform well there. This next test increments a number from 1 to 10 million for each request. I used a concurrency of 10 and a count of 100. Here are the results:

Platform # requests/sec
PHP (via Apache) 1.64
Static (via Apache) N/A
Node.js 12.61

Wow. This one really surprised me. Node.js outperformed PHP by 669%, double that of the high concurrency test. Honestly, I don't know why. I suppose the language itself could just be friggin' awesome. Since the performance of the language itself really comes down to the implementation of V8, I took a look at the V8 docs regarding performance. They list three primary objectives regarding performance and one of them is fast property access. Since JavaScript is a dynamic language, accessing properties is often implemented using a two-step hash-like lookup under the hood. V8 takes a different approach. They create classes (invisible to you) that define exactly what properties an object has and how much memory they take up. This way, properties can be looked up by simply using an offset. This is way fast...like O(n) time. PHP is a dynamic language as well and it doesn't use this fancy method for property access. So, my best guess on the last test results is that it is actually due to the awesomeness of V8.

Is Node.js Worth Spending More Time On?

Yes. I am still hesitant to build out a real site using Node.js. To do this, you'd probably use some cool libraries like express and mongodb-native. Maybe I'll write a post about that sometime. This blog post explains how you might go about doing this. However, before using this for a paying client, I'd want to wait a while longer until this is more time tested. But, what I did learn is that Node.js does have a place in the world, and that's important. I don't know how long it will take, but I think this could catch on and become something big. If PHP, then why not Node.js? Node.js is faster and speaks the same language as the browser, allowing you to use your code both server side and client side, making Node.js a natural fit for the web development universe. I don't know if it will, but it could happen. Until then, I'll be learning more and waiting anxiously.


blog comments powered by Disqus