Transports
Every Tako transport — HTTP, HTTP/3, WebSocket, WebTransport, SSE, gRPC, raw sockets, and PROXY protocol — with runtime and feature-flag support.
Tako runs the same Router across many transports. A single ServerConfig
flows into every one of them, so header read timeouts, keep-alive, drain
timeout, max connections, H2 caps, H3 caps, and the PROXY read timeout are all
sourced from one struct. You pick which transport a listener serves at spawn
time — the routing, middleware, and observability model does not change.
Transport matrix
| Transport | Tokio | Compio | Feature flag |
|---|---|---|---|
| HTTP/1.1 | yes | yes | default |
| HTTP/2 | yes | yes | http2 |
| HTTP/3 (QUIC) | yes | yes | http3 |
| TLS (rustls) | yes | yes | tls / compio-tls |
| WebSocket | yes | yes | ws |
| WebTransport | yes | yes | webtransport |
| SSE | yes | yes | sse |
| gRPC (unary and streaming) | yes | yes | grpc |
| Raw TCP | yes | yes | default |
| Raw UDP | yes | yes | udp |
| Unix sockets | yes | yes | default (unix only) |
| PROXY protocol v1/v2 | yes | yes | proxy-protocol |
Every transport runs on both runtimes: HTTP/2 over TLS, cleartext h2c, HTTP/3,
WebTransport, raw TCP/UDP, Unix sockets, PROXY protocol, gRPC handlers, WebSocket,
and SSE. Only the raw QUIC session helper behind webtransport is Tokio-only. See Runtimes and the
feature reference.
How transports attach to a server
Use Server::builder() on Tokio or CompioServer::builder() on Compio.
The try_spawn_* methods validate configuration before returning a handle;
handle.result().await reports asynchronous startup and serving errors.
shutdown(timeout).await stops acceptance and bounds the drain. Raw socket
and per-thread servers keep their own helper functions.
use std::time::Duration;
use tako::{Server, ServerConfig};
use tako::router::Router;
use tokio::net::TcpListener;
#[tokio::main]
async fn main() -> Result<(), tako::types::BoxError> {
let listener = TcpListener::bind("127.0.0.1:8080").await?;
let mut router = Router::new();
router.route(tako::Method::GET, "/", || async { "hi" });
let server = Server::builder()
.config(ServerConfig {
drain_timeout: Duration::from_secs(30),
max_connections: Some(10_000),
..ServerConfig::default()
})
.build();
let handle = server.try_spawn_http(listener, router)?;
tako::shutdown_signal().await?;
handle.shutdown(Duration::from_secs(30)).await;
Ok(())
}The handle is runtime-agnostic — both Server (tokio) and CompioServer
(compio) return the same ServerHandle type.
Per-transport pages
- HTTP — HTTP/1.1, HTTP/2 cleartext (h2c), and HTTP/2 over TLS via ALPN.
- HTTP/3 — HTTP/3 over QUIC on either runtime; TLS required.
- WebSocket — RFC-6455 upgrade inside an HTTP handler, on both runtimes.
- WebTransport — W3C WebTransport sessions on the
HTTP/3 server, reachable from browsers; requires the
webtransportfeature. - SSE — Server-Sent Events; see the Streams primitives.
- gRPC — unary and streaming RPCs with protobuf.
- TCP / UDP / Unix — raw byte transports and Unix domain sockets.
- PROXY protocol — v1/v2 header parsing behind an L4 load balancer.
WebSocket, SSE, and the HTTP handler
WebSocket and SSE live inside HTTP handlers. WebSocketUpgrade::new(req, handler)
performs an HTTP/1.1 Upgrade; it works over plain HTTP/1.1 and TLS negotiated as HTTP/1.1.
HTTP/2 Extended CONNECT is not implemented. tako::sse::Sse wraps a stream in a
text/event-stream response and can use any supported HTTP transport.
Raw transports
spawn_tcp_raw / tako::server_tcp::serve_tcp and spawn_udp_raw /
tako::server_udp::serve_udp skip the HTTP layer entirely. The handler closure
receives each accepted stream (TCP) or datagram (UDP), so you can implement a
custom line protocol, relay, or proxy. These do not use a Router. See
TCP / UDP / Unix.
Last updated on