September 22nd, 2024

One Year of Rust in Production

Dmitry Kudryavtsev reflects on a year using Rust for his project JustFax, highlighting its type safety, stability, and superior tooling, while noting challenges with compile times and frontend development.

Read original articleLink Icon
One Year of Rust in Production

Dmitry Kudryavtsev reflects on his first year using Rust in production, particularly in his side project, JustFax. Initially, he migrated from LemonSqueezy to Stripe, which unexpectedly expanded into a significant refactor involving job processing and accounting systems, all implemented in Rust. Kudryavtsev emphasizes Rust's type safety and compile-time checks, which prevent many common errors found in dynamic languages like JavaScript. He appreciates the stability of Rust applications, noting he has never experienced a crash, unlike with Node.js. However, he acknowledges the challenges of Rust's compile times, especially with complex projects, which can lead to slower development cycles compared to JavaScript. Despite these drawbacks, he finds Rust's tooling superior, with less boilerplate and a more straightforward project setup. Kudryavtsev also points out the limitations of Rust in frontend development, where rapid prototyping is hindered by the need for recompilation. Overall, he expresses satisfaction with his choice of Rust, attributing it to improved software quality and job security.

- Dmitry Kudryavtsev has spent a year using Rust in production for his project JustFax.

- Rust's type safety and compile-time checks help prevent common coding errors.

- He has not experienced any crashes in Rust applications, contrasting with his experience in Node.js.

- Compile times in Rust can be lengthy, affecting development speed.

- Kudryavtsev finds Rust's tooling to be more efficient than that of JavaScript frameworks.

Link Icon 10 comments
By @throwup238 - 4 months
> Compile time is still PITA

This is Rust's Achilles heel and has been since almost day one. Once a project is at a nontrivial scale, it really starts to weight it down. I'm working on a Rust/C++/QT QML desktop app and I've spent the last week refactoring my crates/libraries so I can split them off as shared libraries that can be built independently, otherwise even incremental builds can take minutes. Thankfully there are some crates to make a stable ABI and dynamic reload.

> LLMs rarely help with a proper solution, as most of the packages are kind of niche.

This has also bitten me quite a bit but at the same time, I've been impressed with what Claude 3.5 and o1-preview have been able to do with Rust even with niche libraries like cxx-qt - a relatively new library with little in the training data. A lot of stuff like writing Rust implementations of QAbstractListModel works really well when given the right context (like an example implementation of another list model).

LLMs have also been a boon for writing macros, both macro_rules and proc macros.

By @Stem0037 - 4 months
The "if it compiles, it runs" phenomenon is indeed one of Rust's strongest selling points. It's amazing how much confidence you can have in your code just because it compiled successfully. However, I'd caution against relying on this too heavily - there are still plenty of logical errors that can slip through compilation.

The author's experience with sqlx is spot on. It's a game-changer for database interactions, though it does come with some drawbacks in terms of compile times and CI/CD pipeline complexity.

One point I'd add is about the ecosystem. While it's true that Rust doesn't have the same breadth of libraries as, say, JavaScript, the quality of the libraries that do exist is generally very high. And the community is incredibly helpful when you do run into issues.

By @empath75 - 4 months
I've been running rust in production for roughly a year and the 'if it compiles it works' thing is very much true. Once we cleaned up all the 'unwraps' and 'expects' after a few days and switched to proper error handling, we had a _single_ crash caused by an unchecked add in an underlying time library (combined with a bad integer cast sending it bad input).

That statement is not really just about memory safety, but it's also about the type system and pattern matching, which prevents a lot of _logic_ bugs that would cause runtime errors and not just memory safety problems. You don't have nil pointer dereferences like you do with go, you don't have problems with accidentally passing a single item instead of a list of items, or a string instead of integer like you might get with python.

It's also a lot easier to write than it's reputation would imply, especially if you don't especially care about memory efficiency or performance and you aren't writing close to the metal, and you can just clone stuff onto the heap all over the place. Even with that, it uses way less memory and cpu than a comparable app in python or java and it's usually more efficient than go.

By @jksmith - 4 months
# If it compiles, it runs # And when it runs, it’s very stable

Modula-2 40 years ago. The ship had strong bones to build upon a long time ago, but alas, C. The tyranny of the masses.

By @dicytea - 4 months
> sqlx — a compile time, type safe SQL wrapper that runs your queries against a real DB

SQLx seems like end game stuff at first glance, but after trying it out for a while I eventually decided that it wasn't for me. Writing dynamic/conditional queries just sucks and there isn't any good solution. On the DX side, completion, formatting/linting, highlighting is also non-existent (at least on VS Code).

I eventually settled on [Diesel][0] (a query builder-ish ORM) and I'm loving it so far. Its [performance][1] crushes every other SQL libraries, including SQLx (very counter-intuitive, huh?). It's technically an ORM, but the query builder is very flexible and you can also extend it with your own traits. It got its warts, but it's the most tolerable SQL rust library I've found so far.

[0]: https://diesel.rs

[1]: https://github.com/diesel-rs/metrics

By @super_linear - 4 months
Nice article, but was looking forward to more of the "in production" angle (e.g. more operations, monitoring, performance). Instead this seemed to more focus on the the maintainability, developer experience using Rust and the ecosystem.
By @Havoc - 4 months
> LLMs rarely help with a proper solution, as most of the packages are kind of niche.

I find that they’re quite good at converting example api calls between languages for the most part…though haven’t worked in rust for a while

By @tempodox - 4 months
sccache can help with compile times:

https://github.com/mozilla/sccache

By @noisy_boy - 4 months
I keep coming back to learning/practicing Rust (I really like it) but every time the job market seems to have very few jobs where I am. Wonder if I need to look for fully remote Rust jobs? What is the experience of people doing Rust as $MAIN_JOB?
By @jpc0 - 4 months
I was hoping to see a good review of rust that would convert me from Go/C#/Java but alas this was not it.

Seems like the writer finally experienced an errors as values statically typed language which doesn't have a ton of legacy in it. Many of the issues OP mentioned (CJS vs MJS, configuration file changes) comes from being around for a while, Rust just hasn't had the time in the saddle yet to show how they would deal with that. Don't get me wrong, I'm not saying they won't deal with it well but Python 2-3, Vue, JS CJS to MJS etc all show that a fundamental change to some core part of the language / framework is very tough to navigate and quite frankly Rust hasn't needed to do that yet.