Skip to content

Add aiofastnet dependency to speedups extra (faster TLS and native kernel TLS support)#12744

Closed
tarasko wants to merge 43 commits into
aio-libs:masterfrom
tarasko:feature/aiofastnet_extra
Closed

Add aiofastnet dependency to speedups extra (faster TLS and native kernel TLS support)#12744
tarasko wants to merge 43 commits into
aio-libs:masterfrom
tarasko:feature/aiofastnet_extra

Conversation

@tarasko

@tarasko tarasko commented May 30, 2026

Copy link
Copy Markdown
Contributor

What do these changes do?

Discussion #12701

This change adds aiofastnet to speedups extras.
aiofastnet provides more efficient implementations for

  • loop.create_connection
  • loop.start_tls
  • loop.create_server
  • loop.sendfile

aiohttp will use them if aiofastnet can be imported.

On top of that, aiofastnet provides optional, transparent Kernel TLS support on Linux and native sendfile for TLS connections using SSL_sendfile. User can enable it via an option in SSLContext.

Are there changes in behavior for the user?

This is an optimization change, it should not change visible behavior.

Is it a substantial burden for the maintainers to support this?

There is now an extra indirection layer in net_helpers.py, tests should prefer to mock its functions instead of mocking loop primitives like create_connection directly.

Every time when users will complain about something that sounds like a networking layer issue, it would be very important to know: is aiofastnet installed or not? So it would be good to add this question to the issue template.

aiofastnet itself is a medium size project, functionally-wise it has a limited scope, and I hope I'll be able to maintain it the next 5 years. It is relatively new, I have written a good amount of tests already and I'm currently adding code coverage reports. I want to get coverage close to 100%.

Related issue number

Checklist

  • I think the code is well written
  • Unit tests for the changes exist
  • Documentation reflects the changes
  • If you provide code modification, please add yourself to CONTRIBUTORS.txt
    • The format is <Name> <Surname>.
    • Please keep alphabetical order, the file is sorted by names.
  • Add a new news fragment: 12744.feature.rst

@tarasko tarasko requested review from asvetlov and webknjaz as code owners May 30, 2026 21:50
@psf-chronographer psf-chronographer Bot added the bot:chronographer:provided There is a change note present in this PR label May 30, 2026
@codecov

codecov Bot commented May 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.26087% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 98.91%. Comparing base (e8832ae) to head (133193d).
⚠️ Report is 1 commits behind head on master.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
aiohttp/connector.py 85.71% 1 Missing ⚠️
tests/test_connector.py 87.50% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #12744      +/-   ##
==========================================
- Coverage   98.92%   98.91%   -0.01%     
==========================================
  Files         131      132       +1     
  Lines       46881    46916      +35     
  Branches     2431     2434       +3     
==========================================
+ Hits        46376    46408      +32     
- Misses        379      381       +2     
- Partials      126      127       +1     
Flag Coverage Δ
Autobahn 22.48% <35.65%> (+0.02%) ⬆️
CI-GHA 98.88% <95.65%> (-0.02%) ⬇️
OS-Linux 98.63% <90.43%> (-0.02%) ⬇️
OS-Windows 96.93% <83.47%> (-0.10%) ⬇️
OS-macOS 97.88% <89.56%> (-0.03%) ⬇️
Py-3.10 98.15% <94.78%> (+0.02%) ⬆️
Py-3.11 98.37% <95.65%> (-0.02%) ⬇️
Py-3.12 98.45% <95.65%> (-0.02%) ⬇️
Py-3.13 98.43% <95.65%> (-0.01%) ⬇️
Py-3.14 98.45% <95.65%> (-0.02%) ⬇️
Py-3.14t 97.50% <89.56%> (-0.02%) ⬇️
Py-pypy-3.11 97.36% <86.95%> (-0.03%) ⬇️
VM-macos 97.88% <89.56%> (-0.03%) ⬇️
VM-ubuntu 98.63% <90.43%> (-0.02%) ⬇️
VM-windows 96.93% <83.47%> (-0.10%) ⬇️
cython-coverage 37.98% <16.52%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@webknjaz

Copy link
Copy Markdown
Member

FTR, we should be conservative about adding deps that have only existed for just under 3 months and aren't under our control. This poses a supply chain risk. Something to concider could be running an audit or offering hosting it under the org.

cc @bdraco @Dreamsorcerer

@codspeed-hq

codspeed-hq Bot commented May 30, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 18.88%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 5 improved benchmarks
✅ 67 untouched benchmarks
⏩ 72 skipped benchmarks1

Performance Changes

Benchmark BASE HEAD Efficiency
test_one_thousand_round_trip_websocket_binary_messages[small] 16.3 ms 13.2 ms +24.06%
test_one_thousand_round_trip_websocket_text_messages 16.8 ms 13.6 ms +23.24%
test_simple_web_file_response 82 ms 71.5 ms +14.7%
test_simple_web_file_sendfile_fallback_response 88.1 ms 71.5 ms +23.11%
test_ten_streamed_responses_iter_any 21.7 ms 19.8 ms +9.98%

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing tarasko:feature/aiofastnet_extra (133193d) with master (e8832ae)2

Open in CodSpeed

Footnotes

  1. 72 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on master (ec3f080) during the generation of this report, so e8832ae was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

Comment thread aiohttp/web_fileresponse.py Fixed
Comment thread aiohttp/connector.py Fixed
Comment thread aiohttp/web_runner.py Fixed
@tarasko

tarasko commented May 31, 2026

Copy link
Copy Markdown
Contributor Author

2 checks are failing:

  • code coverage has slightly decreased, less than 0.5%, I'm not sure how if it is related to my changes and whether I can do something about it.
  • Labels - I don't know what to add there, and I don't think I can.

Everything else pass

@Dreamsorcerer

Copy link
Copy Markdown
Member

FTR, we should be conservative about adding deps that have only existed for just under 3 months and aren't under our control. This poses a supply chain risk. Something to concider could be running an audit or offering hosting it under the org.

I've already done an AI audit and shared any results with tarasko. tarasko also has some prior involvement with aiohttp in the past in relation to websockets optimisation, which is why I've encouraged this. If this library proves out to be beneficial then we'll open an invitation to host it under aio-libs, if tarasko is interested.

@Dreamsorcerer

Copy link
Copy Markdown
Member

I'm going to skip this for the 3.14 release and we can look at including it into 3.15/4.

@tarasko

tarasko commented May 31, 2026

Copy link
Copy Markdown
Contributor Author

FTR, we should be conservative about adding deps that have only existed for just under 3 months and aren't under our control. This poses a supply chain risk. Something to concider could be running an audit or offering hosting it under the org.

I've already done an AI audit and shared any results with tarasko. tarasko also has some prior involvement with aiohttp in the past in relation to websockets optimisation, which is why I've encouraged this. If this library proves out to be beneficial then we'll open an invitation to host it under aio-libs, if tarasko is interested.

Yes, I'm interested. I think it would be great for aiofastnet credibility if you host it under aio-libs.

Since aiofastnet replacing such a fundamental layer, it comes with a big security concern. I'm happy to discuss what can be done to mitigate any security risks.

@Dreamsorcerer

Copy link
Copy Markdown
Member

Since aiofastnet replacing such a fundamental layer, it comes with a big security concern. I'm happy to discuss what can be done to mitigate any security risks.

The audit results are in a private vulnerability report, if you've not already seen it:
https://github.com/tarasko/aiofastnet/security

@tarasko

tarasko commented May 31, 2026

Copy link
Copy Markdown
Contributor Author

Codspeed reports around 20% performance gains on some benchmarks. I noticed these benchmarks run for plain TCP connections only. aiofastnest helps to optimize TCP case of course, but that is not where aiofastnet truly shines. I would expect much more significant gains for TLS connections, my projection is around 50-70%.

Perhaps we could add TLS case to benchmarks as a separate PR, so there will be a good baseline.

@tarasko

tarasko commented May 31, 2026

Copy link
Copy Markdown
Contributor Author

Since aiofastnet replacing such a fundamental layer, it comes with a big security concern. I'm happy to discuss what can be done to mitigate any security risks.

The audit results are in a private vulnerability report, if you've not already seen it: https://github.com/tarasko/aiofastnet/security

Thank you very much. I'm looking into it

@Dreamsorcerer

Copy link
Copy Markdown
Member

Perhaps we could add TLS case to benchmarks as a separate PR, so there will be a good baseline.

Yes, that'd be useful to add.

Comment thread aiohttp/net_helpers.py

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll do a full review later, but given the limited number of places it's used, maybe it's fine to just handle this in each file individually? Problem here is a complete loss of type safety and would likely need a lot more code to get that working sensibly.

@tarasko tarasko May 31, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can make typed wrappers for create_connection and start_tls in connector.py (and similar for other files)

Something like this:

connector.py

async def create_connection(loop: AbstractEventLoop, <actual typed arguments used by aiohttp>) -> tuple[Transport, Protocol]
    if HAS_AIOFASTNET:
        return await aiofastnet.create_connection(loop, <actual typed arguments used by aiohttp>)
    else:
        return await loop.create_connection(<actual typed arguments used by aiohttp>)

This way it can still be easily mocked in tests. But the following will probably have to be repeated in multiple files in some way:

if NO_EXTENSIONS:
    HAS_AIOFASTNET = False
else:
    try:
        import aiofastnet
        HAS_AIOFASTNET = True
    except ImportError:
        HAS_AIOFASTNET = False

or I can keep net_helpers.py and make typed wrappers there. Seems a little cleaner for my taste, but no strong preference

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that should be good.

This way it can still be easily mocked in tests. But the following will probably have to be repeated in multiple files in some way:

Yeah, we already do this for other libraries, so probably fine.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if NO_EXTENSIONS:

Wait, do we want to disable it on NO_EXTENSIONS? That flag is just meant to disable the compiled Cython code in aiohttp.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, indeed. For some reason I thought that it is supposed to disable extensions and extras.
I'll stop using it.

How do you usually test aiohttp locally with and without a particular extra? Just by having 2 environments with and without a package?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess. Currently the CI probably catches this simply by these libraries not being available on some platforms. We could probably do with a separate extras requirements file or something and not install it in the NO_EXTENSIONS test runs.

@tarasko tarasko mentioned this pull request Jun 6, 2026
5 tasks
@tarasko

tarasko commented Jun 6, 2026

Copy link
Copy Markdown
Contributor Author

I messed something up with this branch and got swarmed with endless resolve conflicts.
I have opened a new PR #12822.
Let's continue there

@tarasko tarasko closed this Jun 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:chronographer:provided There is a change note present in this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants