# 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](/docs/concepts/runtimes) and the
[feature reference](/docs/reference/features).

## 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.

```rust
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](/docs/transports/http) — HTTP/1.1, HTTP/2 cleartext (h2c), and HTTP/2
  over TLS via ALPN.
* [HTTP/3](/docs/transports/http3) — HTTP/3 over QUIC on either runtime; TLS required.
* [WebSocket](/docs/transports/websocket) — RFC-6455 upgrade inside an HTTP
  handler, on both runtimes.
* [WebTransport](/docs/transports/webtransport) — W3C WebTransport sessions on the
  HTTP/3 server, reachable from browsers; requires the `webtransport` feature.
* [SSE](/docs/streams) — Server-Sent Events; see the Streams primitives.
* [gRPC](/docs/transports/grpc) — unary and streaming RPCs with protobuf.
* [TCP / UDP / Unix](/docs/transports/tcp-udp-unix) — raw byte transports and
  Unix domain sockets.
* [PROXY protocol](/docs/transports/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](/docs/transports/tcp-udp-unix).

Source: https://tako.rust-dd.com/docs/transports