I'm not sure I agree with the article's premises. Rust can be difficult, yes, but it can also heighten developer productivity above other languages. In Go, I'd have to worry about whether I checked for exceptions via `if err != nil` everywhere, while with Rust, I can depend on the compiler telling me if I haven't done so exhaustively, via the Result type. Same for having algebraic data types or, well, generics in general.
I will also push back on other commentors here saying Rust is not good for web apps and APIs, and I have found that to be the opposite of true. I read Zero To Production In Rust [0] (a great book by the way, all about creating a web API with actix-web and Postgres) and deployed an API that has not gone down a single time since deploying near the beginning of this year. It's as ergonomic as (and sometimes even more so than) any NodeJS or Go API I've made (as even though Rust doesn't have function overloading, actix-web and others have some macro magic they do behind the scenes to make it appear as if it does), and there were very few times I had to contend with the borrow checker. If there had been and if I were really going for speed, I would also have cloned everywhere that was needed.
When I write something in Rust and it compiles, I can depend on it to work, and to continue working. At the end of the day, use the tool that makes sense for your business, but I don't think Rust was necessarily a bad choice based on my personal experience with it.
God I get tired of the if err criticism with Go. I truthfully don't even notice it when I write Go, I don't understand why folks get so bent out of shape over it.
It's nice to read that someone else has had a positive experience with the zero2prod book. I'm working my way through it and my impression so far (even after reading the official "book") is that Rust is hard; I enjoy the challenges and the eventual realizations, but working my way through some of the chapters that involve implementations, traits, and macros makes me wonder: Would I actually be able to do this myself in a reasonable amount of time, in a professional setting?
Agreed! And personally, I've found that "Zero To Production Rust" is absolutely phenomenal! I feel like it's the equivalent of "The Book" for using Rust on back-end apps!
Thank you for linking to zero2prod. I just bought it after looking at the repo for the example code and scanning the sample. I wish I’d read this book a year ago.
I’ve worked my way through a couple of rust books, but this was the first one that actually talked not just about the language, but the entire development flow. Git workflows, CI/CD, docker, comprehensive testing.
Even after clearing the initial rust fundamentals, there are so many standard libraries like anyhow, chrono, serde, thiserror, and tokio that are almost required knowledge, but aren’t covered in most books.
> It's as ergonomic as (and sometimes even more so than) any NodeJS or Go API I've made (as even though Rust doesn't have function overloading, actix-web and others have some macro magic they do behind the scenes to make it appear as if it does)
Not that this takes away from your point, but does Go have function overloading? I had assumed it hadn't given the discussions I had heard about what it would take to retrofit `Context` parameters on everything when they added that type, but I guess maybe this could be one of those "functions can but methods can't" things (which I think I heard is how they do generics as well?)
I agree with you about Rust and the web - it's a great fit for a performance-oriented web backend.
Personally, I actually think it's a worse fit for things like kernel/embedded development than for web backends. The ergonomics of Rust are so Javascript-y that the web is natural, and other environments where C is used are a lot messier and trickier.
7 years ago I’ve deployed the first version of the REST API service written in Rust. We had multiple deployments in consecutive 5 years. For 2 years this service runs without any updates.
There were just a couple of failures in the first 2 months.
I would say that using Rust for backend APIs seems a bit off. I like Rust, but introducing languages that can be made unsafe / can at a minimum memory leak seems irresponsible.
Its dumb when the C++ community refuses rust when it guarantees memory safety, so why would you bring in a language you prefer to an area that doesn't need it if it introduces that issue?
If you like Result<> or concurrency, use a GC language with those things. Go may not have them, but your choice isn't just Go.
> With Rust, though, one needs to learn entirely new ideas — things like lifetimes, ownership, and the borrow checker.
This is really the main reason not to use Rust when you need to move fast: if you don't know the language yet, it will take you time to learn it. But that's true of any language. You probably shouldn't do your startup in Java, either, if your team isn't familiar with it.
Yes, Rust's learning curve is steeper than many other languages, but still... if you're an early-stage startup and you need to move fast, write in a language that you and your team already knows.
> You probably shouldn't do your startup in Java, either, if your team isn't familiar with it.
Java is wildly easier to pick up than Rust, though. Hordes of productive enterprise java programmers are employed today who frankly don't even understand what memory safety even means, much less the tradeoffs their language runtime (or software) needs to make to ensure it.
It's certainly a truism that you should tailor your development environment to the talents of your staff, but that doesn't mean that all tools are equally applicable. Would you do a startup today using APL or COBOL?
> We hired a ton of people during my time at this company, but only about two or three of the 60+ people that joined the engineering team had previous experience with Rust. This was not for want of trying to find Rust devs — they just aren’t out there.
As an experienced Rust dev, I had the opposite problem. I looked for a good Rust job, but couldn't find one. Took an Elixir job instead.
I also don't get the complaint about lack of productivity. I've worked in a dozen languages, and Rust is still the most productive language for me by far. I feel like they're speaking from inexperience here. I'm slow whenever I start a new language too, and Rust was no exception. Keep at it, however, and it'll pay off in the long run.
> My primary experience from Rust comes from working with it for a little more than 2 years at a previous startup. This project was a cloud-based SaaS product that is, more-or-less, a conventional CRUD app
I think this should be at the top of the post. Rust seems like an obvious bad choice for this. For something not performance-sensitive that doesn't require most of Rust's power just use languages/frameworks that are made for this kind of thing. Of course you can do this with Rust, but you're probably picking the wrong tool for the job. The Rust ecosystem around building typical webservices isn't nearly as good as it is for other languages, and the benefit you get from Rust's safety and performance is worth less than the iteration speed you gain from the standard Node/Python/etc approach.
That is the main point of the article. It was a poor choice for what they used it for and most startups aren't writing system (or even desktop) software but are building web apps.
A CRUD/SaaS web team should only be using it for high performance areas with a few microservices. At least until the web side of Rust significantly matures (mostly in the people/community side not just code).
But I've used Rust mostly for performance-critical CLI tools, or highly specialized servers. Typically, these have a narrowly defined job that must be done reliably and efficiently. Rust shines at this. These tools run reliably with almost no changes, often for years at a time.
But I have learned that it's often less useful putting policy and frequently-changed business logic in Rust. That kind of code is often accessible to more developers in a strongly-typed scripting language.
> That kind of code is often accessible to more developers in a strongly-typed scripting language.
I assume that you’re thinking of TypeScript or Python with type hints.
Do you mean that these languages are more accessible because they are more widely known by developers or because codebases in these languages are easier for some reason to change frequently than codebases in Rust?
Interesting. By contrast, I wish I had used less Python and more Rust for my company's product because Rust is considerably more productive. We were building gRPC and web services.
I just haven't found it to be the case that developers have a very hard time learning it, but we haven't grown to the point where that would maybe be the case. We also lean heavily into microservices so "oh there's no library in Rust but there's one in Python" is low cost, we can just write a service in Python.
In my experience, Python is one of the least productive programming languages for projects with more than 3 people. If you have a big project, you are going to spend a lot more time reading code than writing it. Python is write-optimized.
By contrast, using Rust makes it easy to force a readable coding style on yourself and others.
I think that most of why Rust is popular is just that it's a very modern programming language. It has all the nice things people want and surprisingly little of what they don't. So it's no surprise that for some people it's more productive.
But the article pretty clearly outlined a super simple CRUD app. These days that's a problem space so well defined you can practically specify the whole thing in command line flags. Rust really has little to add there. For other stuff, yeah Rust can be super cool.
> Rust was used primarily because a couple of the founders of the company were Rust experts
It's remarkable how significantly the first few months of a project impact the first few years of a company. How quickly casual & spontaneous decisions, largely based on convenience and familiarity, ossify into legacy drag.
I've noticed that Rust is in an interesting spot - it has a lot of overlapping appeal with various groups.
- C/C++ developers like it as an alternative for low level languages
- Functional programmers like it because of it's functional features
- "Cargo Culters" / "Hot Language" / "Flavor of the Month" followers like it, as it's in vogue at the moment (this is the crowd that has likely shifted from various web/API scripting languages over the last decade - (php|ruby|python) -> nodejs -> rust)
However, as the article alludes to, for the third crowd, Rust is just likely not a great fit (even if it has a lot of neat features and introduces some great concepts others may not stumble on of their own accord) when your implementation doesn't do much beyond web dev/API/scripting purposes.
I've written a few APIs in Rust and I'm kinda baffled on what the author is trying to convey. On the one hand he mentions that it's a simple CRUD application, on the other hand he mentions complexity that arose from using Rust. I wish he gave some concrete examples of problems that they have. From my experience, when writing web APIs, most of the problems with Rust are not really that visible. Most of the time you get a request, process some data or interact with a database (or both) and return the response. In this scenario you don't often have to deal with lifetimes or any of the advanced stuff.
While I respect the author's anecdote, this doesn't match my experience. I've been programming for 20+ years across a wide array of languages and I'm by far the most productive in Rust.
With a competent teacher, experienced devs should be able to pick up on the memory model pretty quickly, and that is really the only initial blocker to productivity. After that a dev can essentially write procedural code if they want, like other common languages, while refining their thinking and practices towards idiomatic Rust.
I agree mostly with this, however, ownership can be strange in Rust if you’re not familiar with it. Something simple like a linked list can be challenging to implement.
how can you be more productive in rust, where you do have to worry about object lifetimes than in languages where you don't, and where you can focus more on algorithms, say java?
Isn’t it about time for a language with a runtime with an HTTP server and SQL database? There’s literally millions of us writing basically the same code over and over again: listen on port 80, parse and transform text more times than necessary to make a SQL call to then parse and transform the returned rows into text more times than necessary to return some JSON or HTML.
The wasted clock cycles and developer hours more than makes up for the slow down in productivity rates we’ve seen across advanced economies lately!
I haven't tried this, but I think you can get fairly close by generating the HTTP/SQL serialization code. When I get time I want to write an openapi schema amd generate the server code, write a db schema and generate the db code (I want to try https://github.com/ariga/atlas with Ent for this), then write the business logic between them and see how well it all works
It's not a language, because why do you need language for that. But it's called Hasura, written in Haskell. It's a server which translates Postgres into GraphQL.
Modern OpenJDK comes with a built-in HTTP server, and you can also embed a relational database like H2 or of course SQLite. You can use it from many different languages, of course. Actually it sounds from the article like Kotlin or Java would have been a better fit than Rust for what they were doing. There are also things like Postgrest which turns postgres tables into REST APIs automatically.
But here's something to really chew on. Do we need the HTTP server at all?
Consider: why exactly do we need so much middleware plumbing for ordinary database driven web apps? A lot of this is to do with a winding evolutionary path rather than what you'd design with a clean slate.
Something I've been experimenting with lately is writing apps that connect directly to an RDBMS using its native protocol, over the internet, from a desktop app. Obvs the next step after is to try the same with a mobile app. Historically we've relied on web browsers and written translation layers for a few different reasons, but tech has been improving over time and some of those reasons are becoming obsolete:
1. Free relational databases were really rough back then and the commercial DBs often had weird limitations around distributing DB drivers. These days it's easier and postgres is a lot better.
2. You needed to slather lots of caches and other stuff in front of the RDBMS if you had high traffic. Modern DBs are a lot better at materialized views, cached query plans, read replicas etc. Postgres has a variety of load balancers that can sit in front of it and work around its per-connection overhead.
3. Security wasn't good enough. Nowadays you have features like row level security, security-definer views etc in the free DBs.
4. People translate everything to HTML/HTTP partly because it was too hard to distribute and update apps to Windows desktops/laptops in the 2000s, due to MS just generally losing the ability to execute and being distracted by stuff like Longhorn/WinFS. Browsers solved the basics of caching and refreshing of code for you. Now there's https://conveyor.hydraulic.dev/ which makes distributing desktop apps way easier. It's a lot more feasible now to just knock out a quick desktop app and upload to an S3 bucket, with built in online updates. Also the next release will support force-update-on-start, so you can get a web like experience where the user is always up to date so the schemas and client can be evolved in parallel.
If you could just write your UI using a 'real' UI toolkit and invoke directly to the DB from the UI code, you wouldn't need a lot of the microservices plumbing anymore, you wouldn't need to serialize stuff to JSON or HTML. You could just use the underlying DB protocol as an RPC layer and let the DB enforce business logic. It can be done for common kinds of enterprise apps today: there are only a few problems to solve, none of them especially hard. For instance a little service that turned OAuth SSO into client side certificates would make it easy to connect to a DB without needing to manage usernames or passwords. A tunnelling solution to get through awkward firewalls would also be useful (websockets etc).
For consumer apps there's more complexity. You wouldn't try to implement twitter that way for instance. But still, for the kind of SaaS-y thing that the article is about it could have saved a lot of complexity and improved iteration speed.
> This project was a cloud-based SaaS product that is, more-or-less, a conventional CRUD app: it is a set of microservices that provide a REST and gRPC API endpoint in front of a database, as well as some other back-end microservices
Of course.
Use Java/Kotlin or Node.js/Typescript or Go or Python for your basic web services.
Easy test: Would you at least seriously consider using C/C++ for it? Only then should you use Rust.
The difference between C++ and Rust here is that Rust has a large variety of easily-accessible third-party libraries you can drop in with a one-line change to your Cargo.toml. I think the assessment is no longer that straight-forward. There's some solid crates for building these types of endpoints now, but an honest self-assessment is required to see if it really meets your needs from a staffing perspective.
I'm a Rust-stan for sure, but I probably wouldn't use it for this task either as it'll be hard to find other people who know how to use it - and also for this task. Here's hoping that changes, though.
[edit] I might also add it's not a good fit for making these types of endpoints at a startup as the goal of a startup isn't really to write perfect/correct/safe code, but rather to ship a product as fast as you can so you can iterate on the product-market fit. Quick and dirty in another language is probably a better fit for the business case. Rewrite it later.
> Easy test: Would you at least seriously consider using C/C++ for it? Only then should you use Rust.
This is a great point. I understand liking a language, but don't bring Rust into a GC space (in industry, personal projects can be what you like!) You can find a GC language with all the features of rust you like.
I didn't see it here, but one of the points that doesn't seem to be expanded on too well is that despite liking Rust, I wouldn't use it for a basic web server in a startup environment either, mainly because the whole environment around web stuff is too immature in my experience.
Ruby on Rails certainly isn't perfect, but it's a highly battle-tested web framework. It's been so widely used for so long that you can have high confidence that you won't run into any bugs that will require digging into the guts of it. You can write code against it and be highly confident that any bugs or misbehaviors are in your code, with difficulty of finding and fixing dependent only on how good the code you've written is.
With Rust, I don't think that's the case. The DB and web server related libs just don't seem to have that much manpower behind them, and haven't had big complex services built on them in production for years. If you want to do anything mildly complex, there's a good chance you'll have to dig into the guts of these to figure out what's really happening or to resolve some weird bug or add a feature. That'll require a lot of skill, even if the code you're actually writing is mostly straightforward.
The arguing about Rust seems to miss that Rust protects against more than just security bugs.
If you've ever generated some object out of some factory and then tossed it on a list of things and then gone back to generate a new object out of the factory and found that the first object you put on the list got scribbled over because you forgot to clone it, then that's a category of bugs that rust entirely prevents.
And I thought I was pretty good about reasoning about data ownership in other languages, but the borrow checker is teaching me how to be a lot more careful.
You can also use immutable/persistent data structures and GC, which gives the same safety from bugs, but is much cheaper from the perspective of precious time spent.
It took me almost a year to be as productive (and my code as canonical) in Rust as I was after over two decades of C++.
After a month of Rust I was still fighting the borrow checker and grokking basic concepts of the language. So no surprise in what you wrote.
However, after that year I am probably a factor of two to ten more productive in Rust.
The speedup is about two for everyday code (if it compiles it runs and doesn't crash). Ten (or more) when I need to bring in a dependency.
To qualify the latter: if a crate with same functionality or a Rust wrapper for a C/C++ lib exists, the factor can be much, much higher than ten since it is just adding a line to Cargo.toml.
If the dependency is a C/C++ lib it is as slow as using it from C++. It needs to be integrated with the build and that takes about the same time plus writing/generating a wrapper.
All that said: I had to write code in C++ the other day again. It almost felt painful after three years of only Rust.
Although I like Rust, C++ keeps being my systems language when coding outside Java, .NET and Web.
Why?
Those ecosystems are built alongside C++ tooling, so no need to add an extra layer of indirection.
I already have the safety from those ecosytems, if I am reaching out to C++ is exactly because I need to do some unsafe stuff, or binding libraries that are anyway written in C++.
Well if you had 10 yoe with C++, you would certainly not achieve the same level of productivity with Rust for a while. Your point is valid in the sense that you should use the tool that you know if you need results, but it's not great criticism towards Rust.
"I would much rather have my team sink time into debugging the occasional memory leak or type error for code written in, say, Python or Go, than have everyone on the team suffer a 4x productivity hit for using a language designed to avoid these problems entirely."
I'm not sure if I agree with this. In fact, I'm pretty sure that I don't. These "occasional" nuisances become big blockers after a while and not only decrease productivity but hurt customer goodwill as well when they're not discovered in time.
There's a reason why we see so many articles like "we rewrote x in rust." Rust makes sense when you've scaled to the point that you're seriously considering performance. Sure, starting with rust can potentially save you time, money, and refactoring down the line but only after you've reached a point that few startups ever hit. Otherwise you're limiting yourself with slow development times (compared to, say, Python) and difficulty hiring for very little benefit. I'm sure this startup's founders love rust (and so do I), but ultimately you need to prioritize the company first and that probably means using the most popular, boring tech stack imaginable in the beginning. The more you deviate from that, the harder the early days will be. It's far too easy to be swayed by exciting tech and forget that all that really matters is that you solve someone's problem.
I've seen a pretty clear difference in success with less popular technologies based more on management philosophy and culture than the technologies themselves. Management seeing individual developers as fungible—"lack of fungibility in the engineering team can be a real liability"—is a massive red flag in this regard. I am not surprised to hear Rust didn't work out in an environment like that!
... but especially for a small team, having people able to cross-operate on adjacent pieces of the tech is vital. You can't just not develop if all your Rustaceans catch COVID at the same time.
So "there's a huge bifurcation between people who know this language and people who don't" is a good reason to pick another language. As with so many such techs, network effect can dominate other benefits.
> Management seeing individual developers as fungible—"lack of fungibility in the engineering team can be a real liability"—is a massive red flag in this regard
Yeah, the infamous tin soldier approach that's often used to excuse using worse but more entrenched languages.
While the author's anecdotal evidence is coherent, it's not enough to establish causation. Especially if the measure of productivity is feelings of sluggishness.
Rust or not, there's an argument to be made for statically typed languages improving productivity over the long run [0].
All development can feel sluggish depending on the work hours, estimates, business timelines, engineering skills, and the task at hand.
Programming languages are common targets because
- we use them so much
- there are so many
- and all developers, at some point, must choose to dedicate their time to one over the others.
Finally, productivity itself is only one performance characteristic. To focus only on that (without even a good definition of effect or measure) makes content precisely what the author claims to avoid; flame bait.
As usual, very sad to see how little C# is mentioned as an alternative, having very robust, easy to use and performant stack of standard and third-party libraries for building the exact scenario outlined in the article.
Especially that is has first-class support for gRPC, runs on every cloud/on-prem host you can think of and doesn't force you to go out of your way to get most performance out of your implementation. People should not be mentioning Java first as a GC/JIT-based language for cloud given how competitive C# stack is and how much more you get straight out of the box.
Java just has an incredibly long, deep, relationship with the open source/FOSS world that is going to take C# a lot of time to catch up with. Java's also consistently had a much better story with backwards/forwards compatibility and versioning.
I haven't used it in years, but I didn't find the anywhere near as full an ecosystem around C#, it's tooling, it's libraries, etc. It didn't help that there was a lot of confusion around what ran on which runtimes/versions.
I'm in the middle of a rewrite of my finance analytics library in Rust. I chose it for all the compelling reasons: speed, safety and a great package manager.
About 2 weeks in, I hit a blocker, where the most performance critical layer was running 30x slower than C#. It's two weeks since then, and I'm still blocked. Experienced programmers on the language Discord and Reddit have been stumped as well, and I get the impression this is what one should expect from an immature ecosystem, but also makes me fear that it will never actually catch on.
Point is, I think even the selling point of speed is inappropriate.
> I’ve worked in dozens of languages in my career, and with few exceptions most modern, procedural languages (C++, Go, Python, Java, etc.) all very similar in terms of their basic concepts. Each language has its differences but usually it’s a matter of learning a few key patterns that differ across languages and then one can be productive pretty quickly. With Rust, though, one needs to learn entirely new ideas
I'd argue C++ is not anywhere easier, if you are using its features or need to analyze the code that does. It won't be anywhere quick.
> I don’t know about anyone else, but at least for me, when I’m building a new feature I usually don’t have all the data types, APIs, and other fine details worked out up front. I’m often just farting out code trying to get some basic idea working and checking whether my assumptions about how things should work are more-or-less correct. Doing this in, say, Python is extremely easy, because you can play fast and loose with things like typing and not worry if certain code paths are broken while you rough out your idea. You can go back later and make it all tidy and fix all the type errors and write all the tests.
> In Rust, this kind of “draft coding” is very difficult, because the compiler can and will complain about every goddamn thing that does not pass type and lifetime checking — as it is explicitly designed to do. This makes perfect sense when you need to build your final, production-ready implementation, but absolutely sucks when you’re trying to cruft something together to test an idea or get a basic foundation in place. The unimplemented! macro is helpful to a point, but still requires that everything typechecks up and down the stack before you can even compile.
This rings so true for me. I could "mock up" entire apps using interfaces in Java, without having to actually write impl code. I could be sloppy as hell around the edges, but that didn't matter, because I could get the large design right without the compiler screaming.
In Rust, there is the chasm between no code and anything that works, feels so draggy.
I'd say the author brought a good point of why you should use Rust even for a CRUD app. (and yeah, I am a Rust fanatic and quite biased too). But hear me out.
> Over time, we grew the team considerably (increasing the engineering headcount by nearly 10x), and the size and complexity of the codebase grew considerably as well.
At this point, Rust is providing security and protection from technical debt. You have lots of new comers to the company/project and each one of them is adding or changing something. Developers being normal human beings have the tendency not to read documentation, old code or discuss with 100 engineers before building something.
Rust forces that on them, to a certain degree. Sure, you can move faster without Rust for now; but you'll pay the price later on. I am working on a company where we are doing microservices both in Rust and TypeScript. It's faster to get the job done in TypeScript; however, the cost is the maintenance later. The TS microservices breaks easily, regress much faster when someone modifies them, and are prone to invisible bugs. Rust is more solid in that front.
But in a world where speed of delivery and delivery itself (just deliver and deal with it later), Rust will definitively not shine. This is kicking the problem down to somebody else.
Another point: Because of that, Rust libraries are usually pretty solid. Comparing to the untangled mess in NPM, Rust will break down much less frequently.
Sweet, well the large feature we just spent 9 months building at a company that has yet to turn a profit is not anything that anyone wants to use so we’re throwing your beautiful porcelain dollhouse down the basement stairs and building something else.
> Sure, you can move faster without Rust for now; but you'll pay the price later on.
The flip side argument for an early stage company is that if they can’t move fast they may not survive. Not having tech debt is great, but it’s better to have tech debt and be alive than no tech debt and out of business.
To be clear, I’m not personally taking a hardline position on either side here. I think these kinds of choices are always a balancing act. Moving too fast can kill your business just as effectively as moving too slow: it’s just as hard to ship changes to a permanently on fire ball of spaghetti as it is a pristinely typed piece of clockwork, and sometimes harder.
> What really bites is when you need to change the type signature of a load-bearing > interface and find yourself spending hours changing every place where the type is > used only to see if your initial stab at something is feasible
Editor/IDE should be able to do this in a few seconds.
> With Rust, though, one needs to learn entirely new ideas — things like lifetimes, ownership, and the borrow checker.
Those three things are actually just different facets of the same thing: ownership. The bad news is that you must learn Rust's ownership model to use Rust idiomatically. The good news is that you can do a lot without learning Rust ownership model at all. Just clone all your values. Not advisable for production code, but great for getting over the ownership model hump.
And once you've learnt those things and got some experience writing real world software in Rust, you may well find yourself more productive in Rust than, say Ruby on Rails.
Context matters a lot, and you shouldn't be making tech choices based on the way the wind is blowing ("tech radars", what's hot in the blogosphere, etc.). If hiring teams to work on your mostly-CRUD app easily is a high priority, then Rust probably isn't a good choice. If you have a team that already knows Rust, and you need to add some web app / service, then Rust is a perfectly fine choice, on the grounds that support for web stuff is "good enough" now, and the best tool for the job is often the one you already know well and are already supporting.
If I'm building stuff for _myself_ and it's getting too fiddly for a bash script, then I'll always default to Rust just because _personally_ I'm way more productive in it than anything else.
I guess nodejs might also be throw into the party, as it is anyway needed for many SPA frameworks, and for better or worse, Go, given its relevance on DevOps space.
If it's complex business logic and will grow bigger: Kotlin + Micronaut/Spring Boot + Krush/Hibernate
If it's quite simple and has a clear outlined border: Go + Gin
"Rust has made the decision that safety is more important than developer productivity. This is the right tradeoff to make in many situations — like building code in an OS kernel, or for memory-constrained embedded systems — but I don’t think it’s the right tradeoff in all cases, especially not in startups where velocity is crucial"
This doesn't match my experience. It took some time to get up to speed, but at this point it's much faster for me to write something in Rust than in other languages that I'm proficient in that are ostensibly faster to develop in (e.g., JavaScript).
Part of this depends on one's bar for quality. In Node.js I could write `JSON.parse(input).foo.bar` really quickly. In Rust, I'd probably write two struct definitions with `#[serde(Deserialize)]` first, then a similar line. It'd take 45 seconds longer, but when I'm done, the Rust program validates the input and prints decent error messages.
I don't really agree with that framing. Most of the languages people use to write web apps are safe! The actual tradeoff rust is making is that performance is more important than developer productivity. It's not willing to sacrifice safety for productivity, but fundamentally the reason to use rust is that it's fast.
If you don't need performance, you might be better off using any number of safe, GC languages. (That said, I actually find the ergonomics of Rust nicer than most other languages. A rust-like language with a GC would be very nice for web backends imo.)
The problem is that, while the benefits of trading safety vs. velocity go to the company, the costs go to the user, as it is the user whose data or identity will be stolen. And this goes well beyond Rust and "mere" memory safety: this extends to every kind of taking things slow and being careful in your coding rather than just throwing something together and later finding out you've made a serious error. This is why we need regulation: startups that take the time or put in the effort to play it safe hate at a disadvantage to ones that, frankly, "don't give a shit", and so the world remains an insecure mess. (I do think the calculus works out differently for large companies that are operating at a fundamentally different economy of scale--and so I do feel like colonies the like of Google or Apple are willing to take things a bit more slowly to ensure a more reasonable result, even though they sometimes do fail--but I almost feel that makes the problem worse, not better :/.)
> but I don’t think it’s the right tradeoff in all cases, especially not in startups where velocity is crucial
This could be true for C++, Java or maybe C#. Against them, python/ruby run circles.
But Rust change the equation.
Is super-productive... BUT what is important to note is that you need developers that have done the initial climb and go fully rust with it.
After this, things start to click neatly:
- Modeling code is easy & fast
- Composing code, flow!
- Testing (all of it, including benchmarking and integration) flow.
- Refactoring (big!) is super-easy. This one is where the "velocity" is actually need.
But you CAN'T "code fast". You CAN'T skip in good practiques "let's ignore the use of clippy, Result, proper use of traits (like Into/From), etc". (and even write documentation with including doc-test!)
This is where the "I write code FAASSST bro!, not time for pesky good practiques!" get hurt with Rust.
You need to buy the whole package, because Rust is MADE to be used fully in harmony.
And when you finally do it. IS FAST TO CODE.
And even FASTER to refactor.
And probably so minimal post-fixes.
---
P.D: Major blow against Rust? Slow compiling. This is the one factor that blow the dream and where you truly need a decent machine and flow to make it nice. However, if you take the above advice, you are already with Test/DocTest/Clippy/Check flow and that part can be done to be efficient.
The lack of compilation time in Python is a false economy when you consider the cost of tacking on the type checker and the developer time spent wondering whether the type that's been annotated is accurate. Static typing is good for developer velocity.
This really depends on your problem domain. Rust productivity is vastly higher than C++ due to its helpful compiler error message, package manager, integrated tests and bench facility, and language features like algebraic datatypes and a whole lot more. This also hasn't counted the reduced debug time later, which would be a significant time spent by devs in C++. In areas that don't value performance and correctness, or requirements vary a lot faster like a web app, you will spend time trying to get something correct which you may throw away pretty fast later, which will not be very productive. Thus I think it has less to do with startup picking Rust, but more of whether teams have picked right tool for their domain.
That's not actually the tradeoff in my experience.
If you're willing to blindly follow the suggestions given you by the compiler about references, and clone() things when it doesn't seem to work, you'll be just as productive as a Python/Java ... programmer. You'll just not be as memory efficient as a Rust programmer who actually groks that stuff. That's the tradeoff: coder productivity versus memory efficiency.
Just once I wish I could force a Rust person to use either Ada, or even an Oberon-2 derivative that spits out C code and which compiles in a flash. Then compare the experience...
Speaking as a "Rust person" do you have any code samples or projects I could take a look at to compare? I've always heard good things about Ada but haven't tried it personally.
Are there languages that copy Rust's type system and compiler ergonomics without the memory safety?
I feel like 90% of my struggles with Rust in the real world have to do with the borrow checker. The two pieces don't feel related enough to me that they need to be interlinked.
I am building modelbox right now - https://github.com/tensorland/modelbox I began building this in Rust while also learning the language. It became quickly very complex as I started introducing streams in async traits. I think in a few years things will get a lot better as more people use Rust for building web services, but I had to go back to Go to be more productive and ship this thing out. I loved how the compiler was forcing me to think harder about life times and such.
I personally have a startup and what I think works well is use TypeScript for almost everything, but Rust for anything that has to be fast and/or needs more code safety due to complexity.
I hope more people looking into statically typed languages like Rust also take a look at Nim, as it seems to be striking a good balance between performance and developer productivity.
,,Over time, we grew the team considerably (increasing the engineering headcount by nearly 10x), and the size and complexity of the codebase grew considerably as well.''
This sounds just like all other projects that don't keep the code professional.
The author complains a lot about the quality of the Rust libraries and documentation, but I bet that their code base and documentation and especially testing is worse.
Still, I agree that Rust is not ready for a startup where the requirements change often.
> As mentioned above, the service we were building was a fairly straightforward CRUD app. The expected load on this service was going to be on the order no more than a few queries per second, max, through the lifetime of this particular system.
Naturally, there is a reason people opt for higher level languages like Ruby/Python or at least Go or Java/Kotlin to write apps like this.
I really, really, really, don't understand why people want to use Rust for CRUD/web stuff. Every GC language is better than Rust for CRUD/web when you are in the less than 10,000 users phase.
I understand why Rust is trying to shove its way into the CRUD/web space--that's where all the programming is. I just don't understand the converse.
I cast glances at it every time my company's Python services break because of a runtime error that could have been caught with a better type system, or because they ran out of memory and need bigger boxes, or another developer has to spend a week debugging their environment to get the complex web of dependencies aligned for five minutes, or my laptop strains under the weight of a dozen docker containers attempting to shield all those system-level dependencies from each other, or a deployment fails because of bad tooling/dependency-management
Not all languages are as bad as Python, and Rust comes with a lot of other costs. But it's very seductive to think about a world where you build a static binary with a single command, the build always works no matter what system it's on, the binary always works on the target OS regardless of what else is or isn't installed, it will use 1/10 the memory, and most likely it will never have any runtime errors because you were made to handle them all already
(I realize Go has at least some of these benefits, but its type system is hard for me to stomach)
I've written a few backend APIs with rust and I have to disagree. Not only have the frameworks managed to get the ergonomics similar to your popular GC lang[0][1], the natural lack of shared mutable state of HTTP handlers means you very rarely have to encounter lifetimes and a lot of the language's advanced features. What's more, now when I go back to work with other languages, I can't help but notice the significant number of unit tests I'd not have had to write in Rust. It doesn't have a Rails and Django but it's an easy pick over anything at the language level.
A note on performance, Rust's the only langauge where I haven't had the need to update my unit test harnesses to `TRUNCATE` tables instead of creating/discarding a separate database per test on PostgresSQL.
I'll also like to mention the gem that is SQLx[1]. As someone who's never been satisfied with ORMs, type checked SQL queries that auto-populate your custom types is revolutionary. With the error-prone langauge-SQL boundary covered, I was surprised just how good it can get making use of the builtin PostgreSQL features. Almost to the point that amount of effort the community's put to building great tools like Prisma.js and <insert favorite ORM> feel like a fool's errand (at least so for PosgreSQL).
Rust does have some nice semantics that the last round of popular languages don't, mostly just due to age. I suspect that a decent amount of its popularity is owed to that. But obviously for something CRUDesq all the nice little affordances in the world can't prevent borrowing from putting it way behind any language with a mature framework. That indicates we could use a GC language with Rust's eye towards modern design but without Rust's more difficult bits. Though I haven't really tried Typescript- does it do anything like that?
I feel that this is a click bait to attract employees. The writer links to his startup on his profile (which Medium shows right next to the article), where you can see that he's looking for founding engineers. Rust has been a trending topic lately, which attracts relatively experienced engineers. He mentions that he made these experiences more than 2 years ago, so it's notable that he waited so long to write about it. The slightly noisy "ex-google" and "ex-apple" mentions sound like advertisement.
And, well, the usual, "learning curve" and some largely hypothetical concerns about hiring. I developed a complex app with Rust with very high time pressure and with developers that didn't have any previous Rust experience (I didn't have much of it myself), it was risky but it worked out well, so I know first hand that it's possible. And we are not "ex-google"!
OT, but I thought it was neat how all the splash images were just casually generated by dall-e and the author didn't feel the need to mention it because it's just normal now
(Not /s, I genuinely think it's cool things are like this now)
Languages like Python can go a long way for a startup and is my first choice. Rewrite in Rust when it's clear that the API is stable and performance starts to matter.
Exactly. Iterating on an idea is much easier to do in Python, because you can just use lists, dictionaries and sets to solve most problems. Python's string manipulation is also a lot easier than Rust, because you don't have to think about allocations. Once you have figured out what works, you can start defining your Rust structs and enums to build up a reliable code base.
Over the past 2 years I've been writing Rust services for my own startup. Some were straightforward CRUD, some advanced language parsing and ML services. Some thoughts:
- Rust tends to push you to make good decisions. In my case, one of these good decisions was to ditch an ORM (which has always slowed me down) and instead write Postgres queries directly via SQLx. The compile time checks against an actual DB helped my speed dramatically
- Free performance can be a really big help when you are trying to figure out an API or algorithm. It's really helpful to know that my unoptimized code won't tank the server, and also helps me save costs on the cloud.
- "It doesn't compile, or it doesn't break" is kinda a mantra for Rust, and really helps me focus on problems at hand, instead of hunting down bugs.
> You will have a hard time hiring Rust developers.
I've found that there is a drastic difference between hiring devs willing to learn Rust, and devs that want to work with you because you are using Rust. The bar of those devs that seek out a Rust position tends to be very high.
> We made a huge mistake early on by adopting Actix as the web framework for our service...(To be fair, this was a few years ago and maybe things have improved by now.)
Actix-web has gone through some version-churn, but it's never been "buggy" in my experience. The experience multiple years ago is vastly different than today, but even my older services written years ago with Actix-web are still running fine.
> Libraries and documentation are immature.
Perhaps in years past, but I've always found the docs for Rust and its libraries to be very good. Folks write entire books on elements of Rust, and the standardization of the display of crate docs keeps things consistent.
> Rust makes roughing out new features very hard.
The "json!" macro can come in handy here. Also Github Copilot is a godsend for this.
> What really bites is when you need to change the type signature of a load-bearing interface and find yourself spending hours changing every place where the type is used only to see if your initial stab at something is feasible. And then redoing all of that work when you realize you need to change it again.
Hours? These type of corrections are spoonfed to you via errors at compile, or via the IDE. I've never had to spend hours on this. Everyone of these changes could be a bug, and having a typesafe language is a huge help here.
I recognize I might be in the minority, but I've really enjoyed using Rust for services for my startup. It's helped me move fast, but maybe I'm a special case. I'm curious to hear other's experiences.
Not special. I couldn’t have said it better myself.
I often reach for Rust when Python could do, but it’s a bit bigger than a one page of code program. I also forget I’ve been doing Rust nearly full time since late 2015. And before that 15 years of C and understanding memory, etc. Maybe we’re just a rare breed.
Jokes aside. This is a thoughtful and interesting article. I was wavering on going down the Rust path for my SaaS start-up. Glad I didn't in the end for exactly the same kind of reasons.
Rule number one at startups: write things that don’t scale and use mature, boring frameworks/languages.
The goal is to deliver products and iterate as fast as possible. Productivity is key to success.
IF (and it is a big IF) your startup ever gets to the point of having to scale up (nice problem to have) then
just throw money at AWS, hire senior engineers and let them figured it out.
What matters is customer experience; nobody cares of what’s behind the scene.
Some comments were deferred for faster rendering.
satvikpendem|3 years ago
I will also push back on other commentors here saying Rust is not good for web apps and APIs, and I have found that to be the opposite of true. I read Zero To Production In Rust [0] (a great book by the way, all about creating a web API with actix-web and Postgres) and deployed an API that has not gone down a single time since deploying near the beginning of this year. It's as ergonomic as (and sometimes even more so than) any NodeJS or Go API I've made (as even though Rust doesn't have function overloading, actix-web and others have some macro magic they do behind the scenes to make it appear as if it does), and there were very few times I had to contend with the borrow checker. If there had been and if I were really going for speed, I would also have cloned everywhere that was needed.
When I write something in Rust and it compiles, I can depend on it to work, and to continue working. At the end of the day, use the tool that makes sense for your business, but I don't think Rust was necessarily a bad choice based on my personal experience with it.
[0] https://www.zero2prod.com/
candiddevmike|3 years ago
futureproofd|3 years ago
p4ul|3 years ago
iroddis|3 years ago
I’ve worked my way through a couple of rust books, but this was the first one that actually talked not just about the language, but the entire development flow. Git workflows, CI/CD, docker, comprehensive testing.
Even after clearing the initial rust fundamentals, there are so many standard libraries like anyhow, chrono, serde, thiserror, and tokio that are almost required knowledge, but aren’t covered in most books.
Thank you for sharing your discovery!
saghm|3 years ago
Not that this takes away from your point, but does Go have function overloading? I had assumed it hadn't given the discussions I had heard about what it would take to retrofit `Context` parameters on everything when they added that type, but I guess maybe this could be one of those "functions can but methods can't" things (which I think I heard is how they do generics as well?)
kazinator|3 years ago
That's going to get tiresome after about half a day.
Exceptions or GTFO.
pclmulqdq|3 years ago
Personally, I actually think it's a worse fit for things like kernel/embedded development than for web backends. The ergonomics of Rust are so Javascript-y that the web is natural, and other environments where C is used are a lot messier and trickier.
EugeneOZ|3 years ago
There were just a couple of failures in the first 2 months.
dmix|3 years ago
How often does the codebase change? How many people work on it?
3a2d29|3 years ago
Its dumb when the C++ community refuses rust when it guarantees memory safety, so why would you bring in a language you prefer to an area that doesn't need it if it introduces that issue?
If you like Result<> or concurrency, use a GC language with those things. Go may not have them, but your choice isn't just Go.
kelnos|3 years ago
This is really the main reason not to use Rust when you need to move fast: if you don't know the language yet, it will take you time to learn it. But that's true of any language. You probably shouldn't do your startup in Java, either, if your team isn't familiar with it.
Yes, Rust's learning curve is steeper than many other languages, but still... if you're an early-stage startup and you need to move fast, write in a language that you and your team already knows.
ajross|3 years ago
Java is wildly easier to pick up than Rust, though. Hordes of productive enterprise java programmers are employed today who frankly don't even understand what memory safety even means, much less the tradeoffs their language runtime (or software) needs to make to ensure it.
It's certainly a truism that you should tailor your development environment to the talents of your staff, but that doesn't mean that all tools are equally applicable. Would you do a startup today using APL or COBOL?
roxgib|3 years ago
unknown|3 years ago
[deleted]
brink|3 years ago
As an experienced Rust dev, I had the opposite problem. I looked for a good Rust job, but couldn't find one. Took an Elixir job instead.
I also don't get the complaint about lack of productivity. I've worked in a dozen languages, and Rust is still the most productive language for me by far. I feel like they're speaking from inexperience here. I'm slow whenever I start a new language too, and Rust was no exception. Keep at it, however, and it'll pay off in the long run.
dmix|3 years ago
Did you work on it with a team in a serious production environment?
Sounds like you struggled to find a Rust job, so I'm not sure how you can know that without really betting on it like these guys did.
mudrockbestgirl|3 years ago
I think this should be at the top of the post. Rust seems like an obvious bad choice for this. For something not performance-sensitive that doesn't require most of Rust's power just use languages/frameworks that are made for this kind of thing. Of course you can do this with Rust, but you're probably picking the wrong tool for the job. The Rust ecosystem around building typical webservices isn't nearly as good as it is for other languages, and the benefit you get from Rust's safety and performance is worth less than the iteration speed you gain from the standard Node/Python/etc approach.
dmix|3 years ago
A CRUD/SaaS web team should only be using it for high performance areas with a few microservices. At least until the web side of Rust significantly matures (mostly in the people/community side not just code).
ekidd|3 years ago
But I've used Rust mostly for performance-critical CLI tools, or highly specialized servers. Typically, these have a narrowly defined job that must be done reliably and efficiently. Rust shines at this. These tools run reliably with almost no changes, often for years at a time.
But I have learned that it's often less useful putting policy and frequently-changed business logic in Rust. That kind of code is often accessible to more developers in a strongly-typed scripting language.
nequo|3 years ago
I assume that you’re thinking of TypeScript or Python with type hints.
Do you mean that these languages are more accessible because they are more widely known by developers or because codebases in these languages are easier for some reason to change frequently than codebases in Rust?
insanitybit|3 years ago
I just haven't found it to be the case that developers have a very hard time learning it, but we haven't grown to the point where that would maybe be the case. We also lean heavily into microservices so "oh there's no library in Rust but there's one in Python" is low cost, we can just write a service in Python.
pclmulqdq|3 years ago
By contrast, using Rust makes it easy to force a readable coding style on yourself and others.
ravi-delia|3 years ago
But the article pretty clearly outlined a super simple CRUD app. These days that's a problem space so well defined you can practically specify the whole thing in command line flags. Rust really has little to add there. For other stuff, yeah Rust can be super cool.
creata|3 years ago
Can you expand on this, please?
lemmox|3 years ago
It's remarkable how significantly the first few months of a project impact the first few years of a company. How quickly casual & spontaneous decisions, largely based on convenience and familiarity, ossify into legacy drag.
ahungry|3 years ago
- C/C++ developers like it as an alternative for low level languages
- Functional programmers like it because of it's functional features
- "Cargo Culters" / "Hot Language" / "Flavor of the Month" followers like it, as it's in vogue at the moment (this is the crowd that has likely shifted from various web/API scripting languages over the last decade - (php|ruby|python) -> nodejs -> rust)
However, as the article alludes to, for the third crowd, Rust is just likely not a great fit (even if it has a lot of neat features and introduces some great concepts others may not stumble on of their own accord) when your implementation doesn't do much beyond web dev/API/scripting purposes.
drogus|3 years ago
Casperin|3 years ago
While Rust isn't simple, I don't know any other languages that fill this space.
KingLancelot|3 years ago
[deleted]
errantmind|3 years ago
With a competent teacher, experienced devs should be able to pick up on the memory model pretty quickly, and that is really the only initial blocker to productivity. After that a dev can essentially write procedural code if they want, like other common languages, while refining their thinking and practices towards idiomatic Rust.
almost_usual|3 years ago
https://rust-unofficial.github.io/too-many-lists/
singularity2001|3 years ago
williamcotton|3 years ago
The wasted clock cycles and developer hours more than makes up for the slow down in productivity rates we’ve seen across advanced economies lately!
candiddevmike|3 years ago
bbkane|3 years ago
roryokane|3 years ago
Ur/Web: http://impredicative.com/ur/
Dark (Darklang): https://darklang.com/
nephanth|3 years ago
kika|3 years ago
jcmontx|3 years ago
mike_hearn|3 years ago
But here's something to really chew on. Do we need the HTTP server at all?
Consider: why exactly do we need so much middleware plumbing for ordinary database driven web apps? A lot of this is to do with a winding evolutionary path rather than what you'd design with a clean slate.
Something I've been experimenting with lately is writing apps that connect directly to an RDBMS using its native protocol, over the internet, from a desktop app. Obvs the next step after is to try the same with a mobile app. Historically we've relied on web browsers and written translation layers for a few different reasons, but tech has been improving over time and some of those reasons are becoming obsolete:
1. Free relational databases were really rough back then and the commercial DBs often had weird limitations around distributing DB drivers. These days it's easier and postgres is a lot better.
2. You needed to slather lots of caches and other stuff in front of the RDBMS if you had high traffic. Modern DBs are a lot better at materialized views, cached query plans, read replicas etc. Postgres has a variety of load balancers that can sit in front of it and work around its per-connection overhead.
3. Security wasn't good enough. Nowadays you have features like row level security, security-definer views etc in the free DBs.
4. People translate everything to HTML/HTTP partly because it was too hard to distribute and update apps to Windows desktops/laptops in the 2000s, due to MS just generally losing the ability to execute and being distracted by stuff like Longhorn/WinFS. Browsers solved the basics of caching and refreshing of code for you. Now there's https://conveyor.hydraulic.dev/ which makes distributing desktop apps way easier. It's a lot more feasible now to just knock out a quick desktop app and upload to an S3 bucket, with built in online updates. Also the next release will support force-update-on-start, so you can get a web like experience where the user is always up to date so the schemas and client can be evolved in parallel.
If you could just write your UI using a 'real' UI toolkit and invoke directly to the DB from the UI code, you wouldn't need a lot of the microservices plumbing anymore, you wouldn't need to serialize stuff to JSON or HTML. You could just use the underlying DB protocol as an RPC layer and let the DB enforce business logic. It can be done for common kinds of enterprise apps today: there are only a few problems to solve, none of them especially hard. For instance a little service that turned OAuth SSO into client side certificates would make it easy to connect to a DB without needing to manage usernames or passwords. A tunnelling solution to get through awkward firewalls would also be useful (websockets etc).
For consumer apps there's more complexity. You wouldn't try to implement twitter that way for instance. But still, for the kind of SaaS-y thing that the article is about it could have saved a lot of complexity and improved iteration speed.
pjmlp|3 years ago
paulddraper|3 years ago
> This project was a cloud-based SaaS product that is, more-or-less, a conventional CRUD app: it is a set of microservices that provide a REST and gRPC API endpoint in front of a database, as well as some other back-end microservices
Of course.
Use Java/Kotlin or Node.js/Typescript or Go or Python for your basic web services.
Easy test: Would you at least seriously consider using C/C++ for it? Only then should you use Rust.
arcticbull|3 years ago
I'm a Rust-stan for sure, but I probably wouldn't use it for this task either as it'll be hard to find other people who know how to use it - and also for this task. Here's hoping that changes, though.
[edit] I might also add it's not a good fit for making these types of endpoints at a startup as the goal of a startup isn't really to write perfect/correct/safe code, but rather to ship a product as fast as you can so you can iterate on the product-market fit. Quick and dirty in another language is probably a better fit for the business case. Rewrite it later.
3a2d29|3 years ago
This is a great point. I understand liking a language, but don't bring Rust into a GC space (in industry, personal projects can be what you like!) You can find a GC language with all the features of rust you like.
ufmace|3 years ago
Ruby on Rails certainly isn't perfect, but it's a highly battle-tested web framework. It's been so widely used for so long that you can have high confidence that you won't run into any bugs that will require digging into the guts of it. You can write code against it and be highly confident that any bugs or misbehaviors are in your code, with difficulty of finding and fixing dependent only on how good the code you've written is.
With Rust, I don't think that's the case. The DB and web server related libs just don't seem to have that much manpower behind them, and haven't had big complex services built on them in production for years. If you want to do anything mildly complex, there's a good chance you'll have to dig into the guts of these to figure out what's really happening or to resolve some weird bug or add a feature. That'll require a lot of skill, even if the code you're actually writing is mostly straightforward.
lamontcg|3 years ago
If you've ever generated some object out of some factory and then tossed it on a list of things and then gone back to generate a new object out of the factory and found that the first object you put on the list got scribbled over because you forgot to clone it, then that's a category of bugs that rust entirely prevents.
And I thought I was pretty good about reasoning about data ownership in other languages, but the borrow checker is teaching me how to be a lot more careful.
nlitened|3 years ago
fooker|3 years ago
I have been doing compiler development in C++ for about 10 years, lisp before that and a bit of python more recently.
We could not figure out how to be productive in Rust after starting a greenfield project and sticking to it for a month.
Luckily this was not a project which requires incremental updates, we were on the verge of rewriting it in C++.
virtualritz|3 years ago
It took me almost a year to be as productive (and my code as canonical) in Rust as I was after over two decades of C++.
After a month of Rust I was still fighting the borrow checker and grokking basic concepts of the language. So no surprise in what you wrote.
However, after that year I am probably a factor of two to ten more productive in Rust.
The speedup is about two for everyday code (if it compiles it runs and doesn't crash). Ten (or more) when I need to bring in a dependency.
To qualify the latter: if a crate with same functionality or a Rust wrapper for a C/C++ lib exists, the factor can be much, much higher than ten since it is just adding a line to Cargo.toml.
If the dependency is a C/C++ lib it is as slow as using it from C++. It needs to be integrated with the build and that takes about the same time plus writing/generating a wrapper.
All that said: I had to write code in C++ the other day again. It almost felt painful after three years of only Rust.
pjmlp|3 years ago
Why?
Those ecosystems are built alongside C++ tooling, so no need to add an extra layer of indirection.
I already have the safety from those ecosytems, if I am reaching out to C++ is exactly because I need to do some unsafe stuff, or binding libraries that are anyway written in C++.
karmakurtisaani|3 years ago
UltraViolence|3 years ago
I'm not sure if I agree with this. In fact, I'm pretty sure that I don't. These "occasional" nuisances become big blockers after a while and not only decrease productivity but hurt customer goodwill as well when they're not discovered in time.
63|3 years ago
WirelessGigabit|3 years ago
I feel that it is actually harder to write bad code in Rust than it is in say, Python.
synergy20|3 years ago
tikhonj|3 years ago
shadowgovt|3 years ago
So "there's a huge bifurcation between people who know this language and people who don't" is a good reason to pick another language. As with so many such techs, network effect can dominate other benefits.
shmerl|3 years ago
Yeah, the infamous tin soldier approach that's often used to excuse using worse but more entrenched languages.
tsthename|3 years ago
Rust or not, there's an argument to be made for statically typed languages improving productivity over the long run [0].
All development can feel sluggish depending on the work hours, estimates, business timelines, engineering skills, and the task at hand.
Programming languages are common targets because - we use them so much - there are so many - and all developers, at some point, must choose to dedicate their time to one over the others.
Finally, productivity itself is only one performance characteristic. To focus only on that (without even a good definition of effect or measure) makes content precisely what the author claims to avoid; flame bait.
[0] - https://www.researchgate.net/publication/338162224_A_Study_o...
neonsunset|3 years ago
Especially that is has first-class support for gRPC, runs on every cloud/on-prem host you can think of and doesn't force you to go out of your way to get most performance out of your implementation. People should not be mentioning Java first as a GC/JIT-based language for cloud given how competitive C# stack is and how much more you get straight out of the box.
kjeetgill|3 years ago
I haven't used it in years, but I didn't find the anywhere near as full an ecosystem around C#, it's tooling, it's libraries, etc. It didn't help that there was a lot of confusion around what ran on which runtimes/versions.
Perhaps it's changed since then.
metaltyphoon|3 years ago
kolbe|3 years ago
About 2 weeks in, I hit a blocker, where the most performance critical layer was running 30x slower than C#. It's two weeks since then, and I'm still blocked. Experienced programmers on the language Discord and Reddit have been stumped as well, and I get the impression this is what one should expect from an immature ecosystem, but also makes me fear that it will never actually catch on.
Point is, I think even the selling point of speed is inappropriate.
Cyph0n|3 years ago
As for Rust’s performance, it has been proven time and again to approach that of C and C++. One counterexample does not disprove that.
dlivingston|3 years ago
shmerl|3 years ago
I'd argue C++ is not anywhere easier, if you are using its features or need to analyze the code that does. It won't be anywhere quick.
SliderUp|3 years ago
> I don’t know about anyone else, but at least for me, when I’m building a new feature I usually don’t have all the data types, APIs, and other fine details worked out up front. I’m often just farting out code trying to get some basic idea working and checking whether my assumptions about how things should work are more-or-less correct. Doing this in, say, Python is extremely easy, because you can play fast and loose with things like typing and not worry if certain code paths are broken while you rough out your idea. You can go back later and make it all tidy and fix all the type errors and write all the tests.
> In Rust, this kind of “draft coding” is very difficult, because the compiler can and will complain about every goddamn thing that does not pass type and lifetime checking — as it is explicitly designed to do. This makes perfect sense when you need to build your final, production-ready implementation, but absolutely sucks when you’re trying to cruft something together to test an idea or get a basic foundation in place. The unimplemented! macro is helpful to a point, but still requires that everything typechecks up and down the stack before you can even compile.
This rings so true for me. I could "mock up" entire apps using interfaces in Java, without having to actually write impl code. I could be sloppy as hell around the edges, but that didn't matter, because I could get the large design right without the compiler screaming.
In Rust, there is the chasm between no code and anything that works, feels so draggy.
csomar|3 years ago
> Over time, we grew the team considerably (increasing the engineering headcount by nearly 10x), and the size and complexity of the codebase grew considerably as well.
At this point, Rust is providing security and protection from technical debt. You have lots of new comers to the company/project and each one of them is adding or changing something. Developers being normal human beings have the tendency not to read documentation, old code or discuss with 100 engineers before building something.
Rust forces that on them, to a certain degree. Sure, you can move faster without Rust for now; but you'll pay the price later on. I am working on a company where we are doing microservices both in Rust and TypeScript. It's faster to get the job done in TypeScript; however, the cost is the maintenance later. The TS microservices breaks easily, regress much faster when someone modifies them, and are prone to invisible bugs. Rust is more solid in that front.
But in a world where speed of delivery and delivery itself (just deliver and deal with it later), Rust will definitively not shine. This is kicking the problem down to somebody else.
Another point: Because of that, Rust libraries are usually pretty solid. Comparing to the untangled mess in NPM, Rust will break down much less frequently.
warent|3 years ago
The last thing on my mind when commercializing something is future technical debt.
williamcotton|3 years ago
wfleming|3 years ago
The flip side argument for an early stage company is that if they can’t move fast they may not survive. Not having tech debt is great, but it’s better to have tech debt and be alive than no tech debt and out of business.
To be clear, I’m not personally taking a hardline position on either side here. I think these kinds of choices are always a balancing act. Moving too fast can kill your business just as effectively as moving too slow: it’s just as hard to ship changes to a permanently on fire ball of spaghetti as it is a pristinely typed piece of clockwork, and sometimes harder.
bakul|3 years ago
True for most startups.
Throwaway23459|3 years ago
Editor/IDE should be able to do this in a few seconds.
SevenNation|3 years ago
Those three things are actually just different facets of the same thing: ownership. The bad news is that you must learn Rust's ownership model to use Rust idiomatically. The good news is that you can do a lot without learning Rust ownership model at all. Just clone all your values. Not advisable for production code, but great for getting over the ownership model hump.
jeffparsons|3 years ago
Context matters a lot, and you shouldn't be making tech choices based on the way the wind is blowing ("tech radars", what's hot in the blogosphere, etc.). If hiring teams to work on your mostly-CRUD app easily is a high priority, then Rust probably isn't a good choice. If you have a team that already knows Rust, and you need to add some web app / service, then Rust is a perfectly fine choice, on the grounds that support for web stuff is "good enough" now, and the best tool for the job is often the one you already know well and are already supporting.
If I'm building stuff for _myself_ and it's getting too fiddly for a bash script, then I'll always default to Rust just because _personally_ I'm way more productive in it than anything else.
Context, context, context.
charcircuit|3 years ago
zozbot234|3 years ago
If your alternative is Python or Ruby, then cloning your values is perfectly OK for production code. It will still run very fast.
andrewmutz|3 years ago
I would love to hear what tech stack (or stacks) the HN community thinks currently allows a small team to move fastest for this type of product.
pjmlp|3 years ago
I guess nodejs might also be throw into the party, as it is anyway needed for many SPA frameworks, and for better or worse, Go, given its relevance on DevOps space.
jcmontx|3 years ago
Second tier, a bit higher performance, yet somewhat less productive: ASP.NET Core; Spring Boot; Node/Express/Nest; maybe Go
cryo28|3 years ago
hu3|3 years ago
- Laravel
- Rails
- Next.Js or similar
- Python
- C#/Kotlin/Go
PKop|3 years ago
RamblingCTO|3 years ago
Add login and auth and stuff via ory/keycloak
williamcotton|3 years ago
unknown|3 years ago
[deleted]
mindcrime|3 years ago
yupis|3 years ago
Great point
dap|3 years ago
Part of this depends on one's bar for quality. In Node.js I could write `JSON.parse(input).foo.bar` really quickly. In Rust, I'd probably write two struct definitions with `#[serde(Deserialize)]` first, then a similar line. It'd take 45 seconds longer, but when I'm done, the Rust program validates the input and prints decent error messages.
necubi|3 years ago
If you don't need performance, you might be better off using any number of safe, GC languages. (That said, I actually find the ergonomics of Rust nicer than most other languages. A rust-like language with a GC would be very nice for web backends imo.)
saurik|3 years ago
mamcx|3 years ago
This could be true for C++, Java or maybe C#. Against them, python/ruby run circles.
But Rust change the equation.
Is super-productive... BUT what is important to note is that you need developers that have done the initial climb and go fully rust with it.
After this, things start to click neatly:
- Modeling code is easy & fast
- Composing code, flow!
- Testing (all of it, including benchmarking and integration) flow.
- Refactoring (big!) is super-easy. This one is where the "velocity" is actually need.
But you CAN'T "code fast". You CAN'T skip in good practiques "let's ignore the use of clippy, Result, proper use of traits (like Into/From), etc". (and even write documentation with including doc-test!)
This is where the "I write code FAASSST bro!, not time for pesky good practiques!" get hurt with Rust.
You need to buy the whole package, because Rust is MADE to be used fully in harmony.
And when you finally do it. IS FAST TO CODE.
And even FASTER to refactor.
And probably so minimal post-fixes.
---
P.D: Major blow against Rust? Slow compiling. This is the one factor that blow the dream and where you truly need a decent machine and flow to make it nice. However, if you take the above advice, you are already with Test/DocTest/Clippy/Check flow and that part can be done to be efficient.
polio|3 years ago
WiSaGaN|3 years ago
ocschwar|3 years ago
If you're willing to blindly follow the suggestions given you by the compiler about references, and clone() things when it doesn't seem to work, you'll be just as productive as a Python/Java ... programmer. You'll just not be as memory efficient as a Rust programmer who actually groks that stuff. That's the tradeoff: coder productivity versus memory efficiency.
shrubble|3 years ago
steveklabnik|3 years ago
bschwindHN|3 years ago
Dhghomon-|3 years ago
rsr|3 years ago
I feel like 90% of my struggles with Rust in the real world have to do with the borrow checker. The two pieces don't feel related enough to me that they need to be interlinked.
diptanu|3 years ago
xyzzy4747|3 years ago
plainOldText|3 years ago
xiphias2|3 years ago
This sounds just like all other projects that don't keep the code professional.
The author complains a lot about the quality of the Rust libraries and documentation, but I bet that their code base and documentation and especially testing is worse.
Still, I agree that Rust is not ready for a startup where the requirements change often.
hvis|3 years ago
Naturally, there is a reason people opt for higher level languages like Ruby/Python or at least Go or Java/Kotlin to write apps like this.
bsder|3 years ago
I understand why Rust is trying to shove its way into the CRUD/web space--that's where all the programming is. I just don't understand the converse.
brundolf|3 years ago
Not all languages are as bad as Python, and Rust comes with a lot of other costs. But it's very seductive to think about a world where you build a static binary with a single command, the build always works no matter what system it's on, the binary always works on the target OS regardless of what else is or isn't installed, it will use 1/10 the memory, and most likely it will never have any runtime errors because you were made to handle them all already
(I realize Go has at least some of these benefits, but its type system is hard for me to stomach)
cropcirclbureau|3 years ago
A note on performance, Rust's the only langauge where I haven't had the need to update my unit test harnesses to `TRUNCATE` tables instead of creating/discarding a separate database per test on PostgresSQL.
I'll also like to mention the gem that is SQLx[1]. As someone who's never been satisfied with ORMs, type checked SQL queries that auto-populate your custom types is revolutionary. With the error-prone langauge-SQL boundary covered, I was surprised just how good it can get making use of the builtin PostgreSQL features. Almost to the point that amount of effort the community's put to building great tools like Prisma.js and <insert favorite ORM> feel like a fool's errand (at least so for PosgreSQL).
[0]: https://github.com/alexpusch/rust-magic-function-params
[1]: https://github.com/juhaku/utoipa
[3]: lib.rs/crates/sqlx
ravi-delia|3 years ago
artic91|3 years ago
And, well, the usual, "learning curve" and some largely hypothetical concerns about hiring. I developed a complex app with Rust with very high time pressure and with developers that didn't have any previous Rust experience (I didn't have much of it myself), it was risky but it worked out well, so I know first hand that it's possible. And we are not "ex-google"!
brundolf|3 years ago
(Not /s, I genuinely think it's cool things are like this now)
codazoda|3 years ago
29athrowaway|3 years ago
mrich|3 years ago
vaylian|3 years ago
brochington|3 years ago
- Rust tends to push you to make good decisions. In my case, one of these good decisions was to ditch an ORM (which has always slowed me down) and instead write Postgres queries directly via SQLx. The compile time checks against an actual DB helped my speed dramatically
- Free performance can be a really big help when you are trying to figure out an API or algorithm. It's really helpful to know that my unoptimized code won't tank the server, and also helps me save costs on the cloud.
- "It doesn't compile, or it doesn't break" is kinda a mantra for Rust, and really helps me focus on problems at hand, instead of hunting down bugs.
> You will have a hard time hiring Rust developers.
I've found that there is a drastic difference between hiring devs willing to learn Rust, and devs that want to work with you because you are using Rust. The bar of those devs that seek out a Rust position tends to be very high.
> We made a huge mistake early on by adopting Actix as the web framework for our service...(To be fair, this was a few years ago and maybe things have improved by now.)
Actix-web has gone through some version-churn, but it's never been "buggy" in my experience. The experience multiple years ago is vastly different than today, but even my older services written years ago with Actix-web are still running fine.
> Libraries and documentation are immature.
Perhaps in years past, but I've always found the docs for Rust and its libraries to be very good. Folks write entire books on elements of Rust, and the standardization of the display of crate docs keeps things consistent.
> Rust makes roughing out new features very hard.
The "json!" macro can come in handy here. Also Github Copilot is a godsend for this.
> What really bites is when you need to change the type signature of a load-bearing interface and find yourself spending hours changing every place where the type is used only to see if your initial stab at something is feasible. And then redoing all of that work when you realize you need to change it again.
Hours? These type of corrections are spoonfed to you via errors at compile, or via the IDE. I've never had to spend hours on this. Everyone of these changes could be a bug, and having a typesafe language is a huge help here.
I recognize I might be in the minority, but I've really enjoyed using Rust for services for my startup. It's helped me move fast, but maybe I'm a special case. I'm curious to hear other's experiences.
monkey26|3 years ago
I often reach for Rust when Python could do, but it’s a bit bigger than a one page of code program. I also forget I’ve been doing Rust nearly full time since late 2015. And before that 15 years of C and understanding memory, etc. Maybe we’re just a rare breed.
unknown|3 years ago
[deleted]
_qzu4|3 years ago
You should be using the language you know best or dynamic languages when you are trying to move fast.
unknown|3 years ago
[deleted]
unknown|3 years ago
[deleted]
bradwood|3 years ago
Jokes aside. This is a thoughtful and interesting article. I was wavering on going down the Rust path for my SaaS start-up. Glad I didn't in the end for exactly the same kind of reasons.
blargg|3 years ago
unknown|3 years ago
[deleted]
Patrol8394|3 years ago
The goal is to deliver products and iterate as fast as possible. Productivity is key to success.
IF (and it is a big IF) your startup ever gets to the point of having to scale up (nice problem to have) then just throw money at AWS, hire senior engineers and let them figured it out.
What matters is customer experience; nobody cares of what’s behind the scene.
bgoldste|3 years ago
unknown|3 years ago
[deleted]
Kenji|3 years ago
[deleted]
unknown|3 years ago
[deleted]