Tweet by KentonVarda

April 11, 2026

Hello! I'm the guy to blame for all this input/output gate stuff (and durable objects generally). The intent here is you don't actually have to think about it basically ever. It's just an invisible force that works to keep your program behavior deterministic and correct. Input gates don't even matter that much anymore as storage operations are now synchronous ever since we switched to sqlite as the storage backend. Find more about synchronous storage APIs here: https://t.co/g12TrBI4RG If you use the sync APIs then *obviously* no other event can arrive in the middle of a storage call and input gates just don't matter anymore. As for output gates, you really don't have to think about them either. It's basically a speculative execution optimization, the same thing your processor does but you never thought about (er, until Spectre... never mind that). Semantically, when you write to storage, it either succeeds, or the whole durable object crashes and restarts. Storage failures are very rare, so much so that there's no reason why you should want to write code in your app to handle them. Just crashing and restarting is fine. What output gates do is allow your app to continue executing *speculatively* while the storage write is in progress. But if your app tries to communicate with the outside world, then we stop and wait to verify the storage write actually succeeded, before we allow the message to go out. This way, if the storage write fails, the outside world never knows that your app executed any code beyond that -- it appears the same as if the app just crashed on the write operation itself. What this means for you is you don't have to worry that doing several writes in series might be slow due to round trips. You don't wait for round trips. They all happen concurrently and you only wait when you send a reply to the client.

Author
KentonVarda
Date
April 11, 2026