3 ms·
Oh, I wasn’t aware Node had originally pitched performance. Was it only in the context of single-threaded IO? Yes, from the hiring perspective that “isomorphis
by jmaker 3y ago
Oh, I wasn’t aware Node had originally pitched performance. Was it only in the context of single-threaded IO?
Yes, from the hiring perspective that “isomorphism” makes a lot of sense on paper.
Pardon me, in your third paragraph, what “other factors” are you referring to?
As for the companies that made such a move, well, it’s their choice. There’s always a reason, it boils down in the end just to whether it was well justified at the moment. Time will tell.
A reasonable argument in my decision making was Spring’s huge memory footprint in a microservices architecture deployed to public cloud. Go’s profile was nigh of 100m peak RSS for a given payload, while Spring’s was 1.5g, per instance. I could just take one commodity nano VM at $5 a month instead of multiple 1g-4g VMs at $50-150 a month each. FinOps. It’s a common theme, suppose you have a service mesh with many tiny services, it does sound right to have them utilize just as few resources and be spawnable instantaneously on-demand. So a mixture of Java and Go services comes up quite frequently.
But then you need to factor in a lot of other costs and the fact that Go’s GC will hiccup anyway and potential goroutine leaks could bring down the entire cluster. And so on. That’s just to say that—on paper—it might look assertive, while in reality you would get to realize that there’s so much opaque minute detail behind the Spring or Quarkus APIs that once you realize that it’s missing in your Go or Node code base and get to reintroduce it (wasting hours), you end up with something that need not perform just as well. The more stuff you plug into your Go or Node lightweight frameworks, the more integrational complexity is on you and the less agile you get. It’s all their choice.
There are ways to minimize JVM resource utilization. And you don’t need to always use Spring, and you can have instantaneous start-up times with persisted app state. To me, it’s getting harder and harder to justify Go or Node on the backend.
- throwaway5v54 3y ago> Go’s profile was nigh of 100m peak RSS for a given payload, while Spring’s was 1.5g, per instance. It's not clear from the context if Java actually needed 1.5G to run, or if it simply just saw there was available memory on the instance and made use of it? In my experience Java tends to make use of a larger portion of memory than is actually required. This is a good thing in my opinion, as it reduces the work of the GC. You could try running it on smaller instances to see how it performs, if you have not done so already.
- jmaker 3y agoNo, it was real RSS resource utilization. Basically due to many extra beans being loaded by Spring and extra allocations due to the typical abstractions. If you run it on a smaller instance, your Java process goes out of memory and will have to be restarted. I usually profile all projects thoroughly. You can’t really run a Spring app on less than 512m virtual memory. You can run Java on a few megs, the overhead is negligible over compiled binaries. You can run a lightweight Netty based framework (anything tapir supports essentially) on just 64m heaps. But not Spring. Spring does substantially more work behind the scenes.