rgoussu@goussu: ~/library/rust/web-frameworks
~/library/rust/web-frameworks cat actix-web.md

Actix Web deep dive

# The own-stack incumbent — actix-http engine, App/scope composition, extractors, its Transform middleware model, the actor heritage, and where it beats axum.

Conceptsaved 2026-08-09 #rust#web#actix#http#performance

Overview

Actix Web is Rust's pre-substrate incumbent: started 2017 on the actix actor framework, rebuilt over the years into a self-contained web stack with its own HTTP engine (actix-http), its own middleware model, and years at the top of the TechEmpower benchmarks. The actor heritage survives only in the name and in actix-the-crate being an optional companion — modern Actix Web is ordinary async Rust on Tokio. It is the "Gin of Rust": mature, fast, batteries included, and running its own stack where axum rides the shared one.

Key points

  • Own engine, own contracts: actix-http instead of hyper, App/HttpServer instead of a tower stack — tower-http middleware doesn't apply; the actix-web ecosystem (actix-cors, actix-session, actix-identity, actix-web-httpauth) fills the same needs in-house.
  • Familiar handler shape: async fns with extractors (web::Path, web::Query, web::Json, web::Data<T> for state) and Responder returns — API-compatible in spirit with axum, different types throughout.
  • Routing via macros or builders: #[get("/users/{id}")] attributes or web::resource("/users/{id}").route(web::get().to(show)); web::scope for prefix grouping.
  • Middleware is the Transform trait: wrap-service factories — more boilerplate than tower layers; middleware::from_fn (like axum's) covers the easy cases now.
  • The runtime nuance: runs on Tokio but historically via actix-rt with a multi-threaded, non-work-stealing model — one single-threaded server instance per core, connections pinned to a worker. That architecture (no Send bounds on handlers' futures, per-worker App state factories) is why the benchmarks are good, and the main mental-model difference from axum.
  • Performance: consistently at or near the top for Rust frameworks; the honest summary is that axum closed most of the gap and both saturate real-world workloads — choose on ecosystem shape, not benchmark deltas.
  • Ecosystem posture: the 2020 maintainer crisis (unsafe-code controversy, original author's departure) is history — a community team has shipped steadily since; the actor framework actix remains for stateful in-process components (WebSocket session registries are the classic use — see WebSockets in Rust).

Examples

#[get("/users/{id}")]
async fn show_user(
    data: web::Data<AppState>,
    path: web::Path<Uuid>,
) -> Result<web::Json<User>, ApiError> {
    let user = users::find(&data.pool, *path).await?;
    Ok(web::Json(user))
}

HttpServer::new(move || {
    App::new()
        .app_data(web::Data::new(state.clone()))
        .wrap(middleware::Logger::default())
        .service(show_user)
})
.bind(("0.0.0.0", 8080))?
.run()
.await?;

Related