Rust für das Web: Actix Web vs Axum - Vergleich und Interview-Fragen 2026
Ein praxisorientierter Vergleich von Actix Web 4.14 und Axum 0.8 für die Rust-Webentwicklung 2026. Architektur, TechEmpower Round 23 Benchmarks, Entwicklererfahrung und Interview-Fragen für Backend-Rust-Positionen.

Rust-Web-Framework-Adoptionen haben 2026 deutlich zugenommen, und zwei Frameworks dominieren Produktions-Deployments: Actix Web 4.14 und Axum 0.8. Die Wahl zwischen ihnen beeinflusst alles vom Team-Onboarding bis zum Produktionsdurchsatz, und die Frage kommt häufig in Backend-Rust-Interviews vor.
Actix Web 4.14 führt bei reinem Durchsatz (10-15% mehr Requests pro Sekunde unter hoher Last). Axum 0.8 bietet bessere Ergonomie durch native async-Traits, Tower-Middleware-Komposierbarkeit und engere Tokio-Integration. Für die meisten Teams, die 2026 ein neues Projekt starten, ist Axum die pragmatische Wahl, sofern keine extremen Durchsatzanforderungen bestehen.
Architektur-Unterschiede zwischen Actix Web und Axum
Die architektonische Divergenz zwischen diesen beiden Frameworks erklärt die meisten Performance- und Ergonomie-Trade-offs.
Actix Web startet N Single-Threaded-Tokio-Runtimes, eine pro physischem Kern. Tasks werden an Threads gepinnt ohne Cross-Thread-Datenmigration. Dies eliminiert Work-Stealing-Overhead und Cache-Line-Bouncing, was den konsistenten Durchsatzvorteil unter anhaltender Last erklärt.
Axum läuft auf einer einzelnen Multi-Threaded-Tokio-Runtime mit Work-Stealing. Das Tokio-Team hat Axum speziell entwickelt, um die Fähigkeiten der Runtime zu demonstrieren, daher optimiert jede Designentscheidung für Komposierbarkeit mit dem breiteren Tokio-Ökosystem. Handler sind einfache async-Funktionen, und Middleware verwendet Towers Service-Trait.
use actix_web::{web, App, HttpServer, HttpResponse};
async fn health() -> HttpResponse {
HttpResponse::Ok().json(serde_json::json!({ "status": "ok" }))
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/health", web::get().to(health))
})
.bind("0.0.0.0:8080")?
.run()
.await
}use axum::{Router, Json, routing::get};
use serde_json::{json, Value};
async fn health() -> Json<Value> {
Json(json!({ "status": "ok" }))
}
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/health", get(health));
let listener = tokio::net::TcpListener::bind("0.0.0.0:8080")
.await
.unwrap();
axum::serve(listener, app).await.unwrap();
}Beide Beispiele kompilieren und laufen, aber die Unterschiede sind bereits sichtbar. Actix Web verwendet sein eigenes #[actix_web::main]-Makro und gibt std::io::Result zurück. Axum verwendet das Standard-#[tokio::main] und baut Routes über eine Router-Struct. Der Axum-Handler gibt einen typisierten Extractor (Json<Value>) zurück, anstatt manuell eine HttpResponse zu konstruieren.
Performance-Benchmarks: Actix Web 4.14 vs Axum 0.8
Benchmark-Daten aus TechEmpower Round 23 (Januar 2026) liefern den zuverlässigsten Vergleich. Beide Frameworks rangieren in allen Kategorien in der Spitzengruppe.
| Metrik | Actix Web 4.14 | Axum 0.8.9 |
|---|---|---|
| Plaintext (req/s) | ~7.100.000 | ~6.200.000 |
| JSON-Serialisierung (req/s) | ~1.200.000 | ~1.050.000 |
| DB-Einzelabfrage (req/s) | ~190.000 | ~175.000 |
| Speicherverbrauch (Hello World) | ~8 MB | ~6 MB |
| P99-Latenz (JSON) | 1,1 ms | 1,3 ms |
Actix Web hält einen Durchsatzvorteil von 10-15% über alle Kategorien. Axum benötigt etwas weniger Speicher aufgrund der gemeinsamen Tokio-Runtime. Zum Kontext: Beide Frameworks übertreffen Go's Standard-HTTP-Server um das 2-3-fache und Node.js um das 5-8-fache auf vergleichbarer Hardware.
Der Performance-Unterschied ist relevant für Ad-Serving, Echtzeit-Analytics-Pipelines und High-Frequency-Trading-Gateways. Für eine typische REST-API mit 10.000 Requests pro Sekunde sind beide Frameworks weit jenseits des Engpasses, der die Datenbank oder externe Service-Aufrufe sein wird.
Extractors und Request-Handling im Vergleich
Extractors definieren, wie Frameworks eingehende Requests parsen. Axum 0.8 hat hier signifikante Verbesserungen vorgenommen, indem #[async_trait] zugunsten nativer async-Traits entfernt und OptionalFromRequestParts für bessere Option<T>-Handhabung eingeführt wurde.
use axum::{
extract::{Path, Query, State, Json},
routing::get,
Router,
};
use serde::Deserialize;
use std::sync::Arc;
#[derive(Deserialize)]
struct Pagination {
page: Option<u32>, // defaults to None if missing
per_page: Option<u32>,
}
// State shared across handlers
struct AppState {
db_pool: sqlx::PgPool,
}
// Axum 0.8: /{id} syntax (replaced /:id)
async fn get_user(
State(state): State<Arc<AppState>>,
Path(user_id): Path<i64>,
Query(pagination): Query<Pagination>,
) -> Json<serde_json::Value> {
let page = pagination.page.unwrap_or(1);
// Query database using state.db_pool
Json(serde_json::json!({
"user_id": user_id,
"page": page
}))
}use actix_web::{web, HttpResponse};
use serde::Deserialize;
#[derive(Deserialize)]
struct Pagination {
page: Option<u32>,
per_page: Option<u32>,
}
struct AppState {
db_pool: sqlx::PgPool,
}
async fn get_user(
state: web::Data<AppState>,
path: web::Path<i64>,
query: web::Query<Pagination>,
) -> HttpResponse {
let user_id = path.into_inner();
let page = query.page.unwrap_or(1);
HttpResponse::Ok().json(serde_json::json!({
"user_id": user_id,
"page": page
}))
}Axums Extractors verwenden Tuple-Destructuring direkt in Funktionsparametern. Actix Web wrapped alles in web::Path, web::Query usw. und erfordert .into_inner()-Aufrufe. Beide Ansätze sind zur Compile-Zeit typsicher, aber Axums Ansatz liest sich natürlicher.
Pfadparameter wurden von /:id- zu /{id}-Syntax in Axum 0.8 (via matchit 0.8) geändert. Dies entspricht der OpenAPI-Pfadsyntax. Escaping verwendet doppelte Klammern: {{ für ein literales {.
Middleware-Architektur: Tower vs Actix-Middleware
Middleware-Komposition ist der Bereich, in dem der architektonische Unterschied die größte praktische Auswirkung hat.
Axum verwendet Towers Service- und Layer-Traits. Jede Tower-kompatible Middleware funktioniert mit Axum, einschließlich Rate-Limiter, Tracing, Compression und Authentication-Layers, die für andere Tower-basierte Services erstellt wurden. Diese Komposierbarkeit geht über HTTP hinaus; dieselbe Middleware kann gRPC-Services über Tonic wrappen.
use axum::{
Router, middleware,
routing::get,
extract::Request,
response::Response,
};
use tower_http::{
cors::CorsLayer,
compression::CompressionLayer,
trace::TraceLayer,
};
use std::time::Instant;
// Custom middleware as a plain async function
async fn timing_middleware(
request: Request,
next: middleware::Next,
) -> Response {
let start = Instant::now();
let response = next.run(request).await;
let duration = start.elapsed();
tracing::info!("Request took {:?}", duration);
response
}
fn build_router() -> Router {
Router::new()
.route("/api/data", get(|| async { "ok" }))
.layer(middleware::from_fn(timing_middleware))
.layer(CompressionLayer::new())
.layer(CorsLayer::permissive())
.layer(TraceLayer::new_for_http())
}Actix Web verwendet sein eigenes Middleware-System mit Transform- und Service-Traits (nicht die von Tower). Middleware aus dem breiteren Tower-Ökosystem erfordert Adapter oder Rewrites.
Für Teams, die bereits in das Tower-Ökosystem über Tonic (gRPC) oder Hyper investiert haben, ist Axums Middleware ein signifikanter Vorteil. Für Teams, die einen eigenständigen HTTP-Service bauen, ist Actix Webs Middleware-System gleichermaßen fähig, nur nicht austauschbar.
Actix Web 4.14 führte Route-Middleware-Validierung ein, die einen Panic auslöst, wenn Handler nach dem Middleware-Wrapping hinzugefügt werden, um Konfigurationsfehler beim Start statt zur Laufzeit zu erkennen.
Bereit für deine Rust-Interviews?
Übe mit unseren interaktiven Simulatoren, Flashcards und technischen Tests.
Datenbankintegration mit SQLx
Beide Frameworks arbeiten gut mit SQLx zusammen, dem async-first SQL-Toolkit, das Queries zur Compile-Zeit validiert. Das Integrationsmuster unterscheidet sich leicht.
use sqlx::PgPool;
// This struct works identically with Actix Web and Axum
#[derive(sqlx::FromRow, serde::Serialize)]
struct User {
id: i64,
email: String,
created_at: chrono::NaiveDateTime,
}
// sqlx::query_as! validates against a live DB at compile time
async fn find_user_by_email(
pool: &PgPool,
email: &str,
) -> Result<Option<User>, sqlx::Error> {
sqlx::query_as!(
User,
"SELECT id, email, created_at FROM users WHERE email = ",
email
)
.fetch_optional(pool)
.await
}Die Datenbankschicht bleibt unabhängig von der Framework-Wahl identisch. SQLx' query_as!-Makro verbindet sich zur Compile-Zeit mit einer Live-Datenbank und validiert Spaltennamen, Typen und Tabellenexistenz. Ein Tippfehler in einem Spaltennamen erzeugt einen Compile-Fehler, keinen Laufzeit-Crash.
Fehlerbehandlungsmuster im Vergleich
Fehlerbehandlung offenbart unterschiedliche Designphilosophien. Actix Web verwendet ResponseError-Trait-Implementierungen. Axum basiert auf IntoResponse kombiniert mit dem Result-Typ.
use axum::{
http::StatusCode,
response::{IntoResponse, Response},
Json,
};
// Define application-level errors
enum AppError {
NotFound(String),
DatabaseError(sqlx::Error),
ValidationError(String),
}
// Convert errors into HTTP responses
impl IntoResponse for AppError {
fn into_response(self) -> Response {
let (status, message) = match self {
AppError::NotFound(msg) => (
StatusCode::NOT_FOUND, msg
),
AppError::DatabaseError(_) => (
StatusCode::INTERNAL_SERVER_ERROR,
"Internal server error".to_string(),
),
AppError::ValidationError(msg) => (
StatusCode::BAD_REQUEST, msg
),
};
(status, Json(serde_json::json!({ "error": message })))
.into_response()
}
}
// Handlers return Result<T, AppError>
async fn get_user(
axum::extract::Path(id): axum::extract::Path<i64>,
) -> Result<Json<serde_json::Value>, AppError> {
if id <= 0 {
return Err(AppError::ValidationError(
"ID must be positive".to_string()
));
}
Ok(Json(serde_json::json!({ "id": id })))
}Axums Ansatz komponiert natürlich mit Rusts ?-Operator und dem Result-Typ. Actix Web erreicht dasselbe durch ResponseError, was die Implementierung sowohl von Display als auch ResponseError-Traits erfordert. Beide funktionieren, aber Axums Pattern fühlt sich idiomatischer für Rust-Entwickler an, die mit dem From-Trait und Error-Propagation vertraut sind.
Wann Actix Web die richtige Wahl ist
Actix Web bleibt in spezifischen Szenarien die richtige Wahl:
- Maximale Durchsatzanforderungen: Ad-Exchanges, Real-Time-Bidding, Analytics-Ingestion-Pipelines, wo 10-15% mehr req/s den Trade-off rechtfertigen.
- WebSocket-lastige Anwendungen: Actix Webs WebSocket-Unterstützung ist kampferprobt über mehr Produktions-Deployments. Axums WebSocket-Unterstützung (über
axum::extract::ws) funktioniert gut, hat aber eine kürzere Produktions-Historie. - Bestehende Actix-Web-Codebases: Migration von Actix Web 3.x auf 4.x ist unkompliziert. Ein Rewrite zu Axum bietet abnehmende Renditen für stabile Services.
- Team-Vertrautheit: Wenn das Team Actix Web bereits kennt, zahlt sich ein Framework-Wechsel für ergonomische Gewinne selten kurzfristig aus.
Wann Axum die richtige Wahl ist
Axum passt besser in diese Kontexte:
- Neue Projekte 2026: Die Tokio-Ökosystem-Ausrichtung (Tonic, Hyper, Tower) reduziert Integrations-Reibung.
- Gemischte gRPC- und HTTP-Services: Tower-Middleware funktioniert über beide Protokolle ohne Adaptierungsschichten.
- Teams neu in Rust: Axums typgesteuerte Extractors und Compile-Zeit-Fehlermeldungen bieten eine sanftere Lernkurve. Die
/{id}-Pfadsyntax (aligned mit OpenAPI) ist sofort vertraut. - Microservice-Architekturen: Towers
Service-Trait ermöglicht Middleware-Wiederverwendung über Services hinweg und reduziert Boilerplate.
Interview-Fragen: Actix Web und Axum für Backend-Rust-Positionen
Backend-Rust-Interview-Fragen decken zunehmend Web-Framework-Wissen ab. Diese Fragen erscheinen in Senior-Backend- und Systems-Engineering-Interviews.
F: Erklären Sie den architektonischen Unterschied zwischen Actix Webs und Axums Runtime-Modellen.
Actix Web startet eine Single-Threaded-Tokio-Runtime pro CPU-Kern. Tasks werden an Threads gepinnt, was Work-Stealing-Overhead eliminiert. Axum läuft auf einer gemeinsamen Multi-Threaded-Tokio-Runtime mit Work-Stealing. Actix Webs Modell reduziert Cache-Line-Contention unter hoher Last und produziert höheren Durchsatz. Axums Modell vereinfacht Shared-State-Management, da alle Tasks eine Runtime teilen.
F: Wie beeinflusst Axum 0.8s Entfernung von #[async_trait] benutzerdefinierte Extractors?
Axum 0.8 nutzt Rusts native return-position impl Trait in Traits (stabilisiert Ende 2023). Benutzerdefinierte Extractors, die FromRequestParts oder FromRequest implementieren, definieren jetzt async-Methoden direkt ohne das #[async_trait]-Attribut. Dies eliminiert Heap-Allokationen von Box<dyn Future> und verbessert Compile-Zeiten. Bestehende Extractors erfordern das Entfernen des Makros und Anpassungen der Trait-Implementierungen.
F: Beschreiben Sie, wie sich Tower-Middleware von Actix-Web-Middleware unterscheidet.
Tower definiert einen generischen Service<Request>-Trait, der protokoll-agnostisch ist. Ein Tower-Timeout-Layer funktioniert mit HTTP (Axum), gRPC (Tonic) und jedem benutzerdefinierten Protokoll. Actix Webs Middleware verwendet Transform- und Service-Traits, die spezifisch für sein Framework sind. Die praktische Auswirkung: Axum-Middleware ist im Tower-Ökosystem wiederverwendbar; Actix-Web-Middleware ist framework-spezifisch.
F: Wie funktioniert SQLx Compile-Zeit-Query-Validierung, und was sind die Trade-offs?
SQLx' query_as!-Makro verbindet sich während der Kompilierung mit einer Live-PostgreSQL-Datenbank. Es validiert SQL-Syntax, Spaltennamen, Typen und Tabellenexistenz. Der Trade-off: Der Build erfordert Datenbankzugriff, was CI-Pipelines kompliziert. SQLx stellt sqlx prepare bereit, um Offline-Query-Metadaten zu generieren und Validierungsergebnisse in einem .sqlx-Verzeichnis zu cachen, das der Versionskontrolle übergeben wird.
F: Wann wäre die Wahl von Actix Web gegenüber Axum die technisch korrekte Entscheidung?
Actix Web ist korrekt, wenn anhaltender Durchsatz die primäre Einschränkung ist: Ad-Serving, Real-Time-Analytics-Ingestion oder High-Frequency-Trading-Gateways. Das Pinned-Thread-Runtime-Modell eliminiert Work-Stealing-Overhead und produziert 10-15% höhere req/s unter Last. Axum ist korrekt, wenn Komposierbarkeit mit dem Tokio-Ökosystem mehr zählt als marginale Durchsatzgewinne, besonders in Microservice-Architekturen mit HTTP und gRPC.
Kandidaten behaupten oft, ein Framework sei universell besser. Starke Antworten erkennen den Trade-off an: Actix Web optimiert für Durchsatz, Axum optimiert für Ökosystem-Komposierbarkeit. Die richtige Wahl hängt von den Systemeinschränkungen ab, nicht von persönlicher Präferenz.
Quellen
- TechEmpower Framework Benchmarks Round 23 (Januar 2026): Benchmark-Daten für JSON-, Plaintext- und Datenbank-Tests
- Axum 0.8.9 Release Notes: WebSocket-Subprotokoll-Auswahl, minimale Rust-Version 1.80
- Actix Web 4.14.0 Release (Juni 2026): Route-Middleware-Validierung, IPv6-Dual-Stack-Unterstützung, h1_write_buffer_size
Wichtige Erkenntnisse für Rust-Webentwicklung 2026
- Actix Web 4.14 liefert 10-15% höheren Durchsatz durch sein Pinned-Thread-Runtime-Modell und ist die richtige Wahl für latenz-sensitive, hochdurchsatz-Services
- Axum 0.8 bietet bessere Ergonomie mit nativen async-Traits,
/{id}-Pfadsyntax und voller Tower-Middleware-Kompatibilität über HTTP und gRPC - Beide Frameworks verwenden dieselbe Datenbankschicht (SQLx mit Compile-Zeit-Validierung), daher beeinflusst die Wahl nicht die Datenzugriffsmuster
- Für neue Rust-Webprojekte 2026 ohne extreme Durchsatzanforderungen reduziert Axums Ökosystem-Ausrichtung mit Tokio, Tonic und Tower die langfristigen Wartungskosten
- Interview-Fragen zu diesem Thema testen das Verständnis von Runtime-Modellen, Middleware-Architektur und Trade-off-Reasoning, nicht Framework-Präferenz
- Vorbereitung auf Rust-Interviews erfordert das Verständnis der architektonischen Entscheidungen beider Frameworks, nicht nur der API-Syntax
Fang an zu üben!
Teste dein Wissen mit unseren Interview-Simulatoren und technischen Tests.
Findest du den Bug in Rust?
Ein echter Codeausschnitt, ein versteckter Bug, ein Versuch pro Tag. Zum Ausprobieren ohne Konto.

Geschrieben von
Anthony Fillion-MailletGründer von SharpSkill
Seit über 10 Jahren Fullstack-Entwickler. Er leitet SharpSkill und verantwortet alles, was hier erscheint.
Aktualisiert am 22. August 2026
Tags
Teilen
Verwandte Artikel

Rust und SQLx 2026: Compile-Time geprüfte Queries und Interview-Fragen
Ein umfassender Leitfaden zu SQLx 0.9 in Rust mit Compile-Time Query-Validierung, der neuen sqlx.toml Konfiguration und praxisrelevanten Interview-Fragen für Rust-Entwickler.

Rust lernen 2026: Bootcamp-Vergleich und Ressourcen für das Selbststudium
Umfassender Vergleich von Rust-Bootcamps und Selbststudium-Ressourcen in 2026. Entdecken Sie die besten Wege, Rust zu meistern - von strukturierten Kursen bis hin zu kostenlosen Online-Materialien.

Rust Lifetimes verstehen: Annotationen, Elision und Interview-Fragen 2026
Ein umfassender Leitfaden zu Rust Lifetimes: von grundlegenden Konzepten über Lifetime-Annotationen bis hin zu Elision-Regeln und häufigen Interview-Fragen für Rust-Entwickler.