If you ask around in the developer community about what’s the hottest technology in the recent years, then probably you will get the same answer: Node.js. How hot is that? Its repo now has nearly 20,000 stars, 13,000 commit, and more than 800 contributors on Github now, and that’s just for the node itself as there are even countless libraries, codes, products and websites are based on Node.js. It seems that it is becoming a must-know skill for every developer just because it is so good that everyone likes to use it.

What is Node.js?

Node.js is many things, but mostly it’s just a way to run JavaScript outside the web browser. Thanks to Google’s V8 engine, not only you can run JavaScript on your server ,the performance of Node.js is also really, really fast (in some way) compared with traditional Apache Server. It also includes many new APIs to make it a full-functional server script, such as a Buffer class to let your JavaScript server easily manipulate binary data.

How does it work?

Node.js’s core idea is the famous single threaded non blocking I/O. JavaScript is an event-driven language, and it is based on an architecture called event loop. In event loop, the system will listen to the events emitted, and then do some jobs that are bound and triggered by the events. Node was designed in this way so that all I/O activities should be nonblocking. This means all HTTP requests, database queries, file I/O and other things that require the transitional system to wait do not halt execution until they return data. In fact, they will run independently, and emit events when their data is available. When the events are received by Node, it will invoke the callback function that binds with the event, and let the callback to finished the remaining jobs. Our life is also driven by event. An real-life example is cooking: you will first light the fire and put the pot on the fire. Then instead of waiting the water to be boiled, you will do something else like cutting vegetables. Then when you water is boiling, you will go back to your pot and put your materials inside, and then do other things again. Boiled water is an event, and when it is triggered, you will go back and do something with it, which is exactly a callback invoked for this “boil water” event. Also, you may have realized that everything going on here is “single-threaded” so that only one thing happens at once.

Why Node is more efficient?

The single-threaded concept is quite important because it is related to Node’s performance. The problem with multiple threads system is that it requires extra coordination works. Node’s way is simple: there is only one thing happening at once, and here is what non blocking I/O fits in - you don’t waste time waiting on things like I/O, so the Node is able to act on event in a very short time.

Traditional server, such as Apache, will create a new thread for each request, and the thread will wait for every I/O or heavy task such as database query or file reading, and then send the response back. There are two problems happening here, the first is it will waste time on waiting - which ultimately increase the response time. Secondly, suppose the server has only 2048MB memory size, and each thread will take 2MB resource from the server, then theoretically the maximum number of connections supported by this single server is 2048 / 2 = 1024. If your expected your total number of user is more than that, then you need to consider adding more server in order to support more users. Node, instead, is single threaded, and its I/O is non-blocking, so with same resource and time, it can handle more connections easily because after receiving one request, it can still receive more requests as it does not wait for the I/O work to be finished, but return the response only when the I/O works are finished and corresponding events are triggered.

A good real-life example is ordering food at a fast food restaurant. When you get in line at the counter, the server taking your order can behave in two ways: one of them is event-driven, and one of them is not. The typical approach is after you asking the server for your order, he will not serve any other customers until he has completed your order. He has to wait for an unknown amount of time for the kitchen to prepare your meals. This way is exactly like the tradition approach of web framework: each server(thread) is allocated to just one customer(request) at a time, the only way to scale up is to add more server(thread), and it is obviously not very efficient because he spends too much time waiting for kitchen(I/O).

Restaurants nowadays have a better way to handle this: they give an order number to each customer after they have ordered food. And the number will be called when the kitchen has prepared the food. This is exactly what Node is doing. In this way, you could serve a lot of customers because you can just give them a number (a callback reference) and call them back if their food is ready in the kitchen. In this way, servers are able to maximize their throughput.

!!! An important thing to notice here is Node’s I/O time is not reduced at all. The I/O time is exactly the same as tradition server, but since Node does not waste time on waiting, it can serve more request at the same time, and hence work more efficiently.

What Node is good at, and what is its limitation?

So does it mean that we should just abandon tradition server and replace them by Node? Of course not. Node has its drawback : it is single threaded! What? Didn’t you just tell us this is its advantage? Well, Node will not waste time on waiting for I/O operation, but when the callback is invoked in the main thread and it gets stuck, your server will not be responding anymore since its one and the only one thread is not responding. Node.js is doing only one thing at a time! If the current thing it is working takes a long time, then all requests will have to wait, which really screw up the whole server.

In general, Node.js is good at:

  1. Real-time applications: such as chat app
  2. Applications that are highly event driven & are heavily I/O bound
  3. High traffic, Scalable applications:

It’s better not using Node.js if you need:

  1. heavy CPU consuming algorithm/work on server: Your server will suffer!

Conclusion

Although the weakness is there, Node.js is still a perfect choice for small project. It is fast enough and extremely easy to develop. Especially you could develop real time application like Chat App within half an hour using Socket.io. But if you are going to build a large enterprise system such as an ERP package or payment server, then our old and stable Apache/Tomcat/Nginx servers are still your best friends. Anyway, I still think every developer at least should try Node.js once, and you will realize how fast and easy you can build a web application.

How to lean?

Node School is probably one of the best resource you can find on the web for learning Node.js. By attempting assignments and works on it, you will have a better understanding of Node and things related to it.

Reference

  1. Tom hughes-croucher & Mike wilson. (2012). Node: Up and Running. : O’Reilly Media.