Skip to content

AsyncWebSocket is ~4.5x slower than AIOHTTP #645

@Sh3llcod3

Description

@Sh3llcod3

Overview

The asyncio websocket implementation is approximately 4.5x slower compared to AIOHTTP.

Curl-CFFI:
Image

AIOHTTP:
Image

Results

I am running a fresh install of Ubuntu 24.04.3 LTS (Noble), running bare metal on an HPE DL-60 Gen9 server.

aiohttp 3.12.15
├── aiohappyeyeballs >=2.5.0
├── aiosignal >=1.4.0
│   └── frozenlist >=1.1.0
├── attrs >=17.3.0
├── frozenlist >=1.1.1
├── multidict >=4.5,<7.0
├── propcache >=0.2.0
└── yarl >=1.17.0,<2.0
    ├── idna >=2.0
    ├── multidict >=4.0
    └── propcache >=0.2.1
curl-cffi 0.13.0
├── certifi >=2024.2.2
└── cffi >=1.12.0
    └── pycparser *
uvloop 0.21.0

Results on my machine:

--- Starting curl-cffi Benchmark ---
Connection established (curl-cffi). Starting data transmission...

--- curl-cffi Benchmark Complete ---
Sent 2.00 GB of data in 119.61 seconds.
Average throughput: 0.13 Gbps.
Counter (curl-cffi) returned: 0.42 GB

========================================

--- Starting aiohttp Benchmark ---
Connection established (aiohttp). Starting data transmission...

--- aiohttp Benchmark Complete ---
Sent 2.00 GB of data in 26.48 seconds.
Average throughput: 0.60 Gbps.
Counter (aiohttp) returned: 2.05 GB

I wrote a basic benchmark which you can use to test this. It's a simple server which sends a continnous stream of data back and forth. It's not good code but it illustrates the point. I am running this benchmark with the server and client both using localhost so that real network conditions are not a factor.

The server/client is using TLS since that's a representative use case. On my machine there is not much difference between the TLS version and non-TLS version, so I am only including the TLS version.

Dependencies

I used a Poetry venv so that other system packages don't cause issues.

In order to reproduce the same environment, you can use this pyproject.toml file:

[project]
name = "ws-bench"
version = "0.1.0"
description = ""
authors = [
    {name = "Your Name",email = "[email protected]"}
]
license = {text = "MIT"}
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
    "curl-cffi (>=0.13.0,<0.14.0)",
    "aiohttp (>=3.12.15,<4.0.0)",
    "uvloop (>=0.21.0,<0.22.0)"
]

[tool.poetry]
package-mode = false


[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"

Install it (same directory) with:

sudo apt install pipx
pipx install poetry
pipx ensurepath
exec "$SHELL"
poetry install
eval $(poetry env activate)

Server

In order to run this, you need to start by generating a cert/key:

openssl req -x509 -newkey rsa:2048 -nodes -keyout localhost.key -out localhost.crt -days 365 -subj "/CN=localhost"

Here is the server code: server_ssl.py

Run with:

chmod +x server_ssl.py
./server_ssl.py

Client

Here is the client code: client.py

Run with:

chmod +x client.py
./client.py

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions