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 18.3 µs on uvicorn and 9.1 µ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. The modules upstream exposes under fastapi.* exist under notslowapi.*: responses, requests, middleware, security, openapi, encoders, exceptions, background, staticfiles, templating, testclient, websockets, sse, status.

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 1.3 µs on top of that under granian against 4.8 µs under uvicorn.

On uvicorn, install uvicorn[standard] for uvloop and httptools (18.3 µ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 notslowapi 0.1.0. Raw files: bench/baseline/results_ladder_v1.json and results_ladder_v3.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.5 µs, 74,172 req/s 7.8 µs, 128,801 req/s
plain JSON route 31.2 µs, 32,033 req/s 18.3 µs, 54,793 req/s 9.1 µs, 110,154 req/s
int path + str query param 57.0 µs, 17,531 req/s 24.2 µs, 41,405 req/s 14.3 µs, 69,742 req/s
pydantic body + response_model 52.1 µs, 19,212 req/s 26.1 µs, 38,295 req/s 20.1 µs, 49,777 req/s
50 routes via include_router 92.2 µs, 10,800 req/s * 26.3 µs, 37,968 req/s 17.3 µs, 57,864 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 0.1.0 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: 3,335 FastAPI tests plus 1,154 Starlette tests, 4,489 pass, with the same 8 environmental failures before and after every change. 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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

notslowapi-0.1.0.tar.gz (546.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

notslowapi-0.1.0-py3-none-any.whl (211.0 kB view details)

Uploaded Python 3

File details

Details for the file notslowapi-0.1.0.tar.gz.

File metadata

  • Download URL: notslowapi-0.1.0.tar.gz
  • Upload date:
  • Size: 546.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for notslowapi-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6501afbb9d89154eff2567add78c083c5091c5e444eff7ccf387123c61197eb1
MD5 6d051da6ed2860b7cf8e816ece9725fb
BLAKE2b-256 1f866bce2e7f1330c5135be5e0e88d947a1afa1f865bcfa091db0cd9aa0601bf

See more details on using hashes here.

Provenance

The following attestation bundles were made for notslowapi-0.1.0.tar.gz:

Publisher: release.yml on 4thel00z/notslowapi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file notslowapi-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: notslowapi-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 211.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for notslowapi-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9362e642ca0f33a8e69b25b0d3dd7fbbead5e56a55f0291c5d3d9149d69264e0
MD5 6ae5d0e98818cef22800ff8f51c3606f
BLAKE2b-256 9aae9d331f94438a28662101f667e0c22ff08a67412c56af246b41d9681ff696

See more details on using hashes here.

Provenance

The following attestation bundles were made for notslowapi-0.1.0-py3-none-any.whl:

Publisher: release.yml on 4thel00z/notslowapi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 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