← all work

Software · 06 / 06 · Java 21 · Python · Kafka

Streaming Consumer Benchmark

The same fan-out server written twice, Java 21 virtual threads and Python asyncio, measured by one harness up to 20,000 connections.

20,000socket connections held
320k/sdeliveries in the saturation test
87 → 2.3 msp50 at 20k connections after one fix
0duplicates or gaps, in every run

Why I built this

In the real world

Teams pick Python asyncio or Java for high-concurrency services mostly on opinion. Java 21's virtual threads changed that trade-off: simple blocking code that can hold tens of thousands of connections. The choice decides how many servers you pay for and how fast users get their data.

What I wanted to find out

Python asyncio or Java 21 virtual threads: which should a team pick for a service holding thousands of connections? People argue for both. I wanted numbers instead, even if they went against Python, the language I use most.

What I built

The hot path of my streaming platform, Kafka in and thousands of TCP sockets out, written twice: Java 21 with one virtual thread per connection, and Python asyncio on uvloop.

Both pass the same conformance suite against real Kafka, and one load harness drives them. Every run starts from a cold container, discards the warm-up window and audits every sequence number.

How it works

Kafka produceropen-loop load
Kafkathe event log
ServerJava 21 VT or Python asyncio
Client swarmup to 20k sockets
Reportlatency, CPU, memory, audit

Same protocol, same harness, same 2 CPUs and 1 GiB per server. Only the concurrency model changes.

Measured

Up to 5,000 connections
Both about 2 ms p50. Java p99 4-5 ms, Python 5-10 ms
10,000 connections
Java p99 8 ms. Python on one process: p99 253 ms (one core at 100%)
20,000 connections
Java with 2 dispatch threads: p50 2.5 ms. Python on 2 processes: p50 184 ms
Memory per connection
Java about 28 KiB (+190 MiB JVM). Python about 12 KiB (+45 MiB)
p99 latency as connections grow, Java vs Python
p99 latency as connections grow.
Memory as connections grow, Java vs Python
Memory as connections grow.
Server CPU as connections grow, Java vs Python
Server CPU as connections grow: Python on 2 processes hits the 200% limit first.
p99 latency as offered load grows at 2,000 connections
p99 latency as load rises at 2,000 connections.