Skip to main content
Extractor for accessing shared application state. State is global to a router and shared across all requests. It’s the recommended way to share things like database connection pools, API clients, and configuration.

Type signature

Basic usage

With Router

State must implement Clone since it’s cloned for each request. Use Arc for expensive-to-clone types.

With MethodRouter

With Handler

Extractor ordering

State is an extractor, so it must appear before any body extractors (like Json, Form, String, etc.) in your handler signature.

Combining routers

When combining routers with Router::nest or Router::merge, they must have the same state type:

Explicit state types

When composing routers in separate functions, you may need to annotate the state type:

Substates

You can extract “substates” using FromRef to provide different state to different parts of your app:
You can also derive FromRef:

Shared mutable state

Since state is cloned for each request, you can’t directly get a mutable reference. Use Arc<Mutex<_>> or similar:
Holding a locked std::sync::Mutex across .await points will result in !Send futures which are incompatible with axum. Use tokio::sync::Mutex if you need to hold a mutex across .await points.

State vs Extension

For global application state shared across all requests, prefer State because:
  • Type-safe: The state type is part of the router’s type
  • Compile-time checked: Wrong state types are caught at compile time
  • Better error messages
Use Extension for request-derived data like authorization info or per-request context.