Okay. So what about a blocking web server, a typical web server that you would be building in Python, Ruby, or Java or PHP. So when it comes to web servers, let's say we have some clients, they're making requests, so each subsequent request in the queue would be blocked by the previous requests. And that's why you need multi-threading. So with blocking systems you need multi-threading because that the only way to scale.
I always like to give this example. So let's say you go into a café or a coffee shop, and let's say you see a long line and what they're doing at the register, they're take your order, they take your money, and the same person who took your money, he or she will turn around and go make you a drink.
That's why you have a long line because that person has to wait for all the people in front of that line. So people in line are frustrated, the employee is frustrated, the manager of this coffee shop is frustrated. The only way to scale it is to add more cash registers and to add more baristas manning those cash registers. That's thus your typical multi-threaded blocking IO system and you have a queue and you have a lot of delays. Everything happens synchronously.
Let's get back to the Node. So Node, it uses non-blocking and we can build a non-blocking web server. When requests are coming, they go to event loop. Event loop is almost never blocked and it delegates the processes to some other actors, some other subjects, which do the actual operations. And when the operations are complete, event loop via an intermediary, sends back those requests to the clients.
In the coffee shop analogy, that would be a typical Starbucks store, where you have two different people. One person is at the register, taking your orders and taking your money. Another person is actually making the drinks, or it could be more than one people making the drinks.
So what is happening? You go to the cash register, make your order, and then they write down your name. So you go to your coffee table, there is no line, and you wait. You wait asynchronously. So at your table, you can watch some Node University courses. You're a happy customer. You don't have to stay in line with strangers. And then once your order is ready, they call you. So that's your callback, so you go and take your order. You're a satisfied, happy camper.
So this is a non-blocking system. It works asynchronously, it's way more effective. In this situation, you can scale it more easier. You don't need to add more registers because that's not your bottleneck. You would be adding more workers, people who actually make the drinks.
So multi-threaded, it's not necessarily a good thing. It was born out of necessity to scale those blocking systems. And there are a lot of complexity that counts as multi-threading because you need to synchronize the data between multiple threads, you need to worry about racing conditions, you need to worry about many things. All those things are eliminated in the single threaded, which Node.js is.