Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

"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"

Great point



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.


FWIW the “parse don’t validate” attitude which has become popular in TypeScript circles does this equally well. In Rust you’ll define the types you expect to deserialize as structs with Deserialize trait implementations, in TypeScript you’ll define a basic schema with runtime decoding and corresponding (inferred) static types. Like you say, maybe 45 seconds more typing, with the same value guarantees.

I like that this is enforced in Rust (and that many other things are well beyond what tsc guarantees), and I like it in Node too and I’m glad that a certain corner of the ecosystem takes it seriously.


To me the greatest thing about TypeScript is that there are times that I absolutely know that something doesn't need to be extra safe or to have validation, and I can easily slap a `// @ts-expect-error` on it and either ignore it or come back and fix it later. I know some people think that's a horrible thing and sacrilege, but damn it if it makes it easy to move fast when you need to.


What’s an example where this works be a significant time saver?

In my experience writing a Zod schema to parse something into a typesafe form is quick and easy and you end up with full maintainability


Won’t speak for GP, but I’ll say why I think @ts-expect-error is a useful tool for this. It’s not so much a time saver as a time rearranger. Assuming a few conditions:

- you actually care about type safety so you’re not going to just `as any`

- you have a linter that will block unsafe commits or merges

- you have some type you want to use after it’s established safe, and an idea you want to fill out without breaking flow for even those 45 seconds or whatever to define your schema

- despite your predilection for type safety, you iterate on ideas like that the way people who prefer dynamic languages talk about: damn the torpedoes, I’m in the REPL

Given those assumptions (which fit a lot of TS devs well), the really good thing about @ts-expect-error in particular is it allows you to save an intermediate step for later, catch it in CI or whatevz, and it'll yell at you when, and only when, you leave it unsafe unnecessarily. It’s a good way to have your safety cake and eat your dynamic prototyping cake too, especially if breaking flow for a yak you’d shave anyway is going to sink your flow.


If you're comparing Rust favorably to JavaScript, and then concluding it's the right tool, I think you need more data points.


I take your comment to be a jab at JS, which I’m not a particular fan of, but I don’t think it holds much water: the GP’s example is nearly identical in Ruby and Python as well, and would have the same problem in those languages.


Another interpretation would be that Rust and JS cannot possibly cover all or even most programming domains, so there must be other languages out there that need to be in the ring for any given application.


if you also wanted to pull in a node framework for deserilization you could import something like `zod` to have the similar level of nice error messages when invalid input is encountered.

If you were in typescript, zod would also automatically generate your interfaces too.


> This doesn't match my experience.

Does it match the experience of a team and its need to collaboratively deliver software quality across varying levels of engineer experience? If not, then I'm not sure your individual experience is pertinent to the subject matter at hand (using Rust at a startup).


Feel free to weigh my data point as you see fit or ignore it altogether. It differs from the OP’s (which is why I thought it worth mentioning) and their experience is just as valid. To answer your question, I’ve spent the last three years at a startup building with Rust. Before that I spent 9 years at a startup building on Node.js.


Ok, for some perspective here, that 45 seconds longer is about 50-100 times how long it took to do the one liner in javascript. Extrapolate that to generally 50-100x development time for the development of an entire project and you're looking at weeks to months longer development time to solve the same problem. Rust is slower to develop in by a significant factor than js, python, ruby etc.


What I was trying to get at with the (silly) example is that the time-to-first-execution of a working program on good input might be much faster with something like JS, but the time to have a debugged version that fails gracefully (and clearly) on operational errors may not be. It’s okay to disagree, and it’s also okay to agree and still feel Rust makes the wrong tradeoffs. I just mention it because I think people sometimes overweight the time-to-first-run.


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.)


Rust with a robust GC (strong type safety, great error handling paradigm, Option type) would probably be my ideal language.


Have you tried ReasonML?


Isn’t it called ReScript or something now?


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 :/.)


Rust is essentially not doing anything to prevent the kinds of attacks you're talking about that other mainstream languages aren't already doing. It's a clear win over C and C++! But to a first approximation zero startups are shipping ordinary applicatioins in C/C++. Rust simply isn't meaningfully more secure than Java.


I would argue that a stronger type system will generally reduce bugs, and some of those bugs will impact users (whether by corrupting their data, or breaking a feature, or even causing a security issue).

Most bugs are from the programmer having a misunderstanding about how the system works as they change it. The stronger the type system, the more potential misunderstandings can be verified statically by the compiler before they reach the user.

Other, dynamically typed languages, will require either having unit tests, or running it in prod to find that user who has a null email or whatever, and results in things going awry. Since we're talking about startups, there are of course no unit tests or users, so this is all largely academic. Like, if there are 0 users to trigger bugs, and a bug that could be statically detected by a good type system exists, does it make a sound?


Stronger type systems do reduce bugs. But not all bugs are equal. When we talk about "velocity vs. safety" tradeoffs in SAAS software, we're virtually always talking about security vulnerabilities. There, it's much less clear that stronger type systems reduce vulnerabilities; in fact, the evidence mostly cuts the other way. As far as security is concerned, the major win is memory safety, and you can get that with plain 'ol Java or Python.

I'm bringing this up because in discussions like this, people tend to play fast and loose with the definitions of "safety". The kind of safety we're talking about in a decision between Rust and Java is mostly an externality to the SRE team, not to customers --- in other words, not an externality at all. An internality, if you will.


Most vulnerabilities in boring web apps are not memory safety issues.

I've decided to pick an arbitrary list of security issues where the fixes will be visible to gain some small anecdotal evidence. The top result for "gitlab CVEs" is this august release announcement, let's look at the first three vulns on it: https://about.gitlab.com/releases/2022/08/30/critical-securi...

1. Remote Command Execution via GitHub import

This one was a typeing issue where an object with special keys resulted in dynamic code execution. That could not happen in rust. See the hn discussion here - https://news.ycombinator.com/item?id=33155527

2. Stored XSS via labels color

This can be made into a type-system issue with a good enough type system, text and html should be different types. Arguably this could happen with rust, but honestly, probably would not.

3. Content injection via Incidents Timeline description

This one is also arguably a typing issue for the same reason as above.

----

Hey, look, 3 errors that type systems would help with and which had security implications.

> it's much less clear that stronger type systems reduce vulnerabilities; in fact, the evidence mostly cuts the other way.

What do you mean by that? In what case is a worse type-system (like java or go) going to make it harder to write vulnerabilities than a stronger type system (like haskell or rust)


I'm simply going to say this again: Rust's type system doesn't meaningfully mitigate XSS, RCE, or metacharacter injection. You are equally likely to write an SQLI or an SSRF in Rust as you are in Java.

There are exactly two types of vulnerabilities Rust (and some other modern memory-safe languages) mitigate beyond memory corruption:

1. Java, Python, and Ruby have deserialization libraries that can easily be misused to create RCE vulnerabilities.

2. Python, Ruby, and Javascript have eval and eval-equivalents (which is essentially what your first example is).

You can pretend anything is a type system issue, but neither of these two vulnerabilities are properly understood as type safety errors. Java has a sharply more prescriptive and policed type system than Ruby does, but both have deserialization issues; it's just a generational thing.

Deserialization in new Java code is unlikely; deserialization is much less common than SSRF, which plagues Rust code just like everything else. In 2022, there is no meaningful security benefit to Rust over Java.

There are other reasons to use Rust! People should just stop making up fake security reasons to do it.


As a Rust fanboy, I mostly agree with this sentiment. Theoretically, Rust should prevent “security” issues arising from memory safety issues like heartbleed (maybe not actually heartbleed) but a good GC would too. I do think Rust does push a little harder on correctness via Result types and things like Sync/Send traits, but I don’t have much Java experience to fully compare.

However, type correctness won’t necessarily prevent a DDoS, stolen password, specter, timing attack, phishing attack, etc. Type safety is a nice-to-have but not sufficient for security in SAAS products.


The idea that a clever memory leak is the root cause of most stolen data instead of a phishing attack is ridiculous


I think most of the things that people feel slow them down about using Rust are cases where the language is forcing you to be kind of pedantic about types (and other invariants encoded in the type system). I totally get that. But the idea that compile-time checks don't eliminate important classes of runtime bugs that impact end users is also ridiculous.


There certainly exist languages like F# and OCaml (functional first domain modeling) and also Elixir and Erlang (100% immutable data and failure control) that provide safety but do not get in the way of developer productivity like Rust.


A programming language can not guarantee a program written in it works correctly, even if you are writing in something like Coq or Idris. People who care much more about velocity than about correctness and security--as they are incentivized to do by the shared competitive game they are all playing--can and do routinely code these errors in any number of programming languages.


I see what you are getting at. I think I may have misinterpreted what you originally wrote. Although my comment still stands alone, I can agree that getting people and organizations to move slower, as a whole, would be beneficial. The venture capitalism going on is basically just people trying to make a buck as quick and as much as possible. There's very little art or craft involved or concern for actual customers today.


“Software doesn’t exist yet” is a huge user cost


Could you expand on this? It doesn't really make sense to me, but I'm also a Rust fan. The premise that Rust prioritizes safety (or performance) over developer productivity also doesn't resonate.

As a consumer, I tend to prefer the thing that is available a bit later (or more expensive) and works well, versus the one that is available sooner (or cheaper) and is less reliable. Maybe that preference is a result of years spent fixing things that could've been designed better?


I believe the point TylerE is trying to make is that features that take longer to deliver are a cost to the user. If a user is waiting on a feature, or perhaps a bug fix and that is taking 4x the time to deliver - the cost is right there on the user's clock waiting.

Many people would argue you with you that the "easier" programming languages are no less reliable, context depending. Framing this in the context of the article a CRUD app, there are plenty of reliable frameworks in many languages.


I feel like that boils down to "time is money", and I don't disagree in a commercial context.


Not more than software that do exist.


You're just reiterating the author's point. Not every piece of software written faces dire security ramifications like leaking user identity. Not all software is loading or touching user data at all. Not all software is running in trusted environments. The premise is that Rust may be a good fit if security is a key concern, and even then I would argue it's likely possible to partition the domain into security-sensitive and security-insensitive domains. Cherry picking problem spaces where security matters and making claims about Rust goes against the spirit of the argument.


I would claim the author has an extremely narrow view of where safety matters. Hell: he's even using a pretty safe language (Go) as his alternative! I think the most charitable interpretation I have for the article is that he doesn't actually want to say "I refuse to sacrifice safety for velocity" but "I refuse to sacrifice performance for velocity", which just isn't the same thing.


Well, no, the prudent choice for someone concerned with "safety" in this context is any high-level memory managed (GC) language. It's any boring language that has no `unsafe` at all. What you're actually saying is "I'm willing to sacrifice safety for performance," as invariably the objection to a high-level GC language by Rustaceans is that it lacks the necessary lolspeed.


> while the benefits of trading safety vs. velocity go to the company, the costs go to the user

This is a problem in general, but it's not a good reason to use Rust in a startup, it's a good reason to use Java or C# or TypeScript or another well-worn high-level language with static typing.

Rust's niche is solving a set of security problems that most high-level languages don't have. Choosing it for a startup only really improves your security if the other language you're considering is C or C++.


>This is a problem in general, but it's not a good reason to use Rust in a startup,

It's a good reason to not collect/store information in the first place. If your startup depends on the collection of your user's PII, then I'd seriously question if there's a real purpose to your startup. IF your startup 100% does require the use of PII, then yes, slow the fuck down, and do it right.


I think that’s a bit reductive. The health tech industry as a whole fits this bill — do you question if startups in that sector have a real purpose? There are loads of green engineering teams that have to figure out how to comply with really tricky data handling regulations.


I'm saying that if that is your business, then don't move fast and break things. Health sector isn't going anywhere. It's not a first to market kind of situation. Take your job seriously and secure your data.

If you're some other startup that doesn't actually need PII, but realize it is a fast way to make money, then you should really soul search to ask if you're as amoral as you look to others and if you're okay with that. If not, make a better product that doesn't mean selling your soul to make a buck.


FWIW, immediately after leaving my comment and definitely before seeing your response--but maybe after you opened my comment to read and start your reply--I added this:

> 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.


Rust's safety goes far beyond memory safety. Java or C# or Typescript don't force you to handle errors and don't force you to exhaustively match and don't have an ecosystem that prioritizes safety etc.


Very little --- I'll go ahead and say, to a first approximation, none --- of that safety has anything to do with software security. The same kinds of bugs that hit Java programs hit Rust programs, with maybe the sole exception of deserialization (which has nothing to do with error handling or type safety).

That matters because that's the kind of "safety" we're talking about when we discuss externalities for end-users --- not servers that need extra monitoring because they might crash.


Ignoring error codes and left-pad style issues are common sources of security issues.

Java is more left-pad resistant than Typescript, granted.


No. Rust doesn't do anything interesting to avoid supply-chain attacks.


> an ecosystem that prioritizes safety etc.

Idiomatic Rust code is just as cavalier regarding NPEs as Java or Python code. Because the language starts to look really gross when you make your code panic-safe. So you have an `expect` here, an `unwrap` there, and now you're going to have the exact same runtime issues as the more expressive managed languages. No Rust programmer thinks their `expect` will panic, just like no Java programmer expects something will be null. Rust does not force you to "exhaustively match".


expect is a lot safer than ignoring a return code.


Java and Python don't use return codes, they use exceptions. If you ignore an exception your program crashes, same as a panic in Rust.


I don't think you can reasonably draw any of the conclusions you've made from the individual statements you've said. User PII being misappropriated is far more likely to come from poor InfoSec practices than from the application layer. Memory safety issues are far more likely to accrete to application layer instability and crashes more than not; now that isn't materially good, but it's apples and oranges.

Then you talk about why "startups need regulation" and the lack thereof is why "the world remains an insecure mess" which is another non sequitur drawn from statements which, while individually correct, would never combine to imply that conclusion.

The world is an insecure mess because some societies have not collectively agreed that it is more expensive to be insecure than secure.

Startups don't "need" regulation anymore than regulation is a cure for any problem. In practice, poorly drafted regulation exacerbates rather than solves the problem it is scoped to solve because it opens the door for regulatory capture based monopolies.

That said, I do agree with parts of many of your individual statements: more effective regulations would be good not just for citizens but for startups and society in general; memory safety oriented code tends to be higher ROI for everyone; the world remaining an insecure mess is a pox on global societies whereupon well deployed investment into secure infrastructure would produced significant ROI compared to the present state of the world.


Data security in a SaaS application has more to do with proper role based access to databases than with memory safety. There is nothing in Rust that provides superior role-based security for SaaS than existing frameworks in every major backend language.


I don't disagree, but it sounds like you somehow magically think someone who refuses to trade off velocity for safety--which was a genetic premise that doesn't have much to do with Rust in specific--won't also mess up everything else they touch, which seems far fetched.


I think you're excluding too much of the middle here. Exchanging Rust for Java isn't a meaningful concession to safety, but it is a significant boost to velocity. If you can use Java for your problem domain, Java is probably just objectively better suited to your problem than Rust is.


> as it is the user whose data or identity will be stolen.

that seems a little alarmist, don't you think?


I'm sorry, do you somehow think that is a theoretical concern? I seriously won a $2M bug bounty earlier this year because the CEO of a company wanted to "move fast and break things" their way to a financial product offering :/.


It's alarmist because not all software is a financial product and your original statement lacks necessary qualifiers.


No, some products--like this guy's startup--are providing machine learning services for such devices as cars and drones, an area where safety clearly doesn't matter ;P. I think the issue, FWIW, is that we are actually going to disagree on what those "qualifiers" should be, not merely that they might exist.


Congratulations on becoming a millionaire! That's pretty cool (for you at least, probably not their customers).


The CEO wanted to move fast and break things with respect to security but offered a $2 million bug bounty?


I am not sure how those aren't incompatible thoughts... I was explicitly told, by the CEO, that she was channeling that mindset, and the security engineer there I ended up speaking to was clearly not bothering to actually figure out how to filter change sets made by their engineer as he "felt bad" about it... and I kind of don't blame them, as to the winners go the spoils in some sense? They were super lucky I was the one that found the issue and not a black hat, as $2M was nowhere near how much damage I could have caused. And that's in a financial system, where you might expect someone to know better, and yet they have the same incentives to play fast and loose as everyone else :(.


I think the point here is that the CEO clearly values security, if they were willing to pay you $2m do find issues, isn't it?


Rust still won't save you from logic errors, so I guess I don't see your point.


I don't disagree?... The idea that moving fast is more important than correct and safe code--because a startup can't afford to waste time on these matters as their competitors who "don't give a shit" will eat their lunch--goes well beyond Rust and mere memory safety.


> 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.


Not to mention that cythonization might be part of the pipeline and can have bugs that only show up post-cythonization.

I really dislike python in production and have done it a lot more than I've ever wanted.


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.


>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

Are you actually a C++ programmer? I work at a firm that uses C++ and Rust and this isn't the case at all. Setting up dependencies, tests and benchmarks is a one-off cost, most C++ compiler errors are quite understandable to experienced devs unless they're doing something really hairy, and C++ has algebraic datatypes, as a library (std::variant) via variadic templates, something Rust doesn't support. For C++ devs comfortable with template metaprogramming Rust is missing a bunch of features, many things that are relatively simple in C++ are literally impossible in Rust (at least without writing macros). Rust also doesn't save much on debug time if writing single-threaded code, because memory errors are a very small proportion of the bugs one encounters in modern C++ written by experienced devs, rather most bugs are logic errors, which Rust doesn't prevent.


I was for several years. We were using git submodules to handle dependencies, but still using third party packages involves copy paste a lot. `std::variant` was the one we use to mimic the rust `enum` but it is much cumbersome to use, and not safe at all, there was no compiler checked `match`. Sure, single threaded code is much better, but this won't help with buffer overrun, or use after free like `String("hello").c_str()`, or iterator invalidation when you loop and delete, you just gradually learn all those gotchas along the way while bearing the learning cost. Trust me, experienced devs appreciate Rust much more if they are actually good at writing memory safe code.


> variadic templates, something Rust doesn't support

Well, Rust uses macros for that which are equivalent to C++ templates. Ever used println!() ?


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.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: