Skip to content

Releases: justrach/turboAPI

v1.0.29

26 Apr 01:39

Choose a tag to compare

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 for python3.14t
  • the macOS extension linked against a GitHub Actions-only PythonT.framework path

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.29

TurboAPI 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.whl
  • turboapi-1.0.29-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
  • turboapi-1.0.29.tar.gz

Major Runtime Changes

  • Migrated the Zig HTTP runtime to Zig 0.16.0.
  • Moved the server onto std.Io.net listener and stream APIs.
  • Centralized the shared std.Io.Threaded lifecycle in zig/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_SIZE support for controlling worker count at runtime.
  • Updated runtime synchronization to Zig 0.16-compatible std.Io.Mutex / std.Io.Condition paths 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_params kwargs 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_AsUTF8AndSize in 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: bytes injection.
  • Added populated Request injection for handlers that ask for request: Request.
  • Converted turboapi.middleware into a FastAPI-compatible package with submodules:
    • turboapi.middleware.gzip
    • turboapi.middleware.cors
    • turboapi.middleware.trustedhost
    • turboapi.middleware.httpsredirect
    • turboapi.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 / FileResponse cookie initialization.
  • Fixed middleware exception status propagation.
  • Fixed middleware on_error response 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 inspect shadowing.
  • 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.zig with event-sourced log/span/counter/histogram/gauge events.
  • Added text and JSON-lines stderr exporters.
  • Added TURBO_LOG_LEVEL and TURBO_LOG_FORMAT.
  • Added zig/src/logger.zig wrappers for leveled Zig logs.
  • Replaced direct std.debug.print calls 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 TurboServer and ResponseView exist
    • on macOS, assert the wheel does not link to Python.framework or PythonT.framework
  • Limited release wheels to the actually supported Python 3.14t runtime.

Packaging Fixes in v1.0.29

  • Fixed free-threaded wheel tags from cp314t-cp314t to cp314-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.dylib and /usr/lib/libSystem.B.dylib.
  • Verified a clean PyPI install of turboapi==1.0.29 imports 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 check passed
  • 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.json recorded "workers": 4

Release validation for v1.0.29:

  • Release workflow passed
  • Build & Publish workflow passed
  • Linux 3.14t wheel built and imported the native backend in CI
  • macOS 3.14t wheel built, imported the native backend in CI, and passed the no-Python-fr...
Read more

v1.0.27

01 Apr 01:16
f7ec31e

Choose a tag to compare

What's Changed

Full Changelog: v1.0.24...v1.0.27

v1.0.24

31 Mar 06:19
d0ee8b9

Choose a tag to compare

v1.0.24

Fixes

  • restored Zig-runtime gzip middleware body passthrough so compressed responses keep the correct Content-Encoding: gzip header and the actual compressed body
  • normalized middleware-visible request headers to lowercase before Python-side processing
  • preserved raw bytes response bodies in the Zig bridge instead of JSON-serializing compressed middleware output to null

Packaging

  • synced version metadata to 1.0.24 across pyproject.toml, python/setup.py, and python/turboapi/__init__.py
  • added README and changelog entries for the gzip fix

References

  • fixes #96
  • runtime fix merged in #111
  • release metadata sync merged in #112

What's Changed

Full Changelog: v1.0.23...v1.0.24

v1.0.23

27 Mar 13:20

Choose a tag to compare

What's Changed

  • feat: extract turboapi-core shared Zig library by @justrach in #108

Full Changelog: v1.0.22...v1.0.23

v1.0.22

26 Mar 01:19

Choose a tag to compare

What's Changed

  • fix: refresh dhi hash so release builds can package turbonet by @justrach in #106

Full Changelog: v1.0.21...v1.0.22

What's Changed

  • fix: refresh dhi hash so release builds can package turbonet by @justrach in #106

Full Changelog: v1.0.21...v1.0.22

v1.0.21

26 Mar 00:55
b3adabb

Choose a tag to compare

What's Changed

  • Fix Zig response cache crash under load by @justrach in #95
  • fix: close verified compat gaps in TestClient, lifespan, docs, router deps, and static mounts by @justrach in #105

Full Changelog: v1.0.20...v1.0.21

v1.0.20

24 Mar 13:14

Choose a tag to compare

What's Changed

  • feat: TurboBoto — Zig-accelerated boto3 drop-in replacement by @justrach in #62
  • Tighten benchmark methodology and publish corrected results by @justrach in #77

Full Changelog: v1.0.17...v1.0.20

v1.0.17

21 Mar 02:34
43a7191

Choose a tag to compare

What's Changed

  • bench: asyncpg vs TurboAPI+pg.zig Docker benchmarks by @justrach in #56
  • fix: add TURBO_DISABLE_CACHE env var by @justrach in #58

Full Changelog: v1.0.16...v1.0.17

v1.0.16

20 Mar 10:13

Choose a tag to compare

What's Changed

  • feat: Claude Code skills for TurboAPI development by @justrach in #53
  • feat: Zig-native Postgres via pg.zig — zero-Python CRUD by @justrach in #50

Full Changelog: v1.0.15...v1.0.16

v1.0.15

19 Mar 19:31

Choose a tag to compare

What's Changed

  • fix: support Annotated[Type, Depends(...)] pattern by @justrach in #52

Full Changelog: v1.0.14...v1.0.15