starlette-compress
starlette-compress compresses ASGI HTTP responses with Zstandard, Brotli, or Gzip. Use it with Starlette, FastAPI, or another ASGI application on Python 3.11+.
Works with asyncio and Trio, including streaming responses and server-sent events.
Installation
pip install starlette-compress
Add the middleware
Starlette
from starlette.applications import Starlette
from starlette.middleware import Middleware
from starlette.responses import PlainTextResponse
from starlette.routing import Route
from starlette_compress import CompressMiddleware
async def homepage(request):
return PlainTextResponse("Hello!" * 200)
app = Starlette(
routes=[Route("/", homepage)],
middleware=[Middleware(CompressMiddleware)],
)
Serve app with your ASGI server. Responses are compressed according to the
client's Accept-Encoding header.
FastAPI
from fastapi import FastAPI
from starlette_compress import CompressMiddleware
app = FastAPI()
app.add_middleware(CompressMiddleware)
@app.get("/")
async def homepage():
return {"message": "Hello!" * 200}
Configure compression
Changing minimum response size
minimum_size applies to an ordinary one-shot body: a terminal first body
message below the threshold is forwarded unchanged. Once an ordinary response
sends more_body=True, compression begins without buffering to reach the
threshold, even if the entire response is small. Streaming-registered types
(e.g. text/event-stream) bypass the threshold for one-shot bodies too.
See the constructor reference for defaults.
from starlette.applications import Starlette
from starlette.middleware import Middleware
from starlette_compress import CompressMiddleware
middleware = [
Middleware(CompressMiddleware, minimum_size=1000)
]
app = Starlette(middleware=middleware)
Tuning compression levels
Adjust compression levels to trade compression work for output size. Supported
levels and defaults are in the constructor reference.
Enabled Brotli qualities and Gzip levels outside their documented ranges raise
ValueError when the middleware is constructed.
from starlette.applications import Starlette
from starlette.middleware import Middleware
from starlette_compress import CompressMiddleware
middleware = [
Middleware(CompressMiddleware, zstd_level=6, brotli_quality=6, gzip_level=6)
]
app = Starlette(middleware=middleware)
Supporting custom content types
Unknown content types are not compressed. Add or remove types before serving requests; see the default media types.
from starlette_compress import add_compress_type, remove_compress_type
add_compress_type("application/my-custom-type")
remove_compress_type("application/json")
Server-sent events (SSE)
text/event-stream responses are compressed by default and bypass
minimum_size. The compressor flushes after each non-empty continuing ASGI body
message and finishes on the terminal message. It does not parse SSE frames:
two events in one message share one flush, and empty continuation messages are
skipped.
The middleware forwards http.response.start immediately so clients such as
EventSource can open before the first event, though the ASGI server may buffer
it until the first body. On pathsend-capable scopes, start is deferred to the
first body or pathsend message so a file send is never advertised as compressed.
To opt out:
from starlette_compress import remove_compress_type
remove_compress_type("text/event-stream")
NDJSON / JSONL are not registered by default. Opt in for compressed, incremental line delivery:
from starlette_compress import add_compress_type
add_compress_type("application/x-ndjson", streaming=True)
add_compress_type("application/jsonl", streaming=True)
Flushing makes compressed bytes available from the codec; proxy and CDN buffering remain separate.
Dropping Accept-Encoding header
By default, starlette-compress leaves the request Accept-Encoding header intact. Set
remove_accept_encoding=True to remove it before calling downstream middleware/application.
Response behavior
Enabled algorithms are selected in server priority order: Zstandard, Brotli,
then Gzip. A positive q makes a coding eligible; relative quality values do
not reorder that priority. For example, zstd;q=0.1, gzip;q=1 selects Zstandard.
Non-positive or unparseable q values exclude a coding; * enables supported
codings except explicit exclusions. Multiple Accept-Encoding fields are
combined. No header, no eligible enabled coding, or identity alone uses the
identity path. This middleware falls back to identity rather than returning
406 when no enabled coding is eligible.
Only registered media types are eligible (parameters and case are ignored).
Missing or unknown types, informational responses, status 204/205/304,
Content-Range, and an existing non-identity Content-Encoding bypass
compression. A delayed-start response whose first body is terminal gets its
encoded Content-Length; streaming paths remove it. Eligible body responses
merge Accept-Encoding into Vary, including the identity path, except
ordinary bodies below threshold. Raw pathsend forwarding preserves the
original headers.
Ordinary streams have no per-message flush guarantee; register a type as
streaming for incremental delivery. Omitted
more_body means false. Configure the process-wide registry before serving
requests. Registration is
case-insensitive and idempotent; a plain re-add retains streaming membership,
and removal clears both memberships.
http.response.pathsend is forwarded uncompressed when it is the first
content message. The identity path preserves zero-copy capability; an encoded
path removes http.response.zerocopysend from the downstream scope so raw
file bytes cannot be appended to an encoded response.
Middleware instances can be shared across event-loop threads. Codec errors propagate to the application/server.
Reference and Support
The middleware reference lists
defaults and compression-level ranges. The
add_compress_type and remove_compress_type reference
describes registry operations and default media types.
Issues and questions · Private security reports · Premium support
Metadata
Release files for starlette-compress 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| starlette_compress-2.0.0.tar.gz | 26.2 kB | With provenance | Details for starlette_compress-2.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| starlette_compress-2.0.0-py3-none-any.whl | Python 3 | none | any | Details for starlette_compress-2.0.0-py3-none-any.whl |
Total release size: 41.7 kB
Release files / starlette_compress-2.0.0.tar.gz
| Download URL | starlette_compress-2.0.0.tar.gz |
|---|---|
| Size | 26.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1381d5a0e963a845ab6427e8444e62330eda6e7561f1804c6c8c8081564623e6
|
|
BLAKE2b-256 checksum How to use checksums |
1333387f5e5f59899e7031755fdc8a415966a68176580c61650f03a05b634685
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.
Transparency logRelease files / starlette_compress-2.0.0-py3-none-any.whl
| Download URL | starlette_compress-2.0.0-py3-none-any.whl |
|---|---|
| Size | 15.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7fcea21754ced44e4487870dcf7993348be6c4d697716fb7984ff5627827f529
|
|
BLAKE2b-256 checksum How to use checksums |
af83060f07243f1ec3a1061aeab577870e9e42abe94c5269945a7915749bc170
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.
Transparency logSecurity for starlette-compress 2.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for starlette_compress-2.0.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.