Why Rust for the Backend?

You've heard the pitch. Memory safety without garbage collection. Fearless concurrency. Zero-cost abstractions. It compiles, therefore it works. Et cetera.

All of that is true, and none of it is why you should write your backend in Rust.

You should write your backend in Rust because the ecosystem has finally caught up to the language. For years, Rust had the best type system in production use and an async story that required reading several blog posts, a few RFCs, and at least one existential crisis to understand. That era is over. Tokio is stable and excellent. Axum is ergonomic and fast. SQLx gives you compile-time checked SQL queries. The toolchain is genuinely good.

This book is about building real backend services — HTTP APIs, database access, authentication, observability, deployment — using the current stable Rust ecosystem. We're not going to implement a toy JSON API that returns { "hello": "world" } and call it a day. We're going to build things that work in production.

What This Book Is Not

This is not a Rust tutorial. If you need to be told what a lifetime is, start with The Rust Programming Language and come back. We'll be here.

This is not a survey of every async runtime or HTTP framework. Tokio runs the world. Axum is built on Tower and Hyper, which are the best abstractions available. We're going to learn these tools deeply rather than skimming ten alternatives.

This is not a book about microservices architecture, Kubernetes, or why you should decompose your monolith. Those are fine topics. They're not this topic.

What This Book Is

A practical guide to the choices that actually matter:

  • Which crate, and why — not "here are five options, pick one"
  • What the type system is telling you — Axum's extractor pattern is elegant once you understand FromRequest, confusing until you do
  • How things fail in production — error handling, connection pools, panics in async tasks
  • How to know what's happening — structured logging, distributed tracing, metrics
  • How to ship it — containers, static binaries, multi-stage Docker builds

The Stack

Throughout this book, we'll use:

ConcernCrateVersion
Async runtimetokio1.x
HTTP frameworkaxum0.7.x
Databasesqlx0.7.x
Middlewaretower / tower-http0.5.x / 0.5.x
Tracingtracing / tracing-subscriber0.1.x
Error handlingthiserror / anyhow1.x
Configurationconfig + dotenvy0.14.x / 0.15.x
JWTjsonwebtoken9.x

These are not the only options. They are good options, they work together, and they're what you'll encounter in real Rust backend codebases today.

A Note on Cargo Editions and MSRV

All examples in this book use the 2021 edition. Your Cargo.toml should have:

[package]
edition = "2021"

We'll target Rust 1.75+, which is when async fn in traits was stabilized. Some patterns in this book require it.

Getting Started

If you don't have Rust installed:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Then install the stable toolchain:

rustup default stable
rustup update

Verify:

rustc --version  # rustc 1.75.0 or newer
cargo --version

We'll create a new project at the start of each major chapter. When you're ready to follow along for real, run:

cargo new --bin my-backend
cd my-backend

Now let's talk about async.