Skip to main content

notslowapi

FastAPI, minus the slow.

A fork of FastAPI 0.141.1 that does less work per request: the same public API and test suite, with the plain JSON route down from 31.2 to 15.8 µs on uvicorn and 8.5 µs on granian.

PyPI version Python versions CI

Site: https://notslowapi.com

Docs: https://notslowapi.com/docs/

Source: https://github.com/4thel00z/notslowapi

Install

uv add notslowapi[granian]
pip install "notslowapi[granian]"

Python 3.10 to 3.14 and pydantic>=2.9.0. Pydantic v1 is not supported. The base install brings no ASGI server; the granian extra adds granian>=2.0. The standard extra is FastAPI's and pulls the same set upstream does. Nothing is installed under the fastapi or starlette names, and existing installs of those packages are left alone.

Switch

from notslowapi import FastAPI

Replace the package name fastapi with notslowapi in every import.

Run

granian --interface asgi --workers 1 --loop uvloop myapp:app

myapp:app is the module path and attribute of your FastAPI instance. granian's I/O runs on Rust threads alongside the Python thread, so the framework's Python is the only thing left on the critical path. On a bare ASGI callable the server alone costs 7.8 µs per request under granian against 13.5 µs under uvicorn, and the notslowapi route adds 0.6 µs on top of that under granian against 2.4 µs under uvicorn.

On uvicorn, install uvicorn[standard] for uvloop and httptools (15.8 µs on the plain route against 64.0 µs on asyncio and h11) and run:

uvicorn myapp:app --loop uvloop --http httptools --no-proxy-headers --no-server-header --no-date-header

Leave --proxy-headers on if a proxy in front of you sets X-Forwarded-* headers and your app reads them.

Numbers

One core (Apple M3 Pro, Python 3.13), 64 keep-alive connections, median of 3 x 5 s oha runs, one worker. The first column is upstream FastAPI 0.141.1 on uvicorn at the start of the work; the other two are the current master (all 37 changes). Raw files: bench/baseline/results_ladder_v1.json and results_ladder_v4.json in the repository.

route day one, uvicorn (FastAPI 0.141.1) notslowapi, uvicorn notslowapi, granian
raw ASGI app, fixed bytes (server floor) 13.7 µs, 73,040 req/s 13.4 µs, 74,846 req/s 7.9 µs, 126,443 req/s
plain JSON route 31.2 µs, 32,033 req/s 15.8 µs, 63,374 req/s 8.5 µs, 117,318 req/s
int path + str query param 57.0 µs, 17,531 req/s 18.3 µs, 54,769 req/s 9.0 µs, 111,149 req/s
pydantic body + response_model 52.1 µs, 19,212 req/s 21.1 µs, 47,445 req/s 14.1 µs, 71,011 req/s
50 routes via include_router 92.2 µs, 10,842 req/s * 16.7 µs, 59,862 req/s 8.5 µs, 117,379 req/s
three dependencies (path, header, query via Depends) not measured 25.0 µs, 39,953 req/s 14.9 µs, 67,232 req/s

* This rung did not exist in results_ladder_v1.json. The 92.2 µs is the before-run of the include_router change (bench/baseline/results_fix11_before.json), measured on a tree that already had the first ten changes, so it understates the day-one gap.

The changes are inside the framework: parameter extraction, the dependency solver, routing, exception handling and response encoding. Each is one commit with a before and after measurement, listed at What changed. The method, the tools and the raw files are at Benchmark method; the full tables are at notslowapi.com/benchmarks/.

Compatibility

notslowapi has the public API of FastAPI 0.141.1: classes, functions, parameters and behaviors are upstream's, and the changes are internal. The check is the upstream test suite with its imports rewritten: 4,563 tests pass, and the three files that need packages this repo does not install (fastapi-cli, strawberry, the OpenTelemetry SDK) are skipped. The modified Starlette 1.6.0 ships inside the package as notslowapi.starlette and nothing is installed under the starlette name, so code that imports starlette.* directly needs upstream Starlette installed and gets upstream behavior for those objects.

from notslowapi.starlette.middleware.base import BaseHTTPMiddleware
from notslowapi.starlette.responses import Response

Two observable differences: AsyncExitStackMiddleware is importable but no longer installed, so the scope no longer carries fastapi_middleware_astack, and solve_dependencies raises RuntimeError instead of failing an assert when a yield dependency runs without an exit stack. Details at Compatibility.

Reporting a regression

Open an issue at github.com/4thel00z/notslowapi/issues with the notslowapi version, a minimal app, and what FastAPI 0.141.1 does with the same code. For a performance regression, name the machine, Python version and server, and attach bench/out/results.json from a before and an after run of the ladder.

Credits

notslowapi is built from FastAPI by Sebastián Ramírez and Starlette by Encode. The code is theirs; this fork changes how much of it runs per request. FastAPI's documentation applies to notslowapi with the package name swapped.

License

The FastAPI code is MIT licensed, copyright 2018 Sebastián Ramírez (LICENSE). The vendored Starlette is BSD-3-Clause, copyright 2018 Encode OSS Ltd (notslowapi/starlette/LICENSE.md). Both files ship in the wheel; the package metadata declares MIT.

Metadata

Release files for notslowapi 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for notslowapi 0.2.0
File Size Uploaded
notslowapi-0.2.0.tar.gz 565.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for notslowapi 0.2.0
File Interpreter ABI Platform
notslowapi-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 783.7 kB

Release files / notslowapi-0.2.0.tar.gz

Download URL notslowapi-0.2.0.tar.gz
Size 565.9 kB
Tags Source
SHA-256 checksum
How to use checksums
7e1c2546e3352db67de0926c9ca095ecd73bde4fe045dc5b9ba1959d6344d74b
BLAKE2b-256 checksum
How to use checksums
ca9b8ac6125c0ae5858429d9ac972fecab91902a4eed73a8211b9b35a0773ceb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 3, 2026.

Transparency log

Release files / notslowapi-0.2.0-py3-none-any.whl

Download URL notslowapi-0.2.0-py3-none-any.whl
Size 217.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0c0f31864e3772ecb07fd98c69279c0cc351a68fce73553091c7700706a8e1e4
BLAKE2b-256 checksum
How to use checksums
3751f68c63b39b78c4fadc6e03a2252e382e48339db800c30f8d2e307b9eef24
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 3, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page