# tower-rs/tower: The Rust Crate Behind async fn(Request) -> Result<Response, Error>

> Tower is a library of modular middleware components for Rust networking clients and servers. It is small, protocol agnostic, and mostly useful once you accept its Service trait as the shape of your request handling.

**tower-rs/tower** — async fn(Request) -> Result<Response, Error>

- Repository: https://github.com/tower-rs/tower
- Website: https://docs.rs/tower
- Stars: 4,311 · Forks: 345
- Language: Rust
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/tower-rs-tower

## The problem Tower solves for Rust networking code

Every network client and server ends up needing the same handful of behaviours: retry a failed request, cap how long a call may take, limit how many calls run at once, balance across several backends. Written by hand, each of those behaviours gets entangled with the request logic, and reuse across two services means copying code or inventing an in-house abstraction. Tower's answer is to define one trait for anything that turns a request into a response and then express every one of those behaviours as a wrapper around it. The README describes the crate as "a library of modular and reusable components for building robust networking clients and servers", and the repository description gives the shape of the abstraction directly: async fn(Request) -> Result<Response, Error>.

The audience is Rust engineers writing infrastructure rather than application endpoints. If you are building an HTTP client library, a gRPC stack, or a proxy, you are the target user. If you are writing a single binary that makes one kind of outbound call, the abstraction earns its keep only when you need more than one of the layers. The README is explicit that the crate is protocol agnostic and designed around a request/response pattern, and equally explicit that a purely stream-based protocol may not be a good fit.

## How the Service trait and layers fit together

The repository is a Cargo workspace with four members: tower, tower-layer, tower-service and tower-test. That split is the architecture in miniature. tower-service holds the Service trait itself, the minimal contract. tower-layer holds the Layer trait, which describes how to wrap one service in another. tower is where the concrete middleware lives. tower-test provides test utilities for services.

Because Layer is separate from Service, a middleware author writes one wrapper type and gets composition for free: a timeout layer wrapping a retry layer wrapping a load balancer wrapping your actual service. Each layer only has to know how to build the next service, not what is underneath it. This is why the crate can stay protocol agnostic. It never sees your wire format, only the request and response types you parameterise the service with.

The workspace Cargo.toml shows the shared dependency set, including http, tokio, futures, tracing and pin-project-lite. The presence of http and tokio there, rather than in the README's description, is the honest signal about scope: the ecosystem Tower serves is the Tokio and http one, even though the core traits do not require either.

## Installing tower and writing a first layer

Tower is published on crates.io, and the README points new users at the guides directory in the repository for the basics. Add it to a project with cargo add. The current release line is 0.5.3, published on 2026-01-12.

```bash
cargo add tower
```

A first real use is wrapping a service so that calls are bounded in time. The exact builder names and feature flags for a given layer belong in the docs.rs page for 0.5.3, which the README links as the documentation. What you should expect after adding the dependency is a Service implementation you can pass to your client or server, with the middleware applied as an outer type rather than as code inside your handler.

The workspace pins a minimum supported Rust version of 1.64.0. If your toolchain is older, the build will fail before you reach any Tower-specific error, so it is worth checking that first.

```toml
[workspace]
members = ["tower", "tower-layer", "tower-service", "tower-test"]
```

The workspace manifest above is the repository's own, not something you copy into your project. It is useful because it tells you which crates you can depend on separately: if you only need the trait definitions, tower-service and tower-layer are the smaller dependencies, and the README states that those two are no_std compatible while tower itself is not.

## Where Tower is the wrong tool

The README names the first limitation itself: if your protocol is entirely stream based, Tower may not be a good fit. The request/response pattern is baked into the trait signature, so a protocol that is a continuous flow of bytes with no discrete request boundary has to be forced into a shape it does not have. You can do it, but you are paying for an abstraction that is fighting your problem.

The second constraint is no_std. The README states plainly that tower itself is not no_std compatible, while tower-layer and tower-service are. Embedded or kernel-adjacent work that needs the middleware layers cannot use the main crate.

The third is the MSRV policy. Tower keeps a rolling minimum of at least six months, meaning the minimum supported Rust version can move forward as long as the new compiler release is at least six months old. That is a reasonable policy, but it is a policy, not a guarantee that your pinned toolchain stays supported indefinitely. If you vendor dependencies for long-lived builds, the MSRV is a thing you will eventually have to chase.

Finally, the abstraction has a cost in type complexity. Deeply nested layers produce deeply nested types, which is why the workspace depends on pin-project-lite. Debugging a stack of five layers means reading a compiler error about five nested generic types. That is the trade for composition.

## Tower compared with hyper and the broader Rust HTTP stack

The clearest alternative in this space is hyper, and the difference is scope rather than quality. Hyper is an HTTP implementation: it parses requests, writes responses, manages connections. Tower is not an HTTP implementation at all. It is the middleware vocabulary that sits on top of one, which is why hyper and Tower are commonly used together rather than chosen between.

The practical difference shows up when you want retries or timeouts. With hyper alone you write that logic around your client call. With Tower you express it as a layer and reuse it, and the same layer works for a non-HTTP protocol if you implement Service for it. The cost is that you now depend on the Tower traits and their associated types, and your code has to be written in terms of them.

A second comparison is against writing your own trait. That is a genuinely reasonable choice for a single service, and it avoids the dependency entirely. What you lose is the existing layer implementations and the shared vocabulary: Tower's traits are the ones other crates in the ecosystem implement, so adopting them means third-party middleware composes with yours without adaptation.

## Maintenance, releases and the MIT licence

The repository is not archived, and the last push was on 2026-06-22. The most recent release is tower 0.5.3 from 2026-01-12, following 0.5.2 on 2024-12-11 and 0.5.1 on 2024-09-05. The gap between 0.5.1 and 0.5.2 was a little over a year, and the gap to 0.5.3 was roughly thirteen months. That cadence matters for planning: this is a crate whose API is stable enough that releases are infrequent, so you should not expect a rapid stream of patch releases to fix a problem you hit.

Upgrade cost is bounded by the 0.x version. Tower is pre-1.0, so a minor version bump can carry breaking changes, and the 0.5.x line is where those changes land. Pinning to a specific minor version and reading the changelog before moving is the ordinary discipline for a 0.x dependency.

The licence is MIT, stated in the README and present as a LICENSE file at the repository root. Contributions are licensed as MIT unless stated otherwise. MIT is permissive, which means the practical obligations are attribution and including the licence text; it does not impose copyleft on your own code. That is a description of the licence text, not legal advice, and if your organisation has a policy on dependency licences, the LICENSE file is the thing to hand to it.

## Conclusion

Adopt tower-rs/tower if you are building a Rust client or server around a request/response protocol and want retries, timeouts, load balancing and rate limiting as composable layers instead of hand-written code. Skip it if your protocol is entirely stream based, since the README says Tower may not be a good fit there, or if you need no_std in the top-level crate, which the README states is not supported. Before committing, confirm the MSRV of 1.64.0 against your toolchain, check which feature flags your specific layer requires in the 0.5.3 docs, and read the guides directory for the layer you intend to use.

## FAQ

### What is tower-rs/tower used for?

It is a library of modular, reusable middleware components for building networking clients and servers in Rust, built around a request/response pattern. The README describes it as protocol agnostic, so it is not tied to HTTP specifically.

### How do I install tower-rs/tower?

It is published on crates.io, so you add it as a dependency with cargo add tower. The README points new users at the guides directory in the repository for getting started.

### Is tower-rs/tower no_std compatible?

The README states that tower itself is not no_std compatible, but that tower-layer and tower-service are. If you only need the trait definitions, those two crates are the ones to depend on.

### What Rust version does tower-rs/tower require?

The current minimum supported Rust version is 1.64.0. The project keeps a rolling MSRV policy of at least six months, meaning a new minimum must have been released at least six months before it is adopted.

### What licence does tower-rs/tower use?

It is licensed under MIT, as stated in the README and in the LICENSE file at the repository root. Contributions are licensed as MIT unless explicitly stated otherwise.

## Sources

- [License: MIT](https://github.com/tower-rs/tower/blob/master/LICENSE)
- [Project website](https://docs.rs/tower)
- [README](https://github.com/tower-rs/tower/blob/master/README.md)
- [Releases](https://github.com/tower-rs/tower/releases)
- [tower-rs/tower on GitHub](https://github.com/tower-rs/tower)

---

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
