7 ms·
Web developer currently learning Rust and curious about Actix Web here: how does it compare to let's say Node.Js in regard to performance and security? Any feed
by Zealotux 6y ago
Web developer currently learning Rust and curious about Actix Web here: how does it compare to let's say Node.Js in regard to performance and security? Any feedback on real-world projects to give?
- jnsaff2 6y agohttps://www.techempower.com/benchmarks/ https://www.techempower.com/benchmarks/ gives you some idea about the performance.
- smcleod 6y agoThat’s more than a little impressive.
- skocznymroczny 6y agoPerhaps, however, according to [0]: "The Actix benchmarks which are winning are written at an extremely low level, with manual parsing, hardcoding header values as 'static string literals, ignoring HTTP methods, and basically being fast by skipping all of the work a real-world HTTP server would need to do to be effective" The quote is 9 months old, but I doubt it changed since. [0] https://www.reddit.com/r/rust/comments/e7xwma/rust_actix_is_the_only_web_framework_to_finish_in/fa83p0t/?utm_source=reddit&utm_medium=web2x&context=3 https://www.reddit.com/r/rust/comments/e7xwma/rust_actix_is_... [1] https://github.com/TechEmpower/FrameworkBenchmarks/blob/master/frameworks/Rust/actix/src/main_raw.rs#L26 https://github.com/TechEmpower/FrameworkBenchmarks/blob/mast...
- hobofan 6y agoThere is a very recent, closer-to-real-workloads benchmark: https://matej.laitl.cz/bench-rust-kotlin-microservices/ https://matej.laitl.cz/bench-rust-kotlin-microservices/
- ncrmro 6y agoOne problem that was kinda show stopper for me is sentry support is kinda not working with recent actix versions.
- dvdplm 6y agoAFAIK the Sentry people are big on Rust and very responsive. I’m sure they’d react well to a bug report. :)
- ncrmro 6y agoI think they were aware of it https://github.com/getsentry/sentry-rust/issues/187 https://github.com/getsentry/sentry-rust/issues/187 I did build a nice rust boilerplate tho if any one is interested https://github.com/ncrmro/planet-express https://github.com/ncrmro/planet-express
- jamwaffles 6y agoMore "mechanical" stuff like typos in payload fields and deserialisation is MUCH safer (and more pleasant with the derives!) due to the benefits of Rust's type system, but broader stuff like authenticating requests and user roles is still up to the user to implement well for a web app to be safe. IMO the language helps a ton here too. Performance wise, I don't think I need to repeat half the internet here, but I'll just say you'll be blown away by how little RAM a Rust app/container uses for the number of users hitting it. YMMV of course ;)
- DarthGhandi 6y ago> how little RAM a Rust app/container uses for the number of users hitting it I thought that's only for syncronous libraries/frameworks? With async it blows out quite a bit. Everyone except rocket has got async functionality now too.
- fluffything 6y agoI didn't measure any significant difference on memory consumption with async vs sync. I didn't even need to measure perf to notice a difference.
- nindalf 6y agoProbably worth measuring if that was actual memory consumption or just memory reserved by the kernel. Spinning up several threads will reserve memory but it won't be allocated until you actually try to access it.
- aliceryhl 6y agoThis doesn't seem true. My mental model says that although synchronous may require somewhat fewer resources when there are few connections, async will win as the number of connections increase. To illustrate this, consider the cost of spawning a new thread. The stack of a thread is usually a few MB, but lets use 1 MB for simplicity. Then 1000 concurrent connections is 1 GB of memory just for stack space. With async/await, you don't pay a megabyte per connection because async uses perfectly sized stacks that are typically much much smaller than a megabyte. Of course you can cap the number of connections, but IO speed puts an upper limit on how fast you can serve a connection, which means that the cap limits the number of connections you can serve per second. Additionally, I doubt that the overhead at a few connections is large. There's a reason people call async/await a zero-cost abstraction, even if using a runtime such as Tokio introduces some amount of cost.
- touilleMan 6y agoAn often overlooked but very important point is the ease of use of a programming model. NodeJS has build it concurrency model on callbacks which make non-trivial application difficult to debug and evolve. Since then new paradigms have emerged such as promises and structured concurrency (https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/ https://vorpus.org/blog/notes-on-structured-concurrency-or-g...). Rust has build it concurrency model with those new paradigms in mind, mixing them with it awesome ownership model. In the end Rust brings to the table much stronger guarantees on your code consistency compared to NodeJS, which can save you a lot of time and energy on complex concurrent system ;-)
- gnur 6y agoModern node development uses promises as well.
- ShinTakuya 6y agoYeah in fact they were ahead of the game, not to say I don't prefer Rust, but for a long time promises were a pain in Rust compared to node.
- ragnese 6y agoThey weren't more painful in Rust because of them being implemented poorly or anything. Rust's memory model makes referencing data across scopes difficult. In a GC'd language, your closures can just reference everything willy-nilly. Also, I'm not sure, but I think Scala had Futures before bluebirdjs existed, which was the defacto Promise for JS, AFAIK.
- nicoburns 6y agoI'm not sure if they were first and they were API incompatible with modern JS promises, but jQuery had deferred objects in 2011, 2 years before the first Bluebird commit on Github. Bluebird wasn't the first JS Promise library. It became the defacto library because it was faster than everything else. Edit: https://en.wikipedia.org/wiki/Futures_and_promises https://en.wikipedia.org/wiki/Futures_and_promises has a history
- haywirez 6y agoI've just started to rewrite my NodeJS-based prototype API using Actix.
- 29athrowaway 6y agonode is based on various libraries, among them, v8 and libuv. v8, is a JavaScript engine. An oversimplified way to describe it, is that it has an interpreter and a JIT compiler. Compiled code is faster, but not all code is elegible for that. If you write code that can be optimized by v8, it can run very, very fast. Most of the time v8 will give you decent performance but if you want to maximize performance by minimizing deoptimizations (e.g.: tracing compiler behavior using --trace-opt --trace-deopt CLI arguments)... you will be consuming more time than using Rust. libuv is a crossplatform library written in C that handles all the heavy lifting for node. Using libuv, node creates an event loop and a thread pool, where asynchronous operations can be scheduled and executed concurrently. It also takes care of file I/O and networking. node gives you a decent level of performance when you can delegate most of the work to libuv, or built-in JavaScript functions. But when running user-defined code that is CPU bound, node is not the right tool for the job. CPU bound tasks tend to block the event loop, or make ticks long enough so that it becomes a problem. Blocking or slowing down the event loop causes time sensitive tasks scheduled for future event loop ticks, such as processing events from sockets, to timeout. This can be prevented using worker threads, which are a recent addition to node... but almost all of node and its package ecosystem has been built around the absence of user-facing threads. node can be used to build robust, highly available, performant and secure systems, but you need to know what you are doing and what the limits are. I think node is not the right tool for every job, but when it is, it can be highly productive and save time. Security-wise, node is hard to audit. Packages tend to have many dependencies, and many packages are not built with security in mind. JavaScript itself is a languge that has been built with browser security in mind, but also, JavaScript is a language where almost everything is mutable, including built-in types. Prototype pollution is a big problem. Rust is more flexible, doesn't impose you a threading model, you have access to many concurrency primitives, and all your code will be compiled in a much predictable way. I am not familiar with the security aspects of Rust. At least it seems much safer than C, where it is not hard to create unsafe code.
- steveklabnik 6y agoFun Trivia Fact: long ago, the Rust runtime (when it existed) had libuv in it too!
- sylvain_kerkour 6y agoAfter one year of full-time Rust (starting early 2019, details may have changed since) for web (API) development with Actix, I would not recommend to use it for any serious web project. The language is awesome and the performances too. BUT, there is too many things that will distract you from being productive (compared to Node.js + TS or Go): unstable libraries, compile time is atrocious, cognitive load required to read Rust is high (break your flow), toolchain (RLS auto-completion) is weak, CI/CD costs are too high. You will spend most of your time solving Rust's problems instead of your project's problems. In my opinion Rust is good on a 10-15 years timescale. But your project need to survive 10-15 years... You can read the details here: https://gitlab.com/bloom42/wiki/-/wikis/engineering/languages/rust https://gitlab.com/bloom42/wiki/-/wikis/engineering/language...
- hobofan 6y ago> toolchain (auto-completion) is weak Based on your link, it looks like you are specifically referring to RLS. With the newer contender rust-analyzer[0] auto-completion is very good. In combination with TabNine[1] (for Rust the Pro version is free), auto-completion is pretty amazing by now. [0]: https://rust-analyzer.github.io/ https://rust-analyzer.github.io/ [1]: https://www.tabnine.com/ https://www.tabnine.com/
- sylvain_kerkour 6y agoYes! I've added a little disclaimer because my experience was last year. The ecosystem is moving fast so some details may have changed (which is a cons for me, too unstable).
- ragnese 6y ago> which is a cons for me, too unstable Totally unlike Node, right. ;)
- jokethrowaway 6y agoThat's interesting! I had the opposite experience with Rust With 5 years in PHP, 9 years in node, a few projects in Haskell and sporadic rust usage in the last couple of years: - PHP was great until they added autoloading and everyone started using a half assed package manager - node was great until everyone started using babel and they broke requires / import - python was ok until they split the ecosystem in 2 vs 3 - Haskell keeps getting better (stack, solved record name clashes) because things are rarely broken. It's too bad adoption is limited and there's not much commercial interest - Rust is my new favourite technology, it learned package management from node and functional programming from haskell. New features have been painless and easy upgrades
- golergka 6y agoNodeJS is my primary stack, and I've built toy projects with Rust since 2014, but never used it in production. Rust offers perfomance improvements in CPU and memory usage of the core application logic, and it's almost never the bottleneck for the typical web apps. Almost always, they're limited by IO, and I don't see any reasons why it would be better on Rust that on Node. Also, Rust offers security of safe access to memory, but that's a problem that exists in C and C++, not in GC-based languages. Finally, Rust offers a great type system, but Typescript has a very good one as well, and offers a much easier transition for Javascript Node developers, as well as a much more machure NPM ecosystem. Overall, I just don't see how Rust would make much of an improvement over existing state of affairs.
- cwaffles 6y agoRust offers a few things over Node in my experience: - Super fast startup - Single binary distribution (you can integrate your static assets with rust-embed) - Minuscule ram consumption (0.5MB for a graphql server) - Cargo build system is much easier to work with than webpack - No mismatches between TS types and JS source However the big caveat is the documentation and libraries are still quite lacking
- golergka 6y agoAnything but the last one doesn't really matter for my case. NodeJS app startup takes about 4-5 seconds at most. Binary could theoretically be well into gigabytes for it to make any difference. I'm a pure backend developer, so I don't use webpack. And the mismatch between TS and JS is a pain, but that's why I'm looking forward to Deno.
- staticassertion 6y ago> Rust offers perfomance improvements in CPU and memory usage of the core application logic, and it's almost never the bottleneck for the typical web apps. Has anyone actually managed to find that this is the case? Just because your app is stalling on db queries doesn't mean it's "IO bound". Even the most trivial service that's just routing messages between two other services is likely to be radically faster when implemented in Rust vs JS.
- pornel 6y agoPerformance rocks. For services that do significant amount of computation/data processing, Rust is typically order of magnitude faster and uses less memory. If your service is bottlenecked by a database or an external web API, Rust won't magically solve your problems. Rust has a pretty strict type system, and there's a lot of focus on correctness and reliability. Rust's enums with data are great for handling application state. This helps security, since the language stops you from doing entire classes of silly mistakes. I've written some sites in Actix and it didn't feel too different from using express.js (with a caveat that I am experienced in Rust, so the language itself isn't an issue for to me).