Choosing Rust in 2026: when the compile-time tax is actually worth it

Elena Vasquez

Elena Vasquez

August 27, 2026

Choosing Rust in 2026: when the compile-time tax is actually worth it

I have a timer in my head from the years I spent waiting on cargo build in a Barcelona office that got loud at 6 p.m. The first time I switched a service from Go to Rust, I told the team we were buying correctness. What we actually bought, for the first six weeks, was a coffee habit. The borrow checker was not the expensive part. The expensive part was the minutes between “I think this is right” and “the compiler agrees,” multiplied by every person on the pull request.

That tax is smaller in 2026 than it was in 2020. It is not gone. rustc got faster. Incremental builds got less insulting. rust-analyzer no longer feels like a second job on a mid-size crate. sccache, mold, nextest, and a Cranelift debug profile will save you real minutes. None of that changes the question I still ask before I reach for Rust: is the thing I am building the kind of thing that pays rent on a slow compile?

This is not a language-war essay. Go and Zig are fine. I have shipped both. This is about the specific bill Rust hands you at compile time, and the cases where I still sign it without pretending it is free.

What the tax actually is

People collapse “Rust is slow to compile” into one complaint. It is at least four different bills, and they show up in different rooms.

The first bill is the cold build. A clean CI runner, a new laptop, a dependency bump that invalidates half the graph. This is the one that makes Slack go quiet. In 2026 a non-trivial workspace can still cost you several minutes on a cold runner even if your laptop is fine. If your pipeline does that on every PR, you are paying a team tax, not a personal one.

The second bill is the inner loop. You change a function, you wait, you see the red, you change it again. Incremental cargo and rust-analyzer closed a lot of this gap. They did not close it for the crate that sits in the middle of a workspace and re-exports half your types. One “small” edit in a foundational crate still ripples. I have watched people learn to stop putting shared types in the crate everyone depends on, not because of architecture fashion, but because they were tired of waiting.

The third bill is the first-compile-of-the-day tax on your brain. rust-analyzer wants to index. proc macros want to run. The editor is “ready” in the way a kettle is ready when it has started making noise. If you context-switch into a Rust repo for twenty minutes between meetings, you can spend ten of those minutes watching a progress spinner. That is not a tweet. That is why some teams keep a Go sidecar for the glue.

The fourth bill is the human one, which the benchmarks skip. Rust does not only take wall-clock time. It takes attention. A borrow error is often a real design problem. It is also a design problem you cannot postpone the way you postpone a linter warning in a language that will still run. You pay now. That is the product.

Two laptops on a desk during a compile, coffee mug nearby

The 2026 mitigations, without the brochure

I am not going to pretend the last few years did not happen. Split your workspace so leaf crates compile alone. Keep proc-macro surface area small; they are still a time sink. Use nextest so tests are not a second serial compile in disguise. Cache the dependency graph in CI like you mean it, and pin the cache key to the lockfile, not to vibes. A debug build with Cranelift is good enough for a lot of “does this even run” work. Release builds can stay on the runner that is not your laptop.

AI coding agents changed the tax in a way the compiler team did not plan for. They emit a lot of Rust now. They also emit a lot of Rust that does not compile. You can sit and watch an agent iterate against rustc the way we used to iterate, except the agent does not get bored and the bill still lands on your CI minutes. If you let an agent “just finish the crate” overnight, check what it did to your dependency graph in the morning. I have seen a helpful agent pull in four crates to avoid writing thirty lines, and the cold build never recovered its manners.

The mitigations make Rust livable. They do not make it the default for a script you will throw away on Thursday.

When I pay the tax on purpose

I reach for Rust when the cost of a silent failure is higher than the cost of waiting. That sentence is doing a lot of work, so here are the cases where it has been true for me, not the cases that look good on a conference slide.

A boundary that has to stay up

Anything that parses untrusted input and sits on a network is a candidate. Not because Rust is magic. Because the class of bugs I used to ship in C++ and, less often, in Go — use-after-free, accidental copies of a buffer I thought I had moved, a default that panics in a library path — are the class of bugs I do not want in a process that faces the internet. The compile-time tax is the price of making those bugs a conversation with the compiler instead of a conversation with the on-call.

I do not put Rust on every HTTP handler in a CRUD app for this reason. I put it on the parser, the protocol, the thing that touches bytes from the outside. The rest of the product can be whatever the team already ships quickly.

A long-lived binary that is annoying to patch

Agents in the field. A CLI that customers install and forget. A sidecar that production will not let you bounce on a whim. If the release train is slow, I want the compiler to be rude now. The tax is cheaper than a hotfix ritual six months later when the original author is at another company.

This is also why I am less precious about Rust for an internal web dashboard that deploys twelve times a day. If you can patch in an hour, the incremental cost of a memory-safe language is harder to defend against a language the team already thinks in.

A performance ceiling you can name

Not “it should be fast.” A number. P99 under a budget. A packet path. A batch job that has to finish before the next window. Rust is worth the compile when you are going to spend time in the profiler anyway, and you do not want the language to add a GC pause to the story you have to explain to someone who writes the checks.

If you cannot name the number, you are not choosing Rust for performance. You are choosing it for identity. I have done that. It is an expensive hobby.

A small team that will live in the code

Rust’s tax has a strange property: it is worse for strangers and better for a team that stays. The first month is slow because the types are a language the team has not finished inventing. Month six is faster than the equivalent Go service if the Go service grew a pile of implicit contracts. I have seen both. The compile time does not go to zero. The number of “wait, who is allowed to mutate this” conversations does.

If the team is a revolving door of contractors who will be gone in ten weeks, do not pay this tax. You will spend the whole engagement teaching the compiler, and the contractors will write the same service again in the language they already have muscle memory for.

Small office server rack with amber status lights behind glass

When I refuse the tax

A prototype that exists to answer a product question. A glue service whose entire job is to move JSON from A to B and retry. A weekend tool I will not open in a month. An API whose bottleneck is someone else’s database. A team whose last Rust project is a scar, not a skill.

I also refuse it when the compile is being asked to substitute for tests you will not write. Rust will not save a bad data model. It will make a bad data model slower to change. I have sat in reviews where someone said “the types will catch it” and the types caught a lifetime and missed the business rule. The tax is not a test suite.

And I refuse it for the social reason nobody puts in the RFC. If two of your three strongest engineers will be slower and sadder in Rust, you did not buy correctness. You bought a hiring problem and a morale problem and a compile you now have to defend in standup. Languages are staffing decisions. The compile-time tax is just the part you can measure with a stopwatch.

How I decide on a real project

I steal a trick from the infrastructure reviews I used to sit through. I write the failure I am afraid of in one sentence. Then I write how often we will change this code in the next year. Then I write who will be on-call for it.

If the failure is “we serve wrong bytes to a customer” or “we corrupt the queue” and the change rate is low and the on-call is us, Rust is in. If the failure is “the experiment does not convert” and the change rate is weekly and the on-call is a product manager refreshing a dashboard, Rust is out. If the failure is “we might be a bit slower than we could be” and nobody has a number, Rust is out until someone gets a number.

I also time a representative edit. Clone the repo, change a string in a mid-graph crate, measure to test green. If that loop is over a minute on a warm machine after you have applied the obvious caches, the tax is not theoretical. Either split the crate or pick a different language for that layer. Do this before you announce the rewrite in a channel with a logo in the topic.

CI minutes are part of the design. A language that is “free” on your laptop and brutal on GitHub Actions is not free. I have killed Rust proposals that were technically pretty because the org’s runners were already a political fight. You cannot win a language argument and a capacity argument in the same quarter unless you are very popular.

Living with the tax once you have chosen it

If you said yes, treat compile time like a production SLO. Someone owns the graph. Dependency upgrades are scheduled, not festive. The crate that everyone imports gets a budget: if a change there rebuilds the world, that change needs a reason. You write down the commands for a fast check so newcomers do not discover cargo build --release as their first inner loop.

You also forgive yourself for a second language at the edges. A Python notebook that calls the Rust binary is not a betrayal. A Go control plane that execs a Rust worker is a pattern I have shipped and would ship again. Purity is how you end up compiling the admin UI.

Code review changes too. In Rust I spend less time asking “can this be null” and more time asking “did we just make the easy change expensive for everyone downstream.” That is the compile-time tax showing up as architecture. If you ignore it, you get a beautiful type system and a team that is afraid to touch the shared crate. I have been on that team. We wrote wrappers to avoid recompiling. The wrappers became the product.

So is it worth it

Sometimes. In 2026 I pay the tax for boundaries, for binaries I cannot patch on a whim, for paths with a named performance budget, and for teams that will still be here when the types start paying back. I do not pay it to feel serious. I do not pay it because a timeline said Rust is inevitable. I do not pay it because an agent can now emit impl blocks. The agent does not sit in the standup when CI is yellow.

If you are choosing Rust this year, choose it for a sentence you can defend when the build is still running. “We cannot afford this class of bug in this process” is a sentence. “I would like to get better at Rust” is also a sentence. Only one of them belongs in an RFC.

More articles for you