# tower-http: HTTP middleware that plugs into anything built on the http crate

> tower-http is a set of Tower middleware and utilities for HTTP clients and servers, built on the http crate so it works with hyper, axum, warp, tonic and anything else that speaks that interface. It covers request tracing, body compression and decompression, redirect following, and a longer list in the crate docs. It was extracted from an internal Embark Studios project, and the MSRV is Rust 1.65.

**tower-rs/tower-http** — HTTP specific Tower utilities.

- Repository: https://github.com/tower-rs/tower-http
- Stars: 924 · Forks: 236
- Language: Rust
- License: not declared
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/tower-rs-tower-http

## Compatibility comes from the http crate, not from a framework

The design decision that makes tower-http broadly useful is stated in one sentence in the README: middleware uses the http crate as the HTTP interface, so they are compatible with any library or framework that also uses http. Hyper is given as the example.

That is the difference between a framework extension and a middleware crate. A framework middleware is tied to that framework's request type, its router, its context. A tower-http middleware operates on the http crate's types, so the same compression layer can sit in an axum stack, a warp stack, a tonic stack or a hand-rolled hyper service.

The middleware follows the Tower model rather than inventing a new one, which means the composition rules are Tower's: layers wrap services, and the ordering of the stack is the ordering of the layers. That is a well understood convention for anyone who has used Tower, and the README points newcomers at the tower guides when they need help.

The project has a stated origin that explains the shape of the code. The middleware were originally extracted from one of EmbarkStudios internal projects, so what you get is a set of layers that survived production use at one company, reorganised as a public crate.

The scope is deliberately HTTP-specific. The README calls the crate HTTP specific Tower utilities and describes it as middleware and utilities for HTTP clients and servers. It is not a general purpose Tower toolbox, and it is not a web framework.

For anyone arriving from a different ecosystem, the tradeoff is real but not subtle. The compatibility you gain is with other Rust HTTP libraries, and you pay for it in the type gymnastics that the http crate's abstraction requires.

## Trace, Compression, Decompression and FollowRedirect

The README names four middleware as highlights, and they are worth reading as a set because they map onto the three things every HTTP stack eventually needs.

`Trace` adds high level logging of requests and responses. The detail that matters is that it supports both regular HTTP requests and gRPC, which is not a small addition, since gRPC frames its messages inside HTTP bodies and a naive logger produces unreadable output for it.

`Compression` and `Decompression` handle compressing and decompressing response bodies. Having both directions in one crate matters for a client that receives compressed responses and a server that sends them.

`FollowRedirect` automatically follows redirection responses, which removes a piece of hand-rolled logic from every client that was missing it.

And that is only the highlights. The README is explicit that the docs contain the complete list of middleware, so anything beyond these four has to be found in the crate documentation on docs.rs. That is a limitation of the README rather than of the crate, but it does mean you cannot make an adoption decision from the README alone. Middleware covering headers, timeouts, sensitive header masking, request ID propagation, compression content negotiation and CORS are the kind of thing such a crate usually carries, though this README does not enumerate them, and the crate docs are where you confirm what is actually there.

One design point visible in the naming: `Trace` is described as high level logging, which suggests it logs request and response summaries rather than byte level bodies. That is the useful default for a server, since bodies are where the sensitive data lives.

The middleware are usable in both directions. That the crate describes itself as middleware and utilities for HTTP clients and servers is not incidental wording, and it is why `FollowRedirect` sits comfortably next to `Compression` in the same list.

## Three key value store examples, one per framework

The examples directory is the best part of the repository for understanding how the middleware are meant to be used, and the README points at it in two places, once for how to use the middleware and once as a set of examples showing how to put everything together.

Three examples are named, and each one is a key/value store with an HTTP API built on a different stack. There is a warp based key/value store, an axum based key/value store, and a tonic based one with a gRPC API and client. The repository listing confirms all three directories exist, alongside an `examples/README.md` and one more example directory named custom-future-multiple-bodies, which points at a specific and genuinely awkward problem in the HTTP body domain.

The repetition of the same application across three frameworks is the point of the exercise. Same application, same middleware, different framework. It demonstrates that the compatibility claim in practice rather than in principle, and it gives you a working reference for whichever framework you already use.

The tonic example is the one to read if you are unsure about the gRPC claim in the `Trace` description, because it is the case where the HTTP layer and the RPC layer have to coexist.

The repository layout supports the same picture. It is a Cargo workspace with two members declared, the `tower-http` crate itself and a wildcard for `examples/*`, so every example is a workspace member and shares the dependency versions of the library. There is also a `test-files/` directory and a `deny.toml`, which is the configuration file used by cargo-deny to check dependency licences and advisories against a policy. For a crate that sits in the dependency tree of most Rust web services, having that policy file in the repository is a meaningful signal about how the project treats its own supply chain.

## Getting the crate and building the workspace

The crate is published on crates.io as tower-http, with the documentation on docs.rs and the source in the `tower-http/` directory of the repository. The README does not reproduce an installation snippet, so there is nothing here to copy for a Cargo.toml dependency line beyond the fact that the crate name is `tower-http`.

The workspace definition in the repository root shows how the crate and its examples fit together:

```toml
[workspace]
resolver = "2"
members = [
  "tower-http",
  "examples/*",
]
```

The wildcard member entry means every example directory is built as part of the workspace, which is why the examples in the README can be expected to compile against the current version of the library rather than a published release. Building the workspace therefore builds the examples too.

The minimum supported Rust version is stated as 1.65. That number is a floor, not a recommendation, and it has practical consequences. A crate with a low MSRV can be pulled into older projects without forcing a toolchain upgrade, which is exactly why tower-http is a common dependency in libraries rather than only in applications. It also means the crate avoids language features newer than 1.65, which constrains how some of the middleware are written.

Help is available in a few places. The README suggests the tower guides if you are new to tower, points to the examples in this repository for how to put everything together, and mentions the `#tower` Discord channel and opening an issue with your question. There is a contributing guide for people who want to contribute rather than just use the crate.

## Features and the optional dependency surface

A crate with many optional middleware has a feature flag story, and this README does not describe it. That is worth flagging because it directly affects how you depend on the crate.

The practical consequence is that adding `tower-http` to a Cargo.toml pulls in only what you enable. The highlights are named as separate items, `Trace`, `Compression`, `Decompression` and `FollowRedirect`, and a project that only wants logging should not be forced to compile compression backends it will never use. The exact flag names live in the crate documentation on docs.rs rather than in the README, so read them there before writing the dependency line, and check them against the version you pin.

This also matters for supply chain review. The crate sits under most Rust HTTP services, and the number of transitive dependencies it can bring in varies considerably with the feature set. A team doing a dependency audit will want to know which backends are compiled in, and the `deny.toml` in the repository root shows that the maintainers think about the same question for their own tree.

There is also a security dimension to picking middleware. `Trace` performs high level logging of requests and responses, and anything that logs HTTP traffic has to decide what to leave out. A logger that writes request bodies to disk can write credentials into your logs. The README does not describe any header masking or redaction behaviour for `Trace`, so if you enable it, you should verify what it writes before pointing it at production traffic.

The client side of the crate has the same consideration in reverse. `Decompression` and `FollowRedirect` sit in front of responses your service receives, and both change what the caller ends up with, silently and by design.

## When tower-http is the wrong crate

The clearest case is a project that is not built on Tower or on the http crate. The compatibility that makes tower-http valuable is the same property that makes it unusable in a Python service, a Go gateway or a Node application. There is nothing wrong with those stacks; there is simply no Tower layer to insert.

The second case is a project that has already solved these problems. Many Rust web frameworks ship their own tracing, compression and redirect handling, and adding tower-http on top of a framework that already provides them means two layers doing the same job, with two sets of configuration and one more place where a header can be modified twice. The examples are instructive here: each one builds a key/value store with a framework, and the middleware is added to it, which tells you the intended pattern is one framework plus tower-http layers, not two sources of the same feature.

The third case is a project that wants more than HTTP middleware. The crate does not give you a router, a body parser or an application skeleton. The examples exist precisely because you need something to mount the middleware on.

The fourth case is gRPC-only work. The crate supports gRPC for `Trace`, and the tonic example exists, but if your entire surface is gRPC and you have no HTTP concerns, the gRPC middleware from the ecosystem around tonic is a more direct fit than a general HTTP middleware crate.

One more constraint deserves plain statement. The crate version in the recent release history is 0.7.1, published on 2026-08-31, following 0.7.0 on 2026-06-15 and 0.6.11 on 2026-05-18. That is a pre-1.0 version line, and it means breaking changes are permitted by semver expectations. A crate this widely depended upon will be careful, but you should expect the API to move across minor versions and read the changelog when you bump.

## MIT terms, active development, and the question the metadata does not answer

The README states the project is licensed under the MIT license, pointing at the LICENSE file inside the `tower-http` directory. The contribution terms are stated separately and are worth noting: unless you explicitly state otherwise, any contribution intentionally submitted for inclusion is licensed as MIT, without any additional terms or conditions. That is the standard inbound licensing clause, and it means a company contributing code has not accidentally introduced a proprietary grant.

There is a small mismatch worth flagging. The repository licence field is not classified, so tooling will not report a licence identifier for the repository, while the README and the LICENSE file state MIT. In practice the LICENSE file is the authoritative text, but if your organisation's compliance tooling reads the repository licence field rather than the file, it may flag this project until you point it at the right path.

On maintenance, the last push was on 2026-10-17 and the release history shows work through August 2026, so the crate is being maintained and released.

What the README does not tell you is the compatibility policy. It states an MSRV of 1.65 but does not say whether that floor will move, nor how long each release line is supported, nor whether middleware will be deprecated in favour of something else. For a dependency of this weight in a service, that is the information you would want and the information you will have to get from the release notes and the issue tracker.

The community channels are the same ones the wider tower project uses, the `#tower` Discord channel, the tower guides for learning the middleware model, and GitHub issues on this repository.

## Conclusion

tower-http suits a Rust team that already builds HTTP services or clients on Tower, hyper, axum, warp or tonic and wants tracing, compression and redirect handling without writing those layers by hand, and it is the wrong choice if you are not already inside that ecosystem, since the middleware is built around the http and Tower traits rather than around a framework. Verify three things before you adopt it: that your Rust toolchain meets the MSRV of 1.65, that the middleware you need is enabled through the feature flags your build actually turns on, since the crate ships many optional modules, and that the licence situation is clear for your organisation, because the README states MIT and the contribution terms require contributions to be MIT as well, while the repository licence field is not classified.

## FAQ

### What is tower-http and what does it give me?

It is a set of Tower middleware and utilities for HTTP clients and servers. The README highlights `Trace` for high level request and response logging with gRPC support, `Compression` and `Decompression` for response bodies, and `FollowRedirect` for automatically following redirections.

### Is tower-http compatible with axum, warp and tonic?

Yes, because the middleware uses the http crate as its HTTP interface, so it works with any library or framework using that interface, hyper being the example given in the README. The examples folder contains a key/value store built with warp, one built with axum and one built with tonic.

### What is the minimum supported Rust version for tower-http?

The MSRV is Rust 1.65, stated in the README. The crate is published on crates.io as tower-http, with documentation on docs.rs.

### Can I use tower-http middleware with gRPC?

The `Trace` middleware supports both regular HTTP requests and gRPC, and the examples folder includes a key/value store with a gRPC API and client built with tonic.

### What licence is tower-http under?

The README states the project is licensed under the MIT license, pointing at the LICENSE file in the tower-http directory, and contributions are licensed as MIT unless you state otherwise. The repository licence field is not classified, so some compliance tooling may flag it until pointed at the LICENSE file.

## Sources

- [Issues](https://github.com/tower-rs/tower-http/issues)
- [README](https://github.com/tower-rs/tower-http/blob/main/README.md)
- [Releases](https://github.com/tower-rs/tower-http/releases)
- [tower-rs/tower-http on GitHub](https://github.com/tower-rs/tower-http)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/tower-rs-tower-http
