Step 1 — Why Rust for Backends
Welcome. This is a hands-on, seven-step tutorial that takes you from "I've heard Rust is fast" to "I understand how a real Rust backend is put together." Every concept is grounded in the same stack that powers iKanban's own backend: Axum for HTTP, Tokio for async, SQLx for PostgreSQL, and Serde for JSON.
By the end you'll have built a small Tasks API — create a task, list tasks, fetch one by id — using the exact patterns a production service uses.
What you'll build
A single continuous example runs through every step:
| Step | You'll add |
|---|---|
| 1 | The mental model (this page) |
| 2 | The four language ideas you actually need |
| 3 | A Cargo project + workspace |
| 4 | Your first Axum endpoint |
| 5 | A PostgreSQL query with SQLx |
| 6 | Typed errors, auth middleware, JSON contracts |
| 7 | Build, run, and deploy |
Why choose Rust for a backend?
Three properties matter, and a deployed API benefits from all three.
1. Memory safety without a garbage collector
Rust proves at compile time that your program never uses freed memory, never dereferences null, and never races on shared data — and it does this with no garbage collector. In practice that means:
- No GC pauses → predictable tail latency (p99). Your slowest requests aren't slow because a collector decided to run.
- Tiny memory footprint → a Rust service doing the same work as a JVM or Node service typically uses a fraction of the RAM. On a container platform where you pay per MB, that's real money.
2. "If it compiles, it works" — for a whole class of bugs
Null-pointer crashes, use-after-free, data races, and most "I forgot to handle that case" bugs are compile errors, not 3 a.m. pages. The compiler is strict precisely so production is calm.
With SQLx (Step 5) this guarantee extends all the way into your SQL: a typo'd column name fails the build, not a user request.
3. Fearless concurrency
A backend serves thousands of requests at once. Rust's type system tracks which data is safe to share across threads (Send/Sync), so "two requests mutating the same thing" is caught by the compiler rather than discovered in a heisenbug.
The honest trade-off
Rust asks more of you up front:
- The borrow checker rejects some code that looks fine until you learn its rules (Step 2).
- Compile times are slower than Go or a scripting language.
- Async has sharp edges around lifetimes.
The bargain is: you pay attention at compile time so you don't pay attention at incident time. For a service that needs to stay up, that's usually a good trade — and this tutorial front-loads the exact subset of Rust that makes the trade pay off.
What you need installed
To follow along you'll want:
- Rust via rustup (gives you
rustc,cargo, and toolchain management). - PostgreSQL (local install or Docker) for Step 5.
- Any editor with rust-analyzer — its inline type hints are the single biggest accelerator when learning.
Check your install:
rustc --version # e.g. rustc 1.86.0
cargo --version # e.g. cargo 1.86.0
When you're ready, continue to Step 2 — Four Core Language Ideas, where we cover the only Rust concepts you need to read and write backend code with confidence.