Node.js is an event driven I/O and It's a single threaded server that acts upon callbacks and never blocks on the main thread.
Thread-based model assigning a task to a thread and if there is no idle thread, block new tasks.
I am wondering what are the differences (advantages/disadvantages) between event-driven and thread-based server systems.
The difference might be described as follows (with some simplification):
in "thread driven" runtimes, when a request comes in, a new thread is created and all the handling is done in that thread.
in "event driven" runtimes, when a request comes in, the event is dispatched and handler will pick it up. When? In Node.js, there is an "event loop" which basically loops over all the pieces of code that need to be executed and executes them one by one. So the handler will handle the event once event loop invokes it. The important thing here is that all the handlers are called in the same thread - the event loop doesn't have a thread pool to use, it only has one thread.
In an "event driven" model, if a handler will take a very long time to finish (i.e. by having a computationally intensive for
loop inside), no other request will be handled during that time, because the event loop will not invoke the next handler before the current one completes. That's usually not an issue because of the asynchronous nature of Javascript.
On the other hand, in the "thread driven" model, if the handler takes a lot of time to complete, it won't hurt other threads much, because they can run at the same time independently.
Unfortunately, creating a new thread adds some overhead and if you need to handle thousands of concurrent connections, it might become a burden. That's why Node.js is considered fast - no matter how many connections you handle, there's only one thread 1. You just need to be a bit careful not to block in any of the handlers to keep things moving. Fortunately most of the time it's not that easy to write blocking JavaScript code.
It's also important to note that writing asynchronous code is possible in most of the runtimes. It has become most widely used in Node.js though, because of the nature of Javascript. Thanks to that, virtually every library you use in Node will be asynchronous.
See this article (and pictures) for an explanation of the event loop.
1 Of course there is more that one thread in Node.js process, some of them are related to I/O. But your app logic is handled in one thread.