salvo-compression
Salvo Response Compression
[dependencies]
salvo = { version = "0.89.3", features = ["compression"] }
Basic usage
Compression::new() enables all four algorithms (brotli, zstd, gzip, deflate) at Default level, with min_length = 1024 and a default text/* content-type allowlist.
use salvo::prelude::*;
use salvo::compression::Compression;
#[handler]
async fn body() -> String {
"lorem ipsum ".repeat(200)
}
#[tokio::main]
async fn main() {
let router = Router::new().hoop(Compression::new()).get(body);
let acceptor = TcpListener::new("0.0.0.0:8080").bind().await;
Server::new(acceptor).serve(router).await;
}
CompressionLevel
use salvo::compression::CompressionLevel;
CompressionLevel::Fastest // speed > ratio
CompressionLevel::Default // balanced
CompressionLevel::Minsize // best ratio, slowest (NOT `Best`)
CompressionLevel::Precise(6) // algo-specific level
GOTCHA: the variant is Minsize, not Best.
Selecting algorithms
Enable/disable by name (each returns Self):
use salvo::compression::{Compression, CompressionLevel};
// Only gzip
let only_gzip = Compression::new()
.disable_all()
.enable_gzip(CompressionLevel::Default);
// Gzip + brotli, different levels
let mixed = Compression::new()
.disable_all()
.enable_brotli(CompressionLevel::Minsize)
.enable_gzip(CompressionLevel::Fastest);
Available: enable_gzip, enable_brotli, enable_zstd, enable_deflate (plus matching disable_*).
min_length
Compression::new().min_length(2048); // skip bodies smaller than 2KB
content_types
GOTCHA: content_types takes &[mime::Mime], NOT &[&str]. mime is re-exported at salvo::http::mime.
use salvo::compression::Compression;
use salvo::http::mime;
let comp = Compression::new().content_types(&[
mime::TEXT_HTML,
mime::TEXT_CSS,
mime::APPLICATION_JSON,
mime::APPLICATION_JAVASCRIPT,
"image/svg+xml".parse().unwrap(),
]);
The default list already covers text/*, application/javascript, application/json, and image/svg+xml — only call content_types to restrict further.
Algorithm priority
By default, if the client accepts multiple encodings, the algorithm with the highest client q-value wins. Set force_priority(true) to use server preference order (brotli > zstd > gzip > deflate as inserted by new()).
Compression::new().force_priority(true);
Per-route compression
let static_comp = Compression::new()
.disable_all()
.enable_brotli(CompressionLevel::Minsize)
.enable_gzip(CompressionLevel::Minsize);
let api_comp = Compression::new()
.disable_all()
.enable_gzip(CompressionLevel::Fastest)
.min_length(256);
let router = Router::new()
.push(Router::with_path("static/{**path}").hoop(static_comp).get(StaticDir::new("./public")))
.push(Router::with_path("api/{**rest}").hoop(api_comp).get(api_handler));
Pre-compressed static assets
If you pre-compress files at build time (gzip -k9 bundle.js, brotli -k bundle.js), serve them with StaticDir which detects the pre-compressed variants automatically and serves them directly.
Related Skills
- salvo-static-files: serve pre-compressed files
- salvo-caching: combine with caching middleware
More from salvo-rs/salvo-skills
salvo-csrf
Implement CSRF (Cross-Site Request Forgery) protection using cookie or session storage. Use for protecting forms and state-changing endpoints.
16salvo-auth
Implement authentication and authorization using JWT, Basic Auth, or custom schemes. Use for securing API endpoints and user management.
15salvo-cors
Configure Cross-Origin Resource Sharing (CORS) and security headers. Use for APIs accessed from browsers on different domains.
15salvo-middleware
Implement middleware for authentication, logging, CORS, and request processing. Use for cross-cutting concerns and request/response modification.
15salvo-realtime
Implement real-time features using WebSocket and Server-Sent Events (SSE). Use for chat applications, live updates, notifications, and bidirectional communication.
15salvo-caching
Implement caching strategies for improved performance. Use for reducing database load and speeding up responses.
15