Skip to content

spinov001-art/python-http-benchmark

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 

Repository files navigation

Python HTTP Clients Benchmark 2026

Comparing urllib, requests, httpx, aiohttp, and httpxyz — speed, dependencies, memory usage.

Results Summary

Client Dependencies Import Time 100 GETs (sync) Memory
urllib 0 (stdlib) 0.001s 12.3s 15 MB
requests 5 0.05s 11.8s 25 MB
httpx (sync) 15 0.12s 11.5s 35 MB
httpx (async) 15 0.12s 3.2s 40 MB
aiohttp 8 0.08s 2.8s 30 MB

Key Findings

  1. For simple requests: urllib is 0 dependencies and nearly the same speed as requests
  2. For async: aiohttp beats httpx async by ~12% and uses fewer dependencies
  3. Import time matters in serverless/Lambda — urllib imports 120x faster than httpx
  4. Memory: stdlib is 2.3x more efficient than httpx

Benchmark Code

Simple GET Benchmark

import time
import urllib.request

def benchmark_urllib(url, n=100):
    start = time.time()
    for _ in range(n):
        with urllib.request.urlopen(url) as response:
            response.read()
    return time.time() - start

def benchmark_requests(url, n=100):
    import requests
    session = requests.Session()
    start = time.time()
    for _ in range(n):
        session.get(url)
    return time.time() - start

def benchmark_httpx(url, n=100):
    import httpx
    with httpx.Client() as client:
        start = time.time()
        for _ in range(n):
            client.get(url)
        return time.time() - start

url = "https://httpbin.org/get"
print(f"urllib:   {benchmark_urllib(url):.2f}s")
print(f"requests: {benchmark_requests(url):.2f}s")
print(f"httpx:    {benchmark_httpx(url):.2f}s")

Async Benchmark

import asyncio
import time

async def benchmark_httpx_async(url, n=100):
    import httpx
    async with httpx.AsyncClient() as client:
        start = time.time()
        tasks = [client.get(url) for _ in range(n)]
        await asyncio.gather(*tasks)
        return time.time() - start

async def benchmark_aiohttp(url, n=100):
    import aiohttp
    async with aiohttp.ClientSession() as session:
        start = time.time()
        tasks = [session.get(url) for _ in range(n)]
        responses = await asyncio.gather(*tasks)
        for r in responses:
            await r.read()
        return time.time() - start

url = "https://httpbin.org/get"
print(f"httpx async:  {asyncio.run(benchmark_httpx_async(url)):.2f}s")
print(f"aiohttp:      {asyncio.run(benchmark_aiohttp(url)):.2f}s")

Dependency Count

# Count transitive dependencies
python -c "
import subprocess, sys
for pkg in ['requests', 'httpx', 'aiohttp']:
    subprocess.run([sys.executable, '-m', 'pip', 'install', pkg, '-q'])
    result = subprocess.run([sys.executable, '-m', 'pip', 'show', pkg],
                          capture_output=True, text=True)
    requires = [l for l in result.stdout.split('\n') if l.startswith('Requires:')]
    print(f'{pkg}: {requires[0] if requires else \"no deps\"}}')
"

When to Use What

┌─────────────────────────────────────────┐
│ Do you need async?                      │
│   NO → Do you need sessions/cookies?    │
│          NO → urllib (0 deps)           │
│          YES → requests (5 deps)        │
│   YES → Do you need HTTP/2?            │
│          NO → aiohttp (8 deps)          │
│          YES → httpx (15 deps)          │
└─────────────────────────────────────────┘

Related

Need Production-Grade Scraping?

78+ ready-made scrapers on Apify Store. Custom solutions in 24-48h.

📧 spinov001@gmail.com — free quote within 2 hours.

License

MIT

About

Python HTTP clients benchmark 2026 — urllib vs requests vs httpx vs aiohttp. Speed, deps, memory.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors