
ExpressJS vs. Actix-Web: performance and running cost comparison - dunnock
https://medium.com/@maxsparr0w/performance-of-node-js-compared-to-actix-web-37f20810fb1a
======
jakelazaroff
Is there any surprise here? Anecdotally Node seems fast for interpreters, but
of _course_ a compiled systems language like Rust blows it away. That’s a
known trade off you make when picking a technology like Node; there are plenty
of _other_ reasons to use it.

~~~
jasondclinton
I can only think of ecosystem size and language familiarity. Authors addressed
development speed and found that Rust's static typing and compiler checks
reduced development time vs JS. What other reasons did you have in mind?

~~~
throwaway894345
I’m skeptical of this finding out at least it’s generalizability. I know (and
like) Rust a fair bit better than JS, but I would be surprised if I could
build a nontrivial web app in Rust faster than Node. And that’s without using
TypeScript. YMMV, but I’d be curious to hear from others with experience with
both languages.

~~~
hombre_fatal
I've used Rust for two years and still regularly get stumped.

Recently, I wanted to maintain a map of routes to futures so that multiple in-
flight requests could await the same future while it fetches from disk.

The Javascript version took about one minute.

Using Rust doesn't give you free performance wins, especially not when working
with async code where lifetimes actually get hard. Any time you're carrying
around your own event loop / cpu pool while trying to avoid blocking requests,
that's also another bombshell in itself. Similar challenges when using
something like NIO/Netty, especially towards the beginning.

Add things like sinking a stream of lazy futures into a response and it can be
very hard to understand what your actual performance looks like and where
things will block, especially with parallel requests. The only way you could
say it's a free lunch is if you're a Rust expert who has done it before, which
doesn't apply if you're considering Rust vs JS/TS anyways.

Not to say nobody out there should be writing Rust, that would be silly. But
someone upstream is seriously asking what advantages JS could have over Rust
and difficulty is one of them. And it's not a small one.

~~~
Dowwie
My first attempts with anything in Rust are also challenging. Second attempts,
though, are straightforward as long as I have an example to work from and
haven't forgotten about it. It would take me a lot longer to build your router
example in Node than it did you because I haven't worked with Node but once I
know how, maybe it would take me a minute, too.

What did you finally come up with for your router impl in Rust?

~~~
kaoD
I'm fluent in both Rust and JS. IMHO first attempts are much faster in JS than
in Rust. Rust is much easier to maintain in the long term, and for large scale
codebases it excels once the groundwork has been laid.

------
nwsm
No one has ever been deciding between express and actix-web

~~~
http-teapot
I have, because I did a bunch of Express+TypeScript, always wanted to learn
Rust and wanted to bootstrap a business by optimizing costs.

I liked this article since I always wanted to see concrete numbers or at least
a general idea.

It's not uncommon for business to move from Ruby/Python/JavaScript to Go as
they grow. I personally preferred learning Rust over Go because of its depth.

~~~
ablekh
_"... wanted to bootstrap a business by optimizing costs"_ \-- The famous
quote _" premature optimization is the root of all evil"_ comes to mind. :-)
As a fellow tech entrepreneur, thinking long and hard about my planned
startup's technology stack, I was also guilty of initially leaning toward a
scalable, safe, enterprise-y and fancy, but less mature, stacks, like C# on
.NET Core and Julia, correspondingly. However, upon my extensive research and
thinking, I'm now leaning toward using Python and Flask for API-focused
backend and Vue for frontend. After all, unless you're the next Google (or, at
least, Dropbox), costs of your infrastructure would be negligible compared to
business costs associated with people (due to salaries) and lost time-to-
market advantage (due to higher complexity and learning curve). Should a
startup become wildly successful and scale-driven cost optimization would
become an issue, it most likely would make much more sense from the strategy
perspective to ask a team to rewrite the platform(s) - or, rather, its
relevant performance-critical parts - into a highly-performant language, like
Rust. Having said that, I still think that the containerized applications (not
necessarily microservices!) approach might be preferable, despite
corresponding increase in extra complexity, learning curve, efforts and costs,
because IMO the above-mentioned extras are less significant (and, thus, more
affordable for a bootstrapping startup) than those associated with attempting
to use new to founders or relevant team or not mature enough language and
corresponding technology stack.

~~~
http-teapot
I 100% agree with the point you are making.

A concret example of that is in a comment in this thread:
[https://news.ycombinator.com/item?id=22458176](https://news.ycombinator.com/item?id=22458176)

That said you partially quoted me, if it wasn't for learning Rust I would
stick to Express+TypeScript. If it's bound to fail, I might as well learn and
have fun doing it.

~~~
ablekh
I'm sorry about partially misinterpreting your words - it was not intentional.
I'm getting myself a cup of coffee to improve my level of attention for the
rest of the day. :-) Anyway, I'm glad that we're on the same page on the core
issue discussed.

------
SahAssar
It calls expressjs minimalist, but it has 52 dependencies.

I really feel like we really need to reconsider what "minimalist" means in the
js ecosystem.

~~~
Kaze404
A real minimalist web framework for Node is Koa. Basically anything besides
the bare minimum is a separate dependency, so you only install what you need.

That said, it probably means minimalist in a usage sense. Compared to things
like Nest.js (which I love, don't get me wrong), express is a lot more
straightforward and basic.

~~~
SahAssar
Koa is better but still has 43 dependencies...

~~~
Kaze404
23 according to npm, with a size of 83kb. Sounds pretty minimal to me.

~~~
SahAssar
NPM only counts direct dependencies, so the reality is almost always higher.

------
BossingAround
Can someone ELI5 the node code sample?

> full = full == "true";

Umm.. Why?

> if (!!limit

Not not limit? Is this due to some corner case conversion for JS to make 100%
sure this gets into a boolean..?

I'm sure both samples have its reasoning, I'm just not aware. Any help please?

~~~
mynegation
“!!” is a way to convert any “falsy” value to a Boolean false. E.g. if you
have a flag “enableFoo” that can take the values of undefined, null, numerical
zero, NaN, empty string, and actual Boolean false, all these values will be
converted to false with “not not”. All other values, including - ironically -
“false” as a string, will be converted to Boolean true.

~~~
williamdclt
I even once got a `!!!someVariable` in a codebase I inherited. It's what
convinced me that the previous devs weren't doing weird things to work around
a bad backend: they just didn't know what they were doing

------
tp_13
A lot of Rust advocating here lately. But most miss the point. Nobody doubts
the performance, efficiency, packaging solution or language design of Rust.

A more interesting question is:

As a CTO: Why would or wouldn't you choose Rust over Java, Node or Go?

Rust is not a new language (started in 2006, 1.0 Release in 2015). Why is its
adoption kind of disappointing compared to its technical value?

The answers are not even more benchmarks or another even more wicked zero cost
abstraction async runtime.

I'd like to read stories about some real world adoption. Can your average Java
or Go devs become proficient in Rust in a reasonable amount of time? Is the
code really mostly maintaince free, once it has compiled? Would it have been
cheaper to just add some more servers to handle the load? How about large
teams working on large domains (Java land)?

------
winrid
They are running Node with only one worker and are instead tuning the DB
connection pool in that one worker... So the whole benchmark is bogus.

~~~
jasondclinton
Author addressed this on a Reddit comment thread:
[https://www.reddit.com/r/rust/comments/fbu5tt/expressjs_vs_a...](https://www.reddit.com/r/rust/comments/fbu5tt/expressjs_vs_actixweb_performance_and_running/fj6lqlq/)
. The results aren't significantly different; Rust is still very much more
efficient than NodeJS especially when considering memory utilization (and the
hosting costs associated with that memory footprint).

~~~
winrid
I really don't think the results would be significantly different.

I tried to make changes and run his benchmarks, however the DB seeding is in
Rust and it fails to compile on my machine....

------
wmf
It's worth recalling DHH's report that Ruby code only accounts for 15% of the
cost of running Basecamp: [https://m.signalvnoise.com/only-15-of-the-basecamp-
operation...](https://m.signalvnoise.com/only-15-of-the-basecamp-operations-
budget-is-spent-on-ruby/)

------
rgbrenner
I understand that using Actix really highlights the speed advantage of Rust...
but I think it's irresponsible to encourage rewrites in Rust using a framework
that's dead because the developer decided to quit instead of fix security
issues[0]. The last thing we need is a bunch of new Rust devs rewriting their
perfectly fine Node code using an insecure framework.

Rust is really fast, especially compared to Node. This is an easy benchmark to
win. So why not use a framework that's actually secure.

0\.
[https://news.ycombinator.com/item?id=22073908](https://news.ycombinator.com/item?id=22073908)

~~~
Chyzwar
Express.js active development seems to stop. The last commit on v5 branch was
from October 2018. We are still waiting for http2 (2 years) or better support
for promises (3 years).

    
    
      https://github.com/expressjs/express/tree/5.0
      https://github.com/expressjs/express/pull/4196
      https://github.com/expressjs/express/issues/2761
    

If someone is doing a new project in node I would recommend:

    
    
      https://github.com/fastify/fastify
      https://github.com/hapijs/hapi
    

In the above benchmark, fastify would probably narrow the gap.

    
    
      https://www.fastify.io/benchmarks/

~~~
srgpqt
I feel like Koa JS deserves a mention.

[https://koajs.com/](https://koajs.com/)

~~~
hombre_fatal
Koa is great and makes the two obvious improvements to Express: first-class
promises, and bubbling up a representation of the response instead of having
your routes directly send the response. So you now have middleware instead of
just Express' "beforeware".

