[Rust or Node.js] what's your opinion?

Would you choose Rust (actix-web, rocket, or something else) over Node.js (Express.js) for production applications?

Let's assume the development team is small, and this app will have a frontend (react/vue) and backend(?what will you choose?) & a database(psql/mongodb).
Let's assume it's a forum app with chat and post functionalities. For example a mini version of Reddit or this rust forum.

As far as I understood from reading articles online, it seems actix-web, in general rust, has great performance on CPU and Memory usage.

What do you think is the most important aspects of such an app to be production ready? What are the things one should consider?

Since we're on a Rust forum and not a nodeJS forum, I think my preference for the initial question should be obvious.

I have used actix-web for quick demos, and it was fine. It's a bit older, and its design is... unique. If I was starting on a similar project today, I would probably try out axum instead.

I think this question is much more interesting. In no particular order, these are the production-readiness things that come to mind:

  1. Code is fully[1] tested.
  2. Document all the things! Rustdoc is actually really awesome. Testing in doc comments keeps your documentation up to date with the code, and docs.rs is magic.
  3. Hook up cargo check, cargo clippy, cargo test, etc, to CI! GitHub Actions makes it smooth once you get it all working.
  4. Metrics and dashboards. I have used cadence with good results. The company I was at had Datadog, and the integrations worked great.
  5. Performance profiling and benchmarking. Just because it's written in Rust doesn't mean it will perform great out of the box! Always profile. Benchmarking can help, but it's easy to get bogged down with meaningless microbenchmarks. Did you remember to set target-cpu=native? Did you remember to set lto=fat? Are you using a connection pool?
  6. Deployment model and strategy. Is this going into a container or bare metal? Do you have all the Terraform stuff figured out? Kubernetes? Is the process documented? Have you considered load balancing? Do you need zero-downtime deploys? Are you using tcp_tw_reuse? Have you increased the open file descriptor limits?

And probably a billion other things I can't think of off the top pf my head. But this should be a decent starting point. I should probably point out that it depends on how serious you are with this project. If you're just messing around (customers will not be depending on this server) and you're ok with quick-and-dirty and you're already comfortable with nodeJS, no harm in just using that.


  1. For some value of "fully". :joy: At least unit tests. Cargo makes it so easy to run tests that you need a really good excuse not to use it. ↩︎

4 Likes

I'm very serious about this project. I lack experience, so I am asking for knowledge. If it's possible for you to help me, please send me a message in [Moderator note: email removed]

Depends entirely on the details of the app.

If I was GitHub remaking the backend for how I would store all the git repos, then I'd use Rust.

If I was a little shop making a backend for a custom CRUD app used by a few dozen people, I'd probably just use Node.js (or Java or Python or whatever I was already familiar with).

3 Likes

Yes, any day.

It's not even the performance. Most systems don't even need performance, and if that were the only concern, one could get away with Node or Python or Ruby or PHP 99% of the time. The much harder problem is getting a team to work together on maintenance, without individual developers screwing up each other's work.

For this, I found that dynamically-typed languages are not great, to put it mildly. For anything that needs to be reliable, robust, and easy to maintain by more than one person, I would strongly advise any team to consider a language with a strong type system if there is enough expertise (or willingness to learn) on the part of the team. Whether it's Rust or Haskell or OCaml or something else is then another question. I know from experience that Rust has great tooling, a wide ecosystem of libraries for web development, and you can expect the community to be able to answer your questions. I don't know about Haskell and OCaml, but I do know about real-world backends that were written in Haskell.

In contrast, I have worked on multiple Node.JS-based backends, and on each occasion, it was only a matter of time before bugs started to creep in, and the corresponding maintenance work overwhelmed a significant portion (say, a third or half) of the development team.

I have also worked on a project which featured a Node backend developed by basically a single person. That did work out and turned out to be maintainable, because that developer could keep the entire application in their head. Once that isn't the case, however, it's extremely important to communicate intent clearly and precisely, and in a way that enforces that developers follow the rules. This is nigh impossible without a strong, static typesystem (no, TypeScript is not a strong type system, nor is MyPy or similar approaches that try to bolt types to dynamic languages after the fact).

Another aspect in which a statically-typed language excels is information/data security. A higher degree of correctness implies that some security vulnerabilities are eliminated, yet others are harder to make. This should also be a top priority for web applications in my opinion. There have been quite some unacceptable leaks, security compromises, and other mistakes in the industry – but of course that isn't merely caused by the lack of typing.

Note that you won't automatically get great performance just because you use Rust. You can write slow code in any language (for the most part, that is not something the type system can protect you from), but perhaps Rust is at least easier to optimize and get reliable performance from. You will still need to put reasonable effort into thinking about what you want/need to optimize (e.g., do you need async and/or threading, does your problem require a lot of DB wrangling or in-memory computations, do you need to perform math-heavy calculations with vectorization, etc.), and design your code accordingly.

2 Likes

One thing that would definitely push me towards using Rust is any non-trivial use of concurrency.

I just hit yet another bug at $RealJob where we were using something from multiple futures that turned out to be not thread-safe, since it's basically impossible to check if something is, or to notice if you're doing it wrong. And, interestingly, it's making machines useless as it results in infinite loops inside a data structure, so the machine slowly gets to 100% as different threads get unlucky.

Rust checking that at compile-time is amazing.

5 Likes

An interesting question and one we have dealt with around here in recent times. I rate JS, Rust and C as my current favourite languages. So here is my story....

TL;DR Not only would I choose Rust and Rocket for production application we did for the latest projects of our little company. There have been no regrets. I have no hesitation recommending Rust for such things.

As a user of C/C++ and the other compiled languages going back many years, a few years ago I found myself needing to develop some "web"/"cloud" services. A whole new world to me but I knew there was no way I was going to tackle it in C or C++. Just at that time Node and things like Express and SocketIO were new kids on the block. They promised a quick and easy way to get what I wanted done. A web server, REST API's, real-time feeds for data visualisation via websockets, easy DB interfacing. Those around me though I was crazy as all this was so new, still barely more than experimental. I had seven weeks to assimilate all that and get a demo working for some expo.

Lucky for me it all worked out well and the Node ecosystem grew at an incredible rate providing for everything I needed in the years ahead.

About three years ago I found myself starting a new company with some very similar project requirements on the table. Just at the time I discovered Rust and could not resist investigating it, being the only new language to hit mainstream attention that had anything new conceptually in it since ALGOL.

One of those requirements called for a service to provide a lot of decoding of messages from a horrible proprietary binary format from "edge" devices. Quite demanding of processing power and not at all suitable to do in Node. Normally I would have done that in C++ but it seemed like a good exercise in Rust for me. So I did, it worked very well.

Then I discovered Rocket so that got pressed into service. Then Tungstenite for web sockets. And so on. And pretty quickly Rust replaced all thought of using node for our projects.

Why did Rust take over?

Rust's performance over JS is attractive of course. Essential in some of our cases, but it is mostly not the main motivator.

It's about confidence, reliability, robustness, predicability, ease of maintenance.

All that type checking and "borrow" checking that gets done is going to stop you in your tracks at compile time rather than being called out when something unexpected goes bump in the night. It removes a whole raft of bug hunting. Some say that if you can get your Rust to compile it's going to work. Not true of course but it certainly gets you a long way there.

Strict type and borrow checking provides great confidence that nothing unexpected is going to creep in when it comes to maintenance, refactoring, feature addition.

All this contributes to increased confidence in the security of ones creations.

Rust is certainly harder to get started with. There is a lot to learn in there. Getting programs to compile can be frustrating. After all this time I have only scratched the surface of Rust. However it turns out most of the Rust I write does not look much different from JS. I don't get into traits, generics much. I have only ever written one macro. If I find myself needing lifetime tick marks I step back and think of a nicer looking way to do it. clone() is your friend. Performance may suffer as a result but it's still way better than JS. Also I don't want to scare colleagues away from Rust by making it look to alien to them.

We still use node for small, quick jobs. Experiments, throw away code. For anything bigger it's worth the investment into building something solid in Rust.

3 Likes

I wrote a travel app in node.js before .

Node.js is not comparable with Rust.
Rust is fastest, No GC, Not Overhead, great syntax , great pattern maching, Rust is Best .

Actix_web is great for io-bound app
If your app is cpu-bound like many processing in server response it is not best choice because don't use work-stealing , each Thread is a Worker and Seperate from each other. But routing feature is very great.

Axum use work-stealing also is and of fastest and simple web framework, we use it for our benckend , serving to real-time application without any problem

If your back-end is mostly moving stuff from the database to blobs of JSON, then you probably don't need Rust.

You may want to use Rust for some CPU-heavy parts of the system. For example, if you need to analyze logs, Rust is great at parsing and having efficient in-memory data structures.

4 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.