Experimenting with free-threaded Python 3.13 for web frameworks

Hi everyone,

I have been experimenting with free-threaded Python 3.13 (PEP 703) to understand what it means for web frameworks. As an exercise, I built a small pure-Python HTTP framework called Barq - no async/await, no C extensions, just `ThreadPoolExecutor` with true parallelism.

The question: With the GIL removed, can a simple threaded approach compete with async frameworks for web workloads?

Initial benchmarks (vs FastAPI, 100 concurrent clients)

  • JSON endpoint: 8,400 req/s vs 4,500 req/s (+87%)
  • CPU-bound handler: 1,425 req/s vs 266 req/s (+435%)

The CPU-bound result was surprising. Since async is fundamentally single-threaded for CPU work, free-threaded Python with multiple workers shows real scaling:

  • 4 threads: 608 req/s
  • 8 threads: 1,172 req/s (1.9x)
  • 16 threads: 1,297 req/s (2.1x)

Implementation details

The framework is ~500 lines of pure Python:

  • `ThreadPoolExecutor` for worker management
  • HTTP/1.1 keep-alive connections
  • Radix tree router for O(1) matching
  • Pydantic for request validation
  • Optional orjson for JSON serialization

Any suggestions for more rigorous benchmarking methodology? This is purely experimental and not production-ready. I’m sharing it to learn from others who are exploring free-threaded Python.

Code: GitHub - grandimam/barq: Free-threaded HTTP library

2 Likes