# Rust para a Web: Actix Web vs Axum - Comparativo e Perguntas de Entrevista 2026 > Comparativo prático de Actix Web 4.13 e Axum 0.8 para desenvolvimento web com Rust em 2026. Arquitetura, performance, experiência de desenvolvimento e perguntas de entrevista para vagas backend Rust. - Published: 2026-05-27 - Updated: 2026-05-27 - Author: SharpSkill - Tags: rust, actix-web, axum, web-framework, backend, comparison - Reading time: 10 min --- A adoção de frameworks web em Rust acelerou significativamente em 2026, e dois frameworks dominam os deploys em produção: [Actix Web](https://actix.rs/) 4.13 e [Axum](https://github.com/tokio-rs/axum) 0.8. A escolha entre eles afeta tudo, desde a integração de novos membros da equipe até a vazão em produção, e a pergunta aparece com frequência em entrevistas técnicas para posições backend em Rust. > **Framework de decisão rápida** > > Actix Web 4.13 lidera em vazão bruta (10-15% mais requisições/segundo sob carga pesada). Axum 0.8 oferece melhor ergonomia através de traits async nativos, composabilidade de middlewares Tower e integração mais estreita com o Tokio. Para a maioria das equipes iniciando um novo projeto em 2026, Axum é a escolha pragmática padrão, a menos que requisitos extremos de performance ditem o contrário. ## Diferenças arquiteturais entre Actix Web e Axum A divergência arquitetural entre esses dois frameworks explica a maioria dos trade-offs em performance e ergonomia. Actix Web instancia N runtimes [Tokio](https://tokio.rs/) single-threaded, um por núcleo físico. As tasks são fixadas às threads sem migração entre elas. Isso elimina o overhead do work-stealing e o cache-line bouncing, o que explica a vantagem consistente de vazão sob carga sustentada. Axum roda em um único runtime Tokio multi-threaded com work-stealing. A equipe do Tokio construiu o Axum especificamente para demonstrar as capacidades do runtime, então cada decisão de design otimiza a composabilidade com o ecossistema Tokio mais amplo. Os handlers são funções async simples, e os middlewares utilizam o trait `Service` do [Tower](https://github.com/tower-rs/tower). ```rust // actix_hello.rs - Actix Web minimal server 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 } ``` ```rust // axum_hello.rs - Axum minimal server use axum::{Router, Json, routing::get}; use serde_json::{json, Value}; async fn health() -> Json { 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(); } ``` Ambos os exemplos compilam e executam, mas as diferenças já são visíveis. Actix Web usa sua própria macro `#[actix_web::main]` e retorna `std::io::Result`. Axum usa o padrão `#[tokio::main]` e constrói rotas através de uma struct `Router`. O handler do Axum retorna um extractor tipado (`Json`) em vez de construir um `HttpResponse` manualmente. ## Benchmarks de performance: Actix Web 4.13 vs Axum 0.8 Dados de benchmark do [TechEmpower Round 22](https://www.techempower.com/benchmarks/) e testes reproduzíveis da comunidade mostram um padrão consistente. | Métrica | Actix Web 4.13 | Axum 0.8.9 | |--------|---------------|-------------| | Serialização JSON (req/s) | ~720.000 | ~640.000 | | Texto puro (req/s) | ~980.000 | ~870.000 | | Query BD única (req/s) | ~180.000 | ~170.000 | | Uso de memória (hello world) | ~8 MB | ~6 MB | | Latência P99 (JSON) | 1,2 ms | 1,4 ms | Actix Web mantém uma vantagem de vazão de 10-15% em todas as categorias. Axum utiliza ligeiramente menos memória devido ao runtime Tokio compartilhado. Para contextualizar, ambos os frameworks superam o servidor HTTP da biblioteca padrão de Go em 2-3x e o Node.js em 5-8x no mesmo hardware. A diferença de performance importa para ad serving, pipelines de analytics em tempo real e gateways de trading de alta frequência. Para uma API REST típica servindo 10.000 requisições/segundo, ambos os frameworks estão muito além do gargalo, que será o banco de dados ou chamadas a serviços externos. ## Extractors e tratamento de requisições comparados Extractors definem como os frameworks fazem parsing das requisições de entrada. Axum 0.8 trouxe melhorias significativas ao remover `#[async_trait]` em favor de traits async nativos e introduzir `OptionalFromRequestParts` para melhor tratamento de `Option`. ```rust // axum_extractors.rs - Axum 0.8 extractor pattern use axum::{ extract::{Path, Query, State, Json}, routing::get, Router, }; use serde::Deserialize; use std::sync::Arc; #[derive(Deserialize)] struct Pagination { page: Option, per_page: Option, } struct AppState { db_pool: sqlx::PgPool, } async fn get_user( State(state): State>, Path(user_id): Path, Query(pagination): Query, ) -> Json { let page = pagination.page.unwrap_or(1); Json(serde_json::json!({ "user_id": user_id, "page": page })) } ``` ```rust // actix_extractors.rs - Actix Web extractor pattern use actix_web::{web, HttpResponse}; use serde::Deserialize; #[derive(Deserialize)] struct Pagination { page: Option, per_page: Option, } struct AppState { db_pool: sqlx::PgPool, } async fn get_user( state: web::Data, path: web::Path, query: web::Query, ) -> 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 })) } ``` Os extractors do Axum usam desestruturação de tupla diretamente nos parâmetros da função. Actix Web encapsula tudo em `web::Path`, `web::Query`, etc., exigindo chamadas `.into_inner()`. Ambas as abordagens são type-safe em tempo de compilação, mas a do Axum se lê de forma mais natural. > **Mudança importante no Axum 0.8** > > Os parâmetros de rota mudaram da sintaxe `/:id` para `/{id}` no Axum 0.8 (via matchit 0.8). Isso se alinha com a sintaxe de paths do OpenAPI. O escape usa chaves duplas: `{{` para um `{` literal. ## Arquitetura de middlewares: Tower vs Actix Middleware A composição de middlewares é onde a diferença arquitetural produz o maior impacto prático. Axum utiliza os traits `Service` e `Layer` do Tower. Qualquer middleware compatível com Tower funciona com Axum, incluindo rate limiters, tracing, compressão e camadas de autenticação construídas para outros serviços baseados em Tower. Essa composabilidade se estende além do HTTP; o mesmo middleware pode envolver serviços gRPC via Tonic. ```rust // axum_middleware.rs - Tower middleware composition use axum::{ Router, middleware, routing::get, extract::Request, response::Response, }; use tower_http::{ cors::CorsLayer, compression::CompressionLayer, trace::TraceLayer, }; use std::time::Instant; 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 usa seu próprio sistema de middleware com os traits `Transform` e `Service` (não os do Tower). Middlewares do amplo ecossistema Tower requerem adaptadores ou reescrita. Para equipes já investidas no ecossistema Tower via Tonic (gRPC) ou Hyper, o middleware do Axum é uma vantagem significativa. Para equipes construindo um serviço HTTP standalone, o sistema de middleware do Actix Web é igualmente capaz, apenas não é intercambiável. ## Integração com banco de dados usando SQLx Ambos os frameworks se integram bem com [SQLx](https://github.com/launchbadge/sqlx), o toolkit SQL async-first que valida queries em tempo de compilação. O padrão de integração difere ligeiramente. ```rust // shared_db.rs - SQLx with compile-time query validation use sqlx::PgPool; #[derive(sqlx::FromRow, serde::Serialize)] struct User { id: i64, email: String, created_at: chrono::NaiveDateTime, } async fn find_user_by_email( pool: &PgPool, email: &str, ) -> Result, sqlx::Error> { sqlx::query_as!( User, "SELECT id, email, created_at FROM users WHERE email = $1", email ) .fetch_optional(pool) .await } ``` A camada de banco de dados permanece idêntica independentemente do framework escolhido. A macro `query_as!` do SQLx se conecta a um banco de dados ativo em tempo de compilação e valida nomes de colunas, tipos e existência de tabelas. Um erro de digitação no nome de uma coluna produz um erro de compilação, não uma falha em produção. ## Padrões de tratamento de erros comparados O tratamento de erros revela filosofias de design diferentes. Actix Web usa implementações do trait `ResponseError`. Axum se baseia em `IntoResponse` combinado com o tipo `Result`. ```rust // axum_errors.rs - Axum error handling with IntoResponse use axum::{ http::StatusCode, response::{IntoResponse, Response}, Json, }; enum AppError { NotFound(String), DatabaseError(sqlx::Error), ValidationError(String), } 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() } } async fn get_user( axum::extract::Path(id): axum::extract::Path, ) -> Result, AppError> { if id <= 0 { return Err(AppError::ValidationError( "ID must be positive".to_string() )); } Ok(Json(serde_json::json!({ "id": id }))) } ``` A abordagem do Axum se compõe naturalmente com o operador `?` do Rust e o tipo `Result`. Actix Web alcança o mesmo através de `ResponseError`, que exige a implementação dos traits `Display` e `ResponseError`. Ambos funcionam, mas o padrão do Axum é mais idiomático para desenvolvedores Rust acostumados ao trait `From` e à propagação de erros. ## Quando escolher Actix Web em vez de Axum Actix Web continua sendo a escolha certa em cenários específicos: - **Requisitos de vazão máxima**: Ad exchanges, leilões em tempo real, pipelines de ingestão de analytics onde 10-15% mais de req/s justificam o trade-off. - **Aplicações com uso intensivo de WebSocket**: O suporte WebSocket do Actix Web é battle-tested em mais deploys de produção. O suporte WebSocket do Axum (via `axum::extract::ws`) funciona bem, mas tem um histórico de produção mais curto. - **Codebases Actix Web existentes**: A migração do Actix Web 3.x para 4.x é direta. Reescrever para Axum oferece retornos decrescentes para serviços estáveis. - **Familiaridade da equipe**: Se a equipe já conhece Actix Web, trocar de framework por ganhos ergonômicos raramente compensa a curto prazo. ## Quando escolher Axum em vez de Actix Web Axum se encaixa melhor nestes contextos: - **Novos projetos em 2026**: O alinhamento com o [ecossistema Tokio](https://tokio.rs/) (Tonic, Hyper, Tower) reduz a fricção de integração. - **Serviços mistos gRPC e HTTP**: Middlewares Tower funcionam em ambos os protocolos sem camadas de adaptação. - **Equipes novas em Rust**: Os extractors tipados do Axum e as mensagens de erro em compilação oferecem uma curva de aprendizado mais suave. A sintaxe `/{id}` para rotas (alinhada com OpenAPI) é imediatamente familiar. - **Arquiteturas de microsserviços**: O trait `Service` do Tower permite a reutilização de middlewares entre serviços, reduzindo boilerplate. ## Perguntas de entrevista: Actix Web e Axum para vagas backend Rust As [perguntas de entrevista backend Rust](/technologies/rust) cobrem cada vez mais o conhecimento sobre frameworks web. Essas perguntas aparecem em entrevistas para vagas de engenharia backend e de sistemas senior. **P: Explicar a diferença arquitetural entre os modelos de runtime do Actix Web e do Axum.** Actix Web instancia um runtime Tokio single-threaded por núcleo de CPU. As tasks são fixadas às threads, eliminando o overhead do work-stealing. Axum roda em um runtime Tokio multi-threaded compartilhado com work-stealing. O modelo do Actix Web reduz a contenção de cache-line sob carga pesada, produzindo maior vazão. O modelo do Axum simplifica o gerenciamento de estado compartilhado, já que todas as tasks compartilham um único runtime. **P: Como a remoção de `#[async_trait]` no Axum 0.8 afeta os extractors personalizados?** Axum 0.8 aproveita os impl Trait nativos em posição de retorno em traits do Rust (estabilizados no final de 2023). Extractors personalizados que implementam `FromRequestParts` ou `FromRequest` agora definem métodos async diretamente sem o atributo `#[async_trait]`. Isso elimina alocações no heap de `Box` e melhora os tempos de compilação. Extractors existentes requerem a remoção da macro e o ajuste das implementações de traits. **P: Descrever como o middleware Tower difere do middleware do Actix Web.** Tower define um trait genérico `Service` que é agnóstico de protocolo. Uma camada de timeout do Tower funciona com HTTP (Axum), gRPC (Tonic) e qualquer protocolo customizado. O middleware do Actix Web usa os traits `Transform` e `Service` específicos do seu framework. O impacto prático: middleware do Axum é reutilizável no ecossistema Tower; middleware do Actix Web é específico do framework. **P: Como funciona a [validação de queries em tempo de compilação do SQLx](/technologies/rust/interview-questions/cargo-ecosystem) e quais são seus trade-offs?** A macro `query_as!` do SQLx se conecta a um banco de dados PostgreSQL ativo durante a compilação. Ela valida a sintaxe SQL, nomes de colunas, tipos e existência de tabelas. O trade-off: o build requer acesso ao banco de dados, o que complica os pipelines de CI. O SQLx fornece `sqlx prepare` para gerar metadados de query offline, fazendo cache dos resultados de validação em um diretório `.sqlx` commitado no controle de versão. **P: Quando escolher Actix Web em vez de Axum seria a decisão tecnicamente correta?** Actix Web é a escolha certa quando a vazão sustentada é a restrição principal: ad serving, ingestão de analytics em tempo real ou gateways de trading de alta frequência. O modelo de runtime com threads fixas elimina o overhead do work-stealing, produzindo 10-15% mais req/s sob carga. Axum é a escolha certa quando a composabilidade com o [ecossistema Tokio](/technologies/rust/interview-questions/async-await) importa mais que ganhos marginais de vazão, particularmente em arquiteturas de microsserviços que usam tanto HTTP quanto gRPC. > **Erro comum em entrevistas** > > Candidatos frequentemente afirmam que um framework é universalmente superior. Respostas sólidas reconhecem o trade-off: Actix Web otimiza a vazão, Axum otimiza a composabilidade com o ecossistema. A escolha certa depende das restrições do sistema, não da preferência pessoal. ## Conclusão - Actix Web 4.13 entrega 10-15% mais de vazão através do seu modelo de runtime com threads fixas, tornando-o a escolha certa para serviços de alta performance sensíveis a latência - Axum 0.8 proporciona melhor ergonomia com traits async nativos, sintaxe `/{id}` para rotas e compatibilidade completa com middlewares Tower em HTTP e gRPC - Ambos os frameworks usam a mesma camada de banco de dados (SQLx com validação em compilação), então a escolha não afeta os padrões de acesso a dados - Para novos projetos web em Rust em 2026 sem requisitos extremos de vazão, o alinhamento do Axum com o ecossistema Tokio, Tonic e Tower reduz o custo de manutenção a longo prazo - As perguntas de entrevista sobre esse tema testam a compreensão de modelos de runtime, arquitetura de middlewares e raciocínio sobre trade-offs, não a preferência por um framework - [Preparar-se para entrevistas de Rust](/blog/rust/rust-interview-questions) requer compreender as decisões arquiteturais de ambos os frameworks, não apenas a sintaxe de suas APIs --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/pt/blog/rust/rust-actix-web-vs-axum-comparison