Why We Use Node
<figure> <img src="https://www.pandastrike.com/assets/images/posts/turkish-carpet.jpg" alt=""/> <figcaption>Christopher Alexander's writings inspired the idea of software design patterns. He also wrote about Turkish Carpets.</figcaption> </figure>
In our last post, we explored the reasons behind some of our technology choices. In this post, we're going to zero in on Node. There's been a lot of different takes on what makes Node appealing. Some developers seem to believe that Node more or less invented fast, async programming. But if you want speed, you'd use Java or C/C++, and async has been around for years. In fact, Node was originally built on top of an existing C async library. So, if it isn't speed or async programming…what is it? Why do we use Node? Why should you use Node?
For Want of an API…
((require "net").createServer ((socket) -> socket.pipe socket)).listen 1337
What's impressive about this is that it uses general purpose network programming abstractions, like servers and streams.<small>A one-line echo server, by itself can be done using netcat as
nc -lk 1337, but the network programming model we have access to with netcat is relatively limited.</small> More interesting applications can thus be written in two or three lines of code, and applications that typically require dozens or even hundreds of lines of code can often be written in a dozen lines or less.
Lines of code is a crude measure of expressiveness. We talked a bit about this in our last post with respect to CoffeeScript. But it also applies to well-designed APIs that provide an intuitive programming model, like the Node APIs. Expressive code is generally easier to debug and maintain, assuming you've learned the language, libraries, and idioms in use.<small>A lot of the griping about any piece of software is at least partly due to discomfort caused by a lack of familiarity.</small> All other things being equal, if it's easier to write expressive code, we all win.
The Bottom Line
That said, effective use of concurrency is crucial for performance in networked applications. After all, I/O is often more important to such applications than CPU or memory. In spite of it's limited concurrency model, it's APIs make it relatively easy to handle high-levels of concurrency. Our simple echo server above can handle thousands of concurrent connections, limited mostly by the configuration and memory of the server itself.<small>We often tell clients that, sure, Node is slower than, say, Java, but it's just as fast at scale, because network I/O is usually their bottleneck at that point. If you can support more concurrency in an I/O bound applciation, you'll utilize more CPU and memory and your costs go down.</small>
I think this is implicit in what people are getting when they talk about Node being fast. What they're saying is they need fewer servers or less expensive servers. And that's the bottom line. Of course, we can always drop into C or Java, and if I really want to, we can write servers that are much faster than Node. In fact, some people have done just that. But Node is "good enough" and it's much simpler. We can still go back and optimize selected components if we need to, where we find bottlenecks, but there's no sense in paying for that ahead of time.
The End of the Language Wars
A Hot Mess