Node.js Overload
thoughtworks.com
thoughtworks.com
This is a page in Thoughtworks' "Technology Radar". Thoughtworks is a global US-based software agency that likes to market themselves as thought leaders in the world of software. They're not super well known in startup land but my impression is that in enterprisy environments they're considered "very good".
One way they maintain this image of thought leadership is employing famous people such as Martin Fowler. Another way is by regularly publishing a document called "Technology Radar" which is in opinionated list of technologies that their tech leadership believes ought to be used, explored, avoided, etc. They explicitly don't position it as a bunch of truths they hold to be absolute - it's just the opinion of a few senior tech folks at Thoughtworks who had a fun weekend in a holiday house together or something like that. I guess they had a disappointing Zoom call this time around.
It's generally a bit more conservative than HN, you often only see stuff listed under "Assess" that has been commonplace in HN articles for multiple years. This makes sense, it's targeted at enterprises. At the same time, it's highly opinionated and they're not afraid to take positions that are not a match with the current hype cycle.
I really like it for this latter quality, and I encourage you to explore this edition further than just their recommendation to not always jump to NodeJS by default (which seems to be a bit of a straw man to me, anyway).
Be sure to click all four "quadrants" (right top of the page), IMO the linked one, "Platforms", is the least interesting one.
In my case, using javascript on the front end and PHP in the back, and as a scripting language for servers was frustrating. Function names are always slightly so different...
I increased my productivity and my fun tremendously when I switched to Node on the backend.
Sometimes I am thinking about using Python for computer vision stuff. Nope... Everything Javascript, so much better for my sanity.
Something like: "I was an intermittent cook, because I need to sell, and manage my (small) business too.
In my case, cooking both soups and main courses, and some deserts occasionally was frustrating. Cooking times are always slightly different...
I increased my productivity and my fun tremendously when I switched to only eating polenta."
I hope this does not come off as offensive, which was not my intention, instead, I hope this serves as food(pun intended) for thought and reflection.
Maybe the analogy would be: “I was using three different kinds of butter in my kitchen. I switched to just one brand. Turns out it didn’t make a difference in taste, yet saves me effort and money because I can buy larger quantities of the ingredient.”
It looks looks the same to its consumer, but it will feel different when under pressure.
I've experienced React SSR server (I know this is heavy) not able to withstand traffic when pushed to only tens of concurrent users, reaching only 1000ish RPS even after being clustered.
I'm not opposed to NodeJS though. I've learnt a lot of it and I've ever been a NodeJS fanboy for like 2 years-ish.
PS: I also increased my productivity too moving from PHP to NodeJS back then years ago.
Only eating one type of food is crazy. Nobody does that and if they do, it’s not fun.
However, as a chef, streamlining the types of meals that you cook sounds like a great way to free up time and have a lot more fun in your life. It doesn’t sound weird at all, not even in the slightest degree.
If you are not a restaurant, and eating polenta is fine for you, and make you save time and increase fun, then go for it!!
My business is not programming, is to provide a service.
I understand the right tool may make a tremendous difference in a big team or someone coding full time, but not for me.
And doing threading in Python is so confusing for new beginners. There are about a million different ways to do it.
I'm starting to think this is going to be a major dividing line in developer skill going forward -- those who can write threadsafe code and those who can't. There's an awful lot of Java, C# and Golang out there and if a programmer can't reliably think through thread safety issues (which is not that difficult in simple cases), they aren't capable in that realm.
One of the most frustrating things about my brief excursion into the land of Ruby was that the community was full of modules written by people who had no reason whatsoever to think about thread safety because they were programming for Rails, not Ruby in general.
This, abstracted, those who can write distributed software and those who can't yet.
Dealing with shared resources is similar to dealing with shared memory if you zoom out a bit.
We need more people to move from the latter group to the former, for reasons. The more people aware of distributed software and its challenges, the better.
A GIL doesn't help developers. It only keeps the internal state of the VM consistent. You still need to to use locks, thread safe collections etc. That's one major reason why some people feel that OS threads + GIL is a poor trade-off.
https://github.com/ruby-concurrency/concurrent-ruby#thread-s...
This is essentially equivalent to running N single-threaded processes, except that when I do have to share data across the system (e.g. a database connection pool), or if the lifecycle of the client crosses multiple strands, I have more tools in my toolkit.
But do these other frameworks give you the simplicity of sharing code and using the same language in for fe and be ?
For me the performance of Node BE applications is just a nice bonus, for having consistent development environment with huge library of radily available packages.
So yes. And you know what ? You shouldn't share too much code between backend and frontend.
The packages are node disavantage. You depends on too much packages it's a security risk.
Yeah right :) I'll tell you what I like about it.
I defined my database models in Typescript[1], work with them in the backend, send them to the frontend, and deserialize them back to the same Typescipt model classes in the browser and continue working with them ( w/o the actual database part) as data structures.
Are you trying to convince me this is bad ? Because I definitely don't believe you :)
- The convenience of using the same language in the client and server
- The speed of Node.js
It unfortunately does not state why it shouldn't be used in the server, or offer any more suitable alternatives.
I think a much better critique would be that the lack of fine grained primitives, and the surrounding ecosystem, are not the best choice for compute heavy tasks.
I definitely see the merit in preferring another language with a clear, native multithreading model - and with perhaps significantly better general performance to boot.
If anything, the critique in my opinion misses how the Node web frameworks tend to be really unopinionated and non-prescriptive which can be great for some teams and projects but really bad for others (they do mention that NestJS is a technology to watch and that they use it widely, so I actually think they’re of the same opinion)
> When Node.js became popular, it was the first major framework to embrace a nonblocking programming model which made it very efficient for IO-heavy tasks. (We mentioned this in our write-up of Node.js in 2012.) Due to its single-threaded nature, Node.js was never a good choice for compute-heavy workloads, though, and now that capable nonblocking frameworks also exist on other platforms — some with elegant, modern APIs — performance is no longer a reason to choose Node.js.
Multi-threading could be added to the runtime for back-end applications (https://news.ycombinator.com/item?id=15498219)
The argument about compute heavy workload also feels orthogonal to the whole issue of Node on the backend.
Reasoning about the backend feels much easier in languages like C# and even python. Because the majority of the code in the backend is about data storage, retrieval, data modeling, rich and complex business logic, etc. While on the front end, the focus is usually on data binding, immutable structures, etc.
JS in react is fine and in my view, for the notion of same language everywhere, JS is a poor language.
Refs: https://vms2.terasp.net/ https://github.com/elestio/cloudgate
There are a lot of little conveniences that are missing. There is no destructuring, no first-class functions (i.e. can’t declare functions outside of a class), no easy way to loop over properties of a class and access their values, no spread/rest operators and other things like that.
I think the C# 9 might address some of these shortcomings.
Some things that I liked about my .Net core project: I didn’t have to write swagger documents at all. They just got auto generated from my API classes. Dapper is better than any micro-ORM that we have in JS. I didn’t have to write a bunch of tests to make sure I was using correct types. It works great on Linux!
Everything’s got its trade-offs. I started my career with Microsoft Access, VB 4/5/6 and complained about moving to .Net. Then I did like 12 years of C# and couldn’t imagine loving JS until I started doing that full-time, since like 2013 or so.... I was glad to polish off my C# skills and to learn .Net core though, just in case I want to switch back some day.
TypeScript is statically typed because of the type annotations and how the compiler checks the type compatibility between objects.
You may can consider TypeScript weakly-typed, because the TypeScript type information are not being encoded into the compilation result.
This is similar to C (being staticcally and weakly typed). You can print int as string and the compiler won't complain.
On the other hand, JavaScript is a dynamically typed and strongly typed language. It is strong as the types are encoded in the runtime. The proof is the keyword `typeof` and its ability to do Reflection.
Reference: Static vs Dynamic: https://en.wikipedia.org/wiki/Type_system#Type_checking Strong vs Weak: https://en.wikipedia.org/wiki/Strong_and_weak_typing
JavaScript has plenty of implicit conversions and will generally only halt execution if it literally cannot do something (like make a function out of `undefined` or the like), much like C, and is a weakly typed language.
[1] https://www.techempower.com/benchmarks/#section=data-r19&hw=...
[2] https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
I think it's totally fair to compare node/js at least to Go. Go is quite simple: it's a GC language, almost without pitfalls except for nil and not error checking type conversions. It's really not unlike JavaScript in many aspects.
Also: node's performance is ok when passing small amounts of data per request. It's when you use it to serve files (images, videos in particular) or larger data tables that it loses steam. And it will take quite a bit of memory, though, unless you start optimizing.
Node is one of those environments that makes it easy to start a project, but difficult to bring it to fruition.
Pretty much every guide/tutorial/documentation says to not use node for this. Isn't this the same for a lot of languages like php, python, ruby, etc? Those all usually run behind a reverse proxy that handles file serving.
Backend performance is usually directly related to cloud resource costs.
Better have a compiled language, even if its within a VM, like C# or Java, rather than interpreted ones like JS or python.
I'm not sure you understand how these languages work as none of the are truly compiled in the sense I think you mean (natively). Both Java/C# and Javascript work in the same way: they are compiled to bytecode which is then interpreted. The only difference is that Java/C# is compiled AOT whereas V8 (presumably) compiles on first execution and caches the output. Python is a truly interpreted language although PyPy can give a huge perf boost.
For one, I am under the understanding that strongly typed languages like C# and Java, are optimally compiled to bytecode such that the overhead of running in a VM is minimal and performance is comparable to native code.
I maybe wrong, I dont have a up to date knowledge of JS runtime and optimizations, but for such a dynamic, loosely typed language, there is only so much AOT and optimization you can do. V8 might have bridged that gap a fair bit, but is nowhere close to performance of C#.
However, in almost all benchmarks, for real world use cases, .net always trumps JS runtimes.Also, a developer needs a high level of awareness and knowledge of underlying systems in JS to write performant code. The same is not true with C#, in the sense that as a seasoned developer, the strongly typed nature of C# mostly saves me from writing poorly performing code. I dont have to worry too much about underlying mechanisms in C#.
Edit : https://stackoverflow.com/questions/35457486/performance-and...
I found this. So, a program made for performance comparision between C# and JS would probably be equally fast in both. However, JS loses performance in real world due to its dynamic typing.
- But you can just use Typescript! Good, I like Typescript but what about some good web framework? You can use NestJS (https://nestjs.com/) which is amazing.
But if you step back, you see that you are basically writing C# that will transpile to JS. So then I just switched to .NET Core.
Feel free to use NodeJS if it allows you iterate faster and your app doesn't need much load.
If you're planning to serve a lot of ConcurrentUser with high RequestPerSecond I suggest to carefully plan the execution.
I'm having trouble now. One of the projects I'm working on is using NodeJS acting as React SSR server (I know it's heavy). It crashes under pressure, with 10-ish CCU reaching only 12-RPS before crashing. The NodeJS server is not clustered yet though. If it is clustered, it might reach a bigger number, but I doubt it would be that significant. Scale up to 1000 users using Kubernetes and see yourself how big the compute bill next month.
This is a fault in architecture and I'm telling you not to repeat my mistake. There are enhancements to NodeJS. NAPI is one, WASM is being introduced too, which is good news. You can utilize child_process and hire someone to write some fast binary for computation-heavy applications and execute that binary.
Again, a lot of companies succeed with NodeJS. It's not to be completely avoided. Just be careful not to use it for something it is not used for.