Expand description
Server-Timing header middleware — surface per-request stage
durations to the browser DevTools “Network” panel. See
server_timing::ServerTimingLayer + server_timing::Timings.
Server-Timing header middleware — surface per-request stage
durations to the browser DevTools “Network → Timing” panel.
See the W3C Server-Timing spec. Chrome and Firefox both render the values in DevTools natively, making this the lowest-friction way to measure where time goes per request.
§Quick start
ⓘ
use rustango::server_timing::{ServerTimingLayer, ServerTimingRouterExt, Timings};
use axum::Extension;
let app = axum::Router::new()
.route("/posts", axum::routing::get(list_posts))
.server_timing(ServerTimingLayer::new());
async fn list_posts(Extension(t): Extension<Timings>) -> Json<Vec<Post>> {
t.measure("db");
let posts = load_posts().await;
t.measure("render");
let body = Json(posts);
t.finish();
body
}Resulting response header:
Server-Timing: total;dur=18.4, db;dur=12.1, render;dur=4.2§What’s measured automatically
total— the full request lifetime (start of middleware to response generation), always emitted.- Anything you
t.measure(name)in a handler.
§Caveats
- The header value is built from per-request mutable state; durations
are recorded in the order you call
measure. Two consecutivemeasure("db")calls overwrite each other (last one wins). - Browsers cap header size — keep entry counts modest (<20).
- Not intended for production tracing — use OpenTelemetry for distributed propagation. This is for “what’s slow in the browser right now?” debugging.
Structs§
- Server
Timing Layer - Timings
- Per-request timing recorder. Cheap to clone — internal
Arc<Mutex>.