Tokio has added experimental io_uring support for file system APIs, which transparently switches from the default implementation to io_uring when enabled through compiler and runtime flags. The implementation uses epoll for event notification while submitting io_uring operations to the kernel, requiring careful resource management to prevent use-after-free issues when operations are cancelled. While io_uring is generally more performant than thread pool implementations due to reduced system call overhead, current limitations include single io_uring instance per runtime causing lock contention with many concurrent operations. Future improvements include exposing io_uring-specific public APIs for custom operations and extending support to network I/O.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
TokioConf 2026 - Tokio’s New io_uring-Based File I/O by Motoyuki KimuraAdded:
Um yeah, thank you for coming to my talk. Um today, uh I'd like to talk about um iring support in Tokyo. Um and my name is Motuki from Ubai Toyota.
So just before my talk um there's a great talk from Christian about um Iuring in general, but um my talk will be focusing on more Tokyo Tokyo specific aspect. uh about IO uring.
So some of you may might be surprised by the fact that Tokyo now actually supports um IOuring but um it's actually happening. So like Alice mentioned yesterday um you know we off uh we experimentally support IOuring for file system APIs. So here is the I think uh release notes from 148. Um as you can see um there are a lot of um description disc description description about um IO support for file system APIs. Um this is still unstable. So you need to pass specific CSVs to enable it but um Tokyo has been exploring the possibilities of you know integrating ION in the runtime.
So um here's the agenda. I want to quickly uh cover these items today. Um the first I want to cover the current status and how it's implemented and also I found kind of interesting findings um during the implementation. So I want to cover that as well. Um also finally uh I want to cover the work idea that we could do in the future to improve current Tokyo um ION support.
Um so current status so like I mentioned uh currently we are supporting uh IOing for file system APIs and technically it's possible to support network operation as well but um it's more complex so we just start um supporting file system API at this point and also the way we do this is you know just transparently swap the implementation so if you enable um Iuring feature um Tokyo will switch um from their normal implementation like Fredpole implementation to you know ioing implementation. So by doing this you know you don't have to uh rewrite your existing code. Um so the only thing you need to do is just pass um compiler flag and add uh runtime flags. And if you visit this issue tracker, you'll get uh other you know details about um which for example API is supporting um Iuring and so on.
So um let's look at how it's implemented. Um here is the diagram um that shows um how it's um implemented in Tokyo as of today.
Um this might be changed in the future maybe but um at this point today um if you submit the IO uring future to Tokyo um at its initialization phase um the task will submit the IO uring um submission Q entry to the kernel and the task will be pending state and then after the operation you submitted has completed then Tokyo event group um will receive the notification from the runtime I mean from the kernel and then after the Tokyo runtime will wake up your tasks and then the task will make a progress. Um the important fact here is that um EO can actually you know receive the uh event from the um um ION.
So EO is the way Tokyo uses for event notification and it allows us to react to um whatever whenever something get ready and so by registering IOuring file descriptor with e you know Tokyo runtime can react to the completion event to the um uh IO uring. So um this mean this also means that if you enable IO uring you would use both like EO and IO uring in the runtime but this strategy actually allows us to you know avoid u fusion rewrite or refactor because currently Tokyo is based on like so you know using IO uring in runtime entirely is not going to happen in near future.
So um this strategy actually allows us to make changes incrementally. So anyways this is how it works today.
Um next I want to cover some kind of um interesting findings or implementation caveats uh I found. Um so if you were so one interesting thing uh you might find when you're dealing with IOuring is uh resource management or cancel safety. Um so in IO urine uh you typically attach additional data or like something like buffer with the operation and so for example this is the uh you know kernel API like IO uring SQL and then if you look at this you know user data field and you can attach like arbitrary data to this field and then the point here is that this user data will be shared um between you know kernel and user land application like Tokyo. So this kind of um property or setup actually makes us think about cancer safety or resource management more carefully.
So um let's look at this um actual example to figure out what it means. So uh I think this is kind of typical scenario uh of uring. So you have um some IOing future like Tokyo FS read or write or whatever and this operation will submit the Iuring operation to kernel. Um but at the same time you would have like some sort of data additional data in this case buffer. Um this buffer will be shared um between kernel and userland application.
Um so what if we implemented this future in a way that you know this future owns this buffer entirely. Um so the future in Tokyo uh can be cancelled by user whenever user want to. So um if you want to so if user user just cancel the future um the buffer will be also freed if this future owns that buffer um that but that actually result in could be uh an issue because kernel still made access to this buffer back in the background. So if that's the case, you know, that would be use after free. Um so we need to somehow avoid this issue.
Um so this is how we um how we handle this uh today. So first uh if user cancel the future then you know Tokyo runtime would just drop the future. um that's it and we wouldn't drop the buffer at this point and after kernel you know send a notification to the runtime like hey this operation is just finished and then Tokyo runtime at this point Tokyo runtime can be sure that this operation um is and finally finished. So after that Tokyo will look up the relevant data and then drop the buffer um at this point. Um so this is a little bit um kind of small change but um the because of the fact that you know kernel may read the data um in background uh asynchronously uh we need to kind of sync this council or resource management carefully and I think this is kind of um interesting Um so look let's look at the uh performance uh stuff as well. Um like how to when to use like IO ringing or when to use u thread pool implementation. Um in most of the cases I would say I ring would be more performant because um so if you use normal file system APIs you're going to create a um dedicated f um thread to handle that operation. But um you know in Iuring and it doesn't happen the only thing you would do is just you know push the operation to the queue and then you know uh call one system calls um so the in the most of the cases I implementation should be more performant but um in my local benchmark uh I also found cases where you know if you submit a bunch of operations like short read or a short write with a a bunch of thread maybe you know over hundred of threads then there was a little bit slows down.
Um this might be related to the fact that you know currently we only have only one um Iuring instance in the runtime. So if you have for example a bunch of threads and then uh submit a bunch of um operations this all thread will access to this kind of global data structure uh wrapped by mutx um this might cause you know some sort of uh lock contention issue. So that said, um if you want to try out the new implementation like Iing implementation, um please um do kind of benchmark to see if you uh if thising implementation works well in your application. Um if it doesn't if it doesn't work well, um please let us know.
Um so so finally I want to quickly cover the future uh work idea we could we could um we could do to improve the current implementation um of Iuring.
So um one thing we could do is you know exposing Iuring specific um APIs uh public APIs to for for users.
Um like I said the current um Iuring is limited to file system APIs and also the way we do we do this is you know we don't break current API. Um this has some benefits from the uh composibility perspectives but um you know this also actually limits what we can do with you know IOuring. Uh, for example, like Christian mentioned in the previous talk, if if you want to do IOuring stuff on top of current Tokyo, you'd probably need to, um, define some sort of, uh, trampoline task, which is a task that wakes up other tasks. And ideally, um, we shouldn't, um, pay that kind of additional cost. So it would be nice if we could provide um a public API that allows users to um build their own Iuring operations by themsel in a more efficient or performant way. Um so um this is just one idea but we could provide this kind of API and what it does is just um essentially accept two kinds of handlers and one is about how to submit the your operation to the kernel and the other one is about um how to receive the completion event from the kernel.
Um if we could provide these kind of APIs then for example user would have like more flexible um operations and for example user might want to submit a file operation to the you know kernel and or user might want to submit network operation or even as a user might want to submit a um multiple operations in batch uh to gain a performance benefit.
it. Um so yeah, I think this is you know eventually a kind of uh flexibility we want to have in the future.
Um so next is uh network IO. So it's also challenging um goal I think but um it would be nice if we could u provide um network IO through IO ring. um network IO is more complex uh than file IO. So typically uh file system operation would be done in a oneshot operation. Um which means that when you submit the operation you would only you would receive um completion event only once but um in network you know the socket could get ready and again and again whenever you get a you know incoming net uh messages. So that might mean that we need to you know use multi-shot features from the IOuring um which has you know additional complexities and also when it comes to the network um we should be able to handle like 100 or thousand or million request um so currently like I mentioned uh we only have you know one Iuring inst uh instance in the runtime so that means that we might rearchitect the current structure to be able to have multiple links um in the runtime. So yeah, there are a couple of like um challenges here, but uh this is uh I believe this is also something we want to achieve in eventually.
So yeah, and this that's what I have.
This is the end of my talk. Um so thank you for listening.
[applause] >> [applause]
Related Videos
Agentforce NOW AMA: Build with React and Salesforce Multi-Framework
SalesforceDevs
490 views•2026-05-28
How agent o11y differs from traditional o11y — Phil Hetzel, Braintrust
aiDotEngineer
450 views•2026-05-28
WEB TECHNOLOGIES UNIT-2 | Degree 4th sem BCOM Computers web technologies unit-2 full explanation💯✅
LearnwithSahera
1K views•2026-05-29
More tests are always better? How to use AI to identify tests that bring little value
Alliance4Qualification
335 views•2026-05-29
Search Algorithms Explained in 60 Seconds! 🤖💨
samarthtuliofficial
218 views•2026-06-01
People of Game of Thrones using JavaScript DOM
AltCampus
296 views•2026-05-30
Introduction to Problem Solving Part - 1 | Lecture 1 | Intermediate DSA
ascensionix
107 views•2026-05-29
So What's Odin Lang Even Good For
TechOverTea
131 views•2026-06-01











