New Cloud Haskell transport layer based on QUIC

As my last open-source contribution of 2025, I have released network-transport-quic, a networking backend for Cloud Haskell based on the QUIC protocol.

QUIC is a protocol that is gaining popularity due in part by HTTP3. But on its own, QUIC provides several advantages in certain situations, over TCP:

  • QUIC is inherently secure, by integrating TLS (whereas TLS is an add-on for TCP connections);
  • QUIC has been designed with network migration in mind (supporting a smooth transition from e.g. WIFI to 5G, which can be important for IoT devices);
  • QUIC multiplexes streams, which improves performance for network topologies with lots of interconnections.

network-transport-quic remains experimental (not the interface, which is standard, but in terms of stability), but I hope it becomes an option as robust as the de-facto standard network-transport-tcp in the near future. If you use Cloud Haskell, I would be grateful for any experience report regarding network-transport-quic!

Happy new year!

20 Likes

This is great! What does experimental mean in practice? Just that the API may change or are there known issues/edge cases?

1 Like

The interface will not change, because it’s compliant with network-transport. Rather, it’s not clear what would happen in real world conditions including high rates of packet losses, dropped connections, etc.

I tried to be as diligent as possible with sources of exceptions, but testing is quite hard in this case!

3 Likes

Congratulations! I seem to remember you got a bit discouraged at various points during the development. Were there any puzzles that you had to figure out to make things work?

3 Likes

Yes – my main issue was figuring out what when events were supposed to be emitted.

For those out of the loop, network-transport backends emit events (e.g. ConnectionOpened, Received for data received, etc). It turns out that there are strong expectations of when these events should be emitted by network-transport-quic, which are… entirely encoded via test cases!

I did not know this initially, so I had to rewrite network-transport-quic to be quite close to the implementation of network-transport-tcp (with the addition of QUIC-related optimizations, and the removal of TCP-related optimizations).

I think it would have been helpful to:

  1. Have the tests be written such that the error is more descriptive (e.g. "Expecting event X, but got Y). For historical reasons, the test cases expectations are basically done via MonadFail, but we should be able to switch over to tasty-hunit and assertEqual.
  2. Have documented semantics for events. I recall a Cloud Haskell issue or wiki discussion on this, but now I can’t find it.

I’ll let network-transport-quic land, and test it in the field, and I hope to come back and make the experience of writing backends more straightforward.

4 Likes