Engineering brief
Distributed protocol testing: ditch containers, use state machines
At a glance
The brief is enough
- Relevance
- Practical value
- Radar
- Time horizon
- Now
- Warnings
- None
Fly.io's team extracted protocol logic into pure state machines, simulating thousands of nodes in a single thread. Tests are deterministic, fast, and catch edge cases impossible in integration tests.
Distributed protocol testing is notoriously flaky and expensive; this pattern fixes both problems.
Watch if you are implementing or modifying a consensus, gossip, or replication protocol and want fast, reliable tests.
Summary
Core insight. Distributed protocols are deceptively simple in pseudocode but notoriously hard to test in practice. Network failures, message reordering, timeouts, and node outages create a combinatorial explosion of states that integration tests struggle to cover. Standing up thousands of containers is slow, expensive, and non-reproducible. The speaker's team at Fly.io faced this while modifying the broadcast protocol for Corrosion, their SQLite replication system.
The solution. The team extracted the protocol's core logic into a pure state machine that never touches sockets, timers, or clocks. Instead of spawning threads or setting timers, the protocol receives events and returns an outbox of actions—send this message, schedule this timer, deliver this payload—that the caller must execute. The caller provides a trait or interface that implements all side effects. This pattern is known in the industry as "sans I/O."
Testing payoff. With the protocol isolated, the test harness simulates clusters of thousands of nodes in a single thread. Events (messages, timers, node failures) are queued in a binary heap and processed in virtual time—the loop jumps to the next smallest timestamp rather than waiting. Failures are injected as events: take a node down, drop its messages, bring it back. The test becomes deterministic, fast, and fully reproducible using a seeded random generator.
Real results. The team validated modifications to the Plumb Tree gossip protocol before production deployment. They tested eager peer selection strategies, measured message delivery latency across the cluster, and confirmed behavior under various failure scenarios. The test caught edge cases that would have been impossible to reproduce in integration tests. All of this ran locally on a developer machine without containers or network dependencies.
The trade-off. This approach does not eliminate integration risk. The protocol logic is verified, but the glue code that connects it to real I/O still needs testing. If the caller blocks on a send or mishandles a timer, the system breaks. The pattern also shifts complexity to the library user, who must implement the I/O trait. For many teams, this is a worthwhile trade-off against flaky, slow, and unrepeatable distributed system tests.
Bottom line for teams. Separating protocol logic from I/O is a well-known pattern that remains underused in distributed systems engineering. It delivers deterministic tests, rapid iteration, and production confidence without expensive infrastructure. Teams building or modifying consensus, gossip, or replication protocols should consider this architectural split before investing in complex integration test suites.
My take
I've seen distributed protocol tests that take hours and fail flakily, which is why this pattern is worth attention. The sans I/O approach is not new, it's been used in networking libraries for years, but it remains rare in distributed systems teams. What I appreciate here is the honest trade-off: the protocol logic is clean, but the I/O layer still carries risk. I'd add that teams should invest in integration tests for the glue code, not just the protocol state machine. The virtual time simulation is the real highlight, it makes testing fast enough that developers actually run it. This is a pattern worth adopting for any team touching distributed protocols.
What to do with this
- Audit your distributed protocol code for entanglement of logic and I/O; identify the boundary.
- Prototype a state machine with explicit event-in/action-out interface for one protocol component.
- Build a deterministic test harness with virtual time to replace your slow integration test suite.
Watch the video
This video is blocked due to your privacy settings. To watch this video, please accept YouTube marketing cookies.
Related breakdowns
Application-driven infrastructure: Stop pre-building environments, start deploying on demand
Pre-provisioned infrastructure creates idle costs and deployment queues. Application-driven infrastructure provisions environments on demand, reducing waste…
OpenAI's finance lead: MCP error rates hit 40% — bundle data yourself
OpenAI's finance product lead reveals MCPs are unreliable, evals are broken, and 95% of what they built is replicable by startups.
DoorDash shows why LLM distillation beats real-time serving
DoorDash's search team doesn't call LLMs online. They distill reasoning into offline primitives—graded labels, semantic IDs, memory blocks—that every…
Get TL;DW
Too Long; Didn't Watch.
A concise breakdowns of the AI and devtools videos that actually matter for engineering leaders.
Free. Weekly. No hype.
Video and thumbnails remain the property of their respective creators. tldw.news provides editorial analysis, commentary, and discovery links to original content.