Releases: justrach/turboAPI
v1.0.29
TurboAPI v1.0.29
This is the real Zig 0.16.0 + Python 3.14t release. It supersedes v1.0.28.
v1.0.28 contained the runtime/performance work, but release smoke testing found packaging problems after publish:
- free-threaded wheels were tagged as
cp314t-cp314t, which pip/uv do not select forpython3.14t - the macOS extension linked against a GitHub Actions-only
PythonT.frameworkpath
v1.0.29 fixes those packaging issues and was smoke-tested from a clean PyPI install with the native Zig backend.
Install
uv python install 3.14t
python3.14t -m pip install turboapi==1.0.29TurboAPI now requires a free-threaded Python build. A regular GIL-enabled Python 3.14 install will refuse to import TurboAPI and tell you to use python3.14t.
Published artifacts:
turboapi-1.0.29-cp314-cp314t-macosx_10_15_universal2.whlturboapi-1.0.29-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whlturboapi-1.0.29.tar.gz
Major Runtime Changes
- Migrated the Zig HTTP runtime to Zig
0.16.0. - Moved the server onto
std.Io.netlistener and stream APIs. - Centralized the shared
std.Io.Threadedlifecycle inzig/src/runtime.zig. - Kept TurboAPI's explicit cross-core connection worker pool so each worker owns a reusable Python thread state.
- Added
TURBO_THREAD_POOL_SIZEsupport for controlling worker count at runtime. - Updated runtime synchronization to Zig 0.16-compatible
std.Io.Mutex/std.Io.Conditionpaths where applicable. - Updated all CI and release workflows to use Zig
0.16.0. - Fixed Zig 0.16 compatibility issues across networking, time APIs, pthread mutexes, Smith fuzz callbacks, libc linking, multipart ownership, and removed std APIs.
Performance Work
- Added eager no-await async dispatch for simple async routes:
simple_async_eager. - Added eager no-await async dispatch for async body routes:
body_async_eager. - Added safety checks so eager async mode is skipped for handlers that actually await, yield, or use loop-sensitive asyncio APIs.
- Added reusable per-worker asyncio event-loop helpers for true-await async handlers.
- Added async vectorcall/noargs fast paths.
- Added cached async response handling.
- Added entry-local atomic cached body pointers for no-arg handlers.
- Added cached JSON response writing that avoids re-entering Python on cache hits.
- Added precomputed scalar JSON body parsing for fast sync/async body wrappers.
- Avoided redundant defensive body copies when Zig already passed immutable Python
bytes. - Reused Zig helpers for
path_paramskwargs and skipped empty path-param dict allocation. - Switched hot route/parameter parsing paths to
std.StaticStringMap. - Added SIMD-assisted header-end scanning and router child dispatch where available.
- Reworked URL percent-decoding to bulk-copy clean spans and branch only on
%/+. - Reworked telemetry JSON escaping to bulk-copy clean spans.
- Replaced DHI field type parsing chains with
StaticStringMap. - Used
PyUnicode_AsUTF8AndSizein SQL value encoding to avoid extra length scans. - Reworked SQL literal escaping to bulk-copy normal spans and only escape when needed.
HTTP, Forms, Multipart, and Middleware
- Added Zig-native multipart/form-data parsing support.
- Fixed multipart, form, URL-encoded, and raw body handling across native, ASGI fallback, and TestClient paths.
- Added
UploadFile/File()/Form()TestClient coverage. - Added raw
body: bytesinjection. - Added populated
Requestinjection for handlers that ask forrequest: Request. - Converted
turboapi.middlewareinto a FastAPI-compatible package with submodules:turboapi.middleware.gzipturboapi.middleware.corsturboapi.middleware.trustedhostturboapi.middleware.httpsredirectturboapi.middleware.sessions
- Fixed middleware route handling so async routes under middleware stay on the correct enhanced path.
- Fixed middleware compatibility for HTTPS redirect, custom logging-style middleware hooks, GZip passthrough, and header tunneling.
- Made
app.mount("/static", StaticFiles(...))register real GET routes so the Zig runtime can serve mounted files. - Ensured middleware can apply to static-file responses.
Bug Fixes
- Fixed implicit HTTP header binding for plain string parameters.
- Fixed query parameter coercion for annotated types like
int,float,bool, lists, and enums. - Fixed path parameter detection so parameter names are matched as
{param}instead of substring matches. - Fixed response normalization to avoid mutating caller dictionaries.
- Fixed response tuple ABI mismatches in the Zig FFI path.
- Fixed
set_cookie()propagation and multi-cookie response handling. - Fixed
StreamingResponse/FileResponsecookie initialization. - Fixed middleware exception status propagation.
- Fixed middleware
on_errorresponse content handling. - Fixed OpenAPI handling for
Optional[X]/Union[X, None]. - Fixed TestClient async dependency resolution.
- Fixed ASGI lifespan handling to use
__aenter__/__aexit__. - Fixed Python 3.14 request failures caused by inline
import inspectshadowing. - Fixed static file path traversal by replacing string-prefix checks with path ancestry checks.
- Fixed CORS regex origin matching to use full matches.
- Fixed CSRF cookie handling so existing cookies are not overwritten.
- Fixed telemetry JSON hex escaping for control characters.
- Fixed native turbopg fallback behavior and multiple DB route/runtime issues.
- Fixed DB query parameter parsing, bool handling, large raw-cell lengths, and insert allocation leaks.
- Fixed DHI schema arena cleanup.
- Fixed turboapi-core router partial mutation on allocation failure.
Structured Logging and Telemetry
- Added
zig/src/telemetry.zigwith event-sourced log/span/counter/histogram/gauge events. - Added text and JSON-lines stderr exporters.
- Added
TURBO_LOG_LEVELandTURBO_LOG_FORMAT. - Added
zig/src/logger.zigwrappers for leveled Zig logs. - Replaced direct
std.debug.printcalls in the server and DB layer with structured logger calls. - Added Python logging helpers and JSON formatting in
python/turboapi/logger.py. - Added telemetry/logging regression coverage.
Protocol and Deployment Docs
- Added
docs/HTTP3_QUIC.md. - Clarified that native QUIC/HTTP/3 is not implemented in TurboAPI yet.
- Documented the supported production path for QUIC/HTTP/3: put TurboAPI behind Caddy, nginx, Cloudflare,
cloudflared, or another edge/reverse proxy. - Updated HTTP/2 docs to avoid claiming unsupported native protocol behavior.
- Updated TLS docs to recommend edge termination / reverse proxy TLS for production.
- Updated WebSocket docs to match the current runtime support model.
- Updated performance tuning docs for worker-pool sizing and
TURBO_THREAD_POOL_SIZE. - Added Zig 0.16 migration docs and a project-agnostic Zig 0.15.2 to 0.16 migration reference.
- Added a zigup multi-version workflow guide.
- Added a frontend release notes page for the 1.0.28/1.0.29 work.
Benchmarking and CI
- Added PR performance regression gating.
- Added benchmark trend/history tooling.
- Added
benchmarks/thresholds.json. - Added
scripts/bench-http.sh. - Added worker-count tracking through
WORKERS=N ./scripts/bench-http.sh. - Updated benchmark result JSON/history/PR output to record worker count, duration, wrk threads, and connections.
- Raised adversarial benchmark thresholds for GitHub-hosted runner stability.
- Fixed the release workflow so it can push tags and dispatch the publish workflow.
- Fixed the build/publish workflow so manual dispatch creates the GitHub Release.
- Added wheel smoke checks in CI:
- install the produced wheel into a fresh venv
- import
turboapi.turbonet - assert
TurboServerandResponseViewexist - on macOS, assert the wheel does not link to
Python.frameworkorPythonT.framework
- Limited release wheels to the actually supported Python
3.14truntime.
Packaging Fixes in v1.0.29
- Fixed free-threaded wheel tags from
cp314t-cp314ttocp314-cp314t. - Stopped linking the Zig extension against libpython for release wheels, so macOS wheels no longer embed a non-portable framework path.
- Verified the macOS wheel links only against
@rpath/libturbonet.dyliband/usr/lib/libSystem.B.dylib. - Verified a clean PyPI install of
turboapi==1.0.29imports the native backend. - Verified a clean PyPI install starts the native Zig HTTP server.
Performance Results
Local no-await async body route measurements with cache disabled:
| Route | Before | After |
|---|---|---|
POST /body0 |
~70.9k req/s | ~110.8k req/s |
POST /body_params |
~67.2k req/s | ~103.6k req/s |
POST /body_sleep0 |
~57k req/s | ~57k req/s |
body_sleep0 is unchanged because it truly awaits and stays on the event-loop path.
Latest mixed-app local HTTP benchmark with TURBO_DISABLE_CACHE=1, TURBO_THREAD_POOL_SIZE=24, and wrk -t8 -c128 -d5s --latency:
| Route | Median |
|---|---|
GET /sync |
91.7k req/s |
GET /async no-await |
89.0k req/s |
POST /body no-await async body |
83.1k req/s |
The same local POST /body route was 49.2k req/s before the precomputed parser pass, so this was about a 69% improvement under the same load.
Validation
Local validation before merge/release:
make checkpassed- full test suite passed:
388 passed, 20 warnings - sample app smoke passed for:
- sync GET
- no-await async GET
- async POST body
- path/query route
- true-await async route
- benchmark wrapper smoke passed with
WORKERS=4 BENCH_DURATION=1 BENCH_THREADS=2 BENCH_CONNECTIONS=16 ./scripts/bench-http.sh /tmp/bench_results.jsonrecorded"workers": 4
Release validation for v1.0.29:
- Release workflow passed
- Build & Publish workflow passed
- Linux
3.14twheel built and imported the native backend in CI - macOS
3.14twheel built, imported the native backend in CI, and passed the no-Python-fr...
v1.0.27
v1.0.24
v1.0.24
Fixes
- restored Zig-runtime gzip middleware body passthrough so compressed responses keep the correct
Content-Encoding: gzipheader and the actual compressed body - normalized middleware-visible request headers to lowercase before Python-side processing
- preserved raw
bytesresponse bodies in the Zig bridge instead of JSON-serializing compressed middleware output tonull
Packaging
- synced version metadata to
1.0.24acrosspyproject.toml,python/setup.py, andpython/turboapi/__init__.py - added README and changelog entries for the gzip fix
References
What's Changed
- fix: resolve yxlyx issues #97, #98; prep #96 by @justrach in #110
- fix: restore gzip middleware body passthrough on Zig runtime by @justrach in #111
- release: bump TurboAPI to v1.0.24 by @justrach in #112
Full Changelog: v1.0.23...v1.0.24
v1.0.23
What's Changed
Full Changelog: v1.0.22...v1.0.23
v1.0.22
v1.0.21
v1.0.20
v1.0.17
v1.0.16
v1.0.15
What's Changed
Full Changelog: v1.0.14...v1.0.15