# Mangum: running an ASGI app on AWS Lambda

> The adapter that lets FastAPI, Starlette, Quart or Django serve requests from Lambda behind API Gateway, a Function URL, an ALB or Lambda@Edge.

**Kludex/mangum** — AWS Lambda support for ASGI applications

- Repository: https://github.com/Kludex/mangum
- Website: http://mangum.fastapiexpert.com/
- Stars: 2,141 · Forks: 135
- Language: Python
- License: MIT
- Published: 2026-10-07 · Updated: 2026-10-07 · Language: en
- Canonical page: https://hysenlabs.com/projects/kludex-mangum

## Five event shapes, one ASGI interface

AWS Lambda does not speak ASGI. It receives a single JSON event whose shape depends on what invoked the function, and hands your code a callback. Mangum sits between those two facts: it is an adapter for running ASGI applications in AWS Lambda to handle Function URL, API Gateway, ALB and Lambda@Edge events.

The handler coverage is itemised, and the two API Gateway variants are listed separately because they are not the same format. There are handlers for API Gateway HTTP and REST APIs, Application Load Balancer, Function URLs, and CloudFront Lambda@Edge. Each of those produces an event with different field names, different header encoding and different notions of base path, which is exactly the translation layer nobody wants to write for every service.

Framework compatibility is broad because the requirement is only that the object satisfies ASGI. The README names Starlette, FastAPI, Quart and Django. Quart is the interesting entry, since it is an ASGI framework that is not FastAPI, and its presence is a decent signal that the adapter is not coupled to one framework's lifecycle.

The package itself is thin. Its only runtime dependency is `typing_extensions`, everything else is a development dependency, and the module layout in the repository is correspondingly small: a `mangum/` package, `docs/`, `tests/`, `scripts/`, a `CHANGELOG.md` and a `pyproject.toml` built with hatchling.

## The handler is three lines around your app

Installation is the usual one-liner:

```shell
pip install mangum
```

The README gives two examples, a raw ASGI callable and a FastAPI app. The raw form makes the contract explicit, because you can see the response being sent as an `http.response.start` message followed by an `http.response.body` message:

```python
from mangum import Mangum

async def app(scope, receive, send):
    await send(
        {
            "type": "http.response.start",
            "status": 200,
            "headers": [[b"content-type", b"text/plain; charset=utf-8"]],
        }
    )
    await send({"type": "http.response.body", "body": b"Hello, world!"})


handler = Mangum(app, lifespan="off")
```

The framework form is the one you will use:

```python
from fastapi import FastAPI
from mangum import Mangum

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": q}

handler = Mangum(app, lifespan="off")
```

Both examples set `lifespan="off"`, and that is the one thing in these snippets worth thinking about rather than copying. Startup and shutdown lifespan events are listed as a supported feature, so the capability exists, but the minimal examples deliberately turn it off. Whether you want it on depends on whether your application has startup work that must complete before the first request and whether it is safe to repeat it, since a Lambda environment is reused across invocations.

## Binary responses and compression

Two features matter more for real traffic than the framework list does. The first is support for binary media types and payload compression in API Gateway using GZip or Brotli.

Binary media types are where a naive adapter quietly corrupts things. API Gateway expects a response body that it can treat as text unless the content type is declared as binary, and an adapter that base64-decodes the wrong field produces an image endpoint that returns bytes nobody can decode. Handling that inside the adapter is the correct place for it, because it depends on which event source fired and on how the API Gateway stage was configured, not on anything your application does.

Compression is the second. GZip and Brotli both add a request to the client and save bytes on the wire, and for JSON APIs the difference between them is often small, but for anything serving larger payloads it is not. Having the choice inside the adapter means your application does not need to know which is in effect.

The other integration item is deployment tooling. The README states that Mangum works with existing deployment and configuration tools, naming the Serverless Framework and AWS SAM. That matters more than it sounds, because getting a Lambda function to invoke the right handler, with the right handler string and the right runtime, is most of the work in a serverless deployment and you do not want a custom build for it.

## The Python version story, including one revert

The release history is worth reading because it documents a real compatibility problem rather than a list of features.

Version 0.20.0, published 2025-12-27, dropped Python 3.7 and 3.8 and added Python 3.14 support. Version 0.21.0, published 2026-02-01, then reverted that Python 3.14 support and added it back properly, and the release notes give the reason: the earlier attempt was not working as expected, with a link to the tracking issue. Both the revert and the re-implementation are listed in the same release, which is an unusually transparent way to handle it.

Version 0.22.0, published 2026-08-22, moved the window forward again. Python 3.15 is supported, with the full suite and strict type checking passing on it, and Python 3.9 is no longer supported, making 3.10 the minimum. That matches the `pyproject.toml`, which declares `requires-python = ">=3.10"` and lists classifiers for 3.10 through 3.15.

The current minimum has therefore moved twice in about a year. If you are pinning a Lambda runtime, the supported window is the thing to check before an upgrade rather than after one.

## Testing against a real runtime instead of mock events

The most substantive change in 0.22.0 is not the Python version. The release notes state that adapters are now verified against a real Lambda runtime: the test suite deploys Mangum to LocalStack and drives it through a Lambda Function URL and an API Gateway REST API with real HTTP requests, covering the HTTP v2 and REST v1 event formats plus lifespan startup, instead of relying only on hand-written mock events.

That is a meaningful statement about the project's priorities. A hand-written mock event is exactly the kind of fixture that keeps passing after AWS changes a field name, which is the failure mode that surfaces in production rather than in CI. Driving real requests through a local AWS emulator closes most of that gap.

The development dependency list backs the claim up. Alongside pytest, coverage, ruff, mypy and the framework packages, the project depends on `testcontainers[localstack]`, `boto3` and `types-boto3`, which is what you need to start a containerised AWS emulator and talk to it. The project also configures strict linting with ruff at a line length of 120.

For an adapter library, that is the test strategy you would want, and it is also the reason to trust a version bump more than you would otherwise.

## Where to look beyond the README

The README is short and mostly a capability list plus two examples, which is a reasonable trade for a package whose job is narrow. The documentation lives at mangum.fastapiexpert.com, and that is where the configuration surface is.

A few things the README deliberately leaves implicit. How the base path from an API Gateway stage or an ALB target group is prepended to the ASGI path. How the `lifespan` parameter behaves in each mode beyond the literal `off` used in both examples. Which handler class corresponds to which event source when you want one rather than automatic detection. How the binary media type configuration has to be set on the API Gateway stage as well as in the adapter.

The package is also small enough to read directly, and the repository has a `CHANGELOG.md` that goes back through the version history alongside the GitHub releases.

For context on where this sits: at 2,137 stars with 136 forks and 39 open issues, this is the de facto way to serve FastAPI on Lambda. It is not archived and the last push was on 2026-09-04, which is a couple of weeks after the 0.22.0 release, so the line is active. The maintenance burden sits with Kludex, who also maintains the fastapi-tips repository, and 39 open issues is a busy queue for a package this small.

## Conclusion

Mangum solves one unglamorous problem properly: turning five different Lambda event shapes into the ASGI call your framework expects, and doing it in a package small enough to read in an afternoon. The adapter has no runtime dependency beyond `typing_extensions`, and the recent releases show the maintenance philosophy, which is to test against a real Lambda runtime through LocalStack rather than hand-written mock events. That is the detail that matters most if you are choosing an adapter, because event format drift is exactly what breaks in production after a quiet upgrade. Install it, wrap your app in a `Mangum` handler, set the lifespan mode deliberately, and read the docs site for the configuration options the README does not cover.

## FAQ

### How do I run a FastAPI application on AWS Lambda with Mangum?

Wrap the application in a `Mangum` handler and point your Lambda function at it. The minimal form is `from fastapi import FastAPI` and `from mangum import Mangum`, then `app = FastAPI()` with your routes and `handler = Mangum(app, lifespan="off")`. Mangum supplies the Lambda entry point; you supply the handler string in your deployment configuration.

### Which AWS event sources does Mangum support?

The README lists handlers for API Gateway HTTP and REST APIs, Application Load Balancer, Lambda Function URLs and CloudFront Lambda@Edge. The two API Gateway variants are separate because the HTTP and REST APIs produce different event formats, and both v2 and v1 formats are covered by the test suite.

### Does Mangum work with frameworks other than FastAPI?

Yes. The requirement is that the application implements ASGI, and the README names Starlette, FastAPI, Quart and Django as compatible frameworks. The raw ASGI example in the README shows a plain callable, so a framework of your own will work if it satisfies the interface.

### What Python versions does the current Mangum release support?

Release 0.22.0, published 2026-08-22, supports Python 3.15 and dropped Python 3.9, so the minimum is now 3.10, matching the `requires-python` declaration in `pyproject.toml`. Support for 3.7 and 3.8 was dropped in 0.20.0. Python 3.14 was added in 0.20.0, reverted in 0.21.0 because it was not working as expected, and then added back properly.

### Does Mangum handle gzip or brotli compressed responses?

Yes. The README lists support for binary media types and payload compression in API Gateway using GZip or Brotli among the features. Binary handling matters because API Gateway only treats a body as binary when the content type is declared as such, and that decision belongs to the adapter rather than your application.

## Sources

- [Kludex/mangum on GitHub](https://github.com/Kludex/mangum)
- [License: MIT](https://github.com/Kludex/mangum/blob/main/LICENSE)
- [Project website](http://mangum.fastapiexpert.com/)
- [README](https://github.com/Kludex/mangum/blob/main/README.md)
- [Releases](https://github.com/Kludex/mangum/releases)

---

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