I’ve seen a lot of comparaison between Golang and Node.js along with debates about which one is the best. In this post I would like to explain why they have been created, how do they perform, scale and their usage, 10 years after they both came into existence.
The Origin Story
Node.js has been designed as an alternative to Apache HTTP Server in order to handle up to 10,000 concurrent connections and more, thanks to a non-blocking low-level I/O API (interaction with the system’s disk and network).
The Go raw CPU performance beats Node.js by far but the real life performances are very similar.
If it’s your main concern, know that Go isn’t faster than Java on average. Your control over the hardware is limited so if you really want to make the most of it, think about C, C++, Rust, or some other language that gives you appropriate control.
Obviously, the overall application performance highly depend of the code quality is limited by potential bottlenecks (network, database, …).
Just like the performance, the overall scalability of an applications doesn’t depend only of the programing language but rather to the application architecture used. However, both languages has interesting built-in mechanisms that make it easier to scale an application.
None is the overall best but one can be better suited for your use case.
Even if some try to deny it, Node.js has powerful built-in tools for scalability. Using the cluster module you can fork the main application process on every CPU cores available and make them communicate with each other. A simple load balancer would allow you to run your application on multiple machines as well.
One machine, multi-core scaling
While you have to manage you threads manually with Node.js, Go do it in an automatic fashion. It’s called a “Goroutines”. If you want to execute a function
hello(name string) and do
go hello("world"), the scheduler will automatically schedule this Go routine to the next available thread. This is a great feature to manage concurrency. If this model solve your problem, great! If not, well, that’s the only one.
This topic is generally overlooked by developers when choosing a programing language. It’s commonplace to go with a shiny new technology to build a new project without thinking about the technical debt we will generate. As a company grow, this may become a huge issue, limiting the productivity and reducing motivation. You can do like Netflix, rebuilding everything from scratch every five years, or you can write maintainable code.
I like to think that maintainability is mainly achieved by good application design and documentation rather than the language or the stack you pick.
Google, with it’s huge codebase, created a programming language, designed to make it easier to maintain by intentionally leaving out many features of modern object oriented languages:
- No classes. Everything is divided into packages only. Go has only structs instead of classes.
- No inheritance support.
- No constructors.
- No annotations.
- No generics.
- No exceptions.
If like Google you have a very large code-base and thousands of developers working on it, it will be easier to maintain.
The absence of exceptions make your code difficult to debug.
The lack of generic programming may leads to code duplication.
The lack of some modern language features make it more verbose.
These omissions are meant to simplify the language but it also makes the abstraction capabilities practically nonexistent. It would be difficult to build more advanced structures than you’ve already got and the compiler won’t help you. Complex projects are forever out of reach by design and it’s a choice because complex projects are not easy to maintain. If you need very high-powered abstraction mechanisms, you can use C++, Scala, Haskell, and so on.
Stack Overflow 2018 Developer Survey
2018 State of the Octoverse
This statement hold for every region of the world. Even if Go is growing rapidly, it still didn’t entered the top 10 programming languages, unlike TypeScript, breaking out this year. Type safety is a real concern in the developer community and TypeScript operability with JS has been a booster.
We can balance this data by adding Python, PHP and Java
It seems like Node.js and Go are both equally trendy.
Real world usage
Node.js is best suited for:
- Network applications
- i/o tasks
- API server
- Distributed single purpose applications
- Working with data, implement business logic
But doesn’t shine for:
- CPU heavy applications
- Static html based applications
- Large complicated applications
Go is very good at:
- CPU heavy applications
- Project with a large codebase
- Use case where the goroutine model suit your needs
But bad at:
- Project that the goroutine model doesn’t suit
- Extend the language
- Functional programming
I hope this post helped you to get a better understanding of each language usage. Don’t hesitate to share your own use cases in the comments.