Sōzu 2.1.0: UDP load balancing for the programmable edge

2026.07.01 Clever Cloud Bannière Blog Sōzu 2.1.0 EN
Sōzu is the open-source reverse proxy and load balancer that sits in front of every application running on Clever Cloud.

We lead the project and are its principal contributor (github.com/sozu-proxy/sozu). With Sōzu 2.0, we explained how the proxy moved from “reverse proxy” toward “programmable edge”: a new HTTP/2 multiplexer, stronger security defaults, a larger observability surface, traffic policies, operational hardening, and crypto agility.

Sōzu 2.0.2 came a few days later with a smaller but revealing release. It added defence-in-depth against the HTTP/2 bomb class and fixed the timestamp foundation needed to reconstruct trustworthy OpenTelemetry spans from access logs. That release showed how we want to operate the edge: when a protocol-level attack class appears, the proxy should absorb as much of it as possible; when observability is subtly wrong, the foundation should be fixed before product features are built on top.

Sōzu 2.1.0 is the next step in that same story. One of the pieces we described as “on the bench” for 2.0 has landed: first-class UDP load balancer support.

This is not just one more protocol checkbox. Sōzu already handled HTTP, HTTPS, and TCP. With 2.1.0, UDP becomes part of the same model: the same hot-reconfigurable control plane, the same operator-facing posture, the same metrics discipline, and the same open-source release process. That widens Sōzu from a web edge into a broader infrastructure load balancer, able to front datagram services such as DNS, syslog, NTP, and generic UDP workloads without forcing operators to put a second load balancer in front of it.

For Clever Cloud, this matters because platform networking is broader than HTTP. Managed Kubernetes and PaaS both need a clean story for direct transport traffic. For operators running Sōzu themselves, it means one component can cover more of the L4/L7 surface while preserving the design properties that made Sōzu useful in the first place.

Why UDP still matters

Most user-facing traffic on the web goes through HTTP, and it is tempting to treat everything else as a special case. Real platforms do not get that luxury.

DNS is UDP by default. Syslog often runs over UDP. NTP is UDP. Many internal and infrastructure protocols use datagrams because they are simple, latency-sensitive, or request/response shaped enough that a full TCP connection is unnecessary. Kubernetes platforms and PaaS products also need to expose direct transport services cleanly, not only web applications that terminate at HTTP.

Before Sōzu 2.1.0, an operator wanting a single edge for HTTP, TCP, and UDP usually had to compose multiple systems. Sōzu could handle the HTTP and TCP side, while a separate component handled UDP. That split carries operational cost: two models of health checking, two ways to observe traffic, two release cycles, two failure surfaces, two sets of configuration, and two places where routing state can drift.

The point of first-class UDP in Sōzu is convergence. A UDP listener now sits beside tcp, http, and https listeners. UDP frontends and backends are part of the same command, configuration, and state machinery. Operators get UDP-specific metrics at the proxy instead of treating datagram traffic as something happening off to the side.

The customer-facing benefit is not that every application suddenly needs UDP. It is that the platform can converge more traffic classes under one operational model: hot reconfiguration, health awareness, metrics, release discipline, and a single edge component that can evolve toward product features rather than remaining a pile of protocol-specific exceptions.

What is available in Sōzu 2.1.0

Sōzu 2.1.0 adds a new protocol = “udp” listener type alongside the existing HTTP, HTTPS, and TCP listeners. It is opt-in. Existing configurations do not become UDP-aware by accident, and existing sozu-command-lib consumers can move from 2.0.2 to 2.1.0 without rewriting their integrations.

The central idea is to model UDP traffic as virtual flows. UDP itself has no connection, no stream, and no accept loop. A datagram arrives on one socket. There is no kernel-created per-client socket like there is with TCP. Sōzu therefore reconstructs the useful part of a connection in userland: a flow keyed by the client source address, optionally including the source port when that is the right affinity model for the workload.

Once Sōzu has a flow, it can make the same class of decisions a load balancer has to make for any transport:

  • which backend owns this client;
  • how long this flow should stay alive;
  • what happens when a backend becomes unhealthy;
  • how overload should be shed;
  • what metrics and logs should be emitted.

The release adds two flow-affine algorithms for UDP. The recommended default is HRW, also known as rendezvous hashing. HRW has a property that matters a lot for hot-reconfigurable systems: when the backend set changes, it minimizes movement without requiring a precomputed lookup table. Sōzu also ships Maglev as an opt-in algorithm for larger backend sets or higher packet rates where an O(1) table lookup is more attractive.

Sōzu can also send PROXY protocol v2 information to UDP backends. This carries the real client address to the backend, so the backend does not have to treat the proxy as the only visible peer. By default, Sōzu sends it on the first datagram of a flow, with an opt-in mode to send it on every datagram when the backend needs that context repeatedly.

Health checking is part of the UDP design rather than an afterthought. A UDP backend can be checked through a companion TCP probe, which is the common practical liveness signal for services where bare UDP does not provide a reliable “connected” state. Sōzu can also use an application-level UDP probe when that is meaningful. The checks support rise/fall hysteresis and fail-open semantics, so a transient or global health-check failure does not automatically black-hole traffic.

Finally, UDP gets its own metric surface: datagrams in and out, bytes in and out, active flows, created, evicted, or shed flows, dropped datagrams by reason, backend health, and flow duration. This follows the same principle as the 2.0 observability work: a feature is not production-grade until operators can see what it is doing.

UDP is easy to add badly

The hard part of UDP load balancing is not receiving a datagram and sending it somewhere else. The hard part is deciding what state exists around that datagram.

TCP gives a proxy a connection lifecycle. HTTP gives it requests, responses, headers, and status codes. UDP gives it packets. Packets can arrive out of order. They can disappear. A client can stop sending without closing anything, because there is nothing to close. A backend can become unhealthy while a virtual flow still points to it. A reconfiguration can arrive while flows are active. A listener can reach its flow cap. A timeout can fire just after the flow was refreshed. These are not exotic cases. They are the normal shape of datagram traffic under load.

That is why the Sōzu 2.1.0 UDP work is as much about testability as it is about features.

The UDP core is structured around a sans-io split. The pure core owns the flow table, admission decisions, timers, teardown policy, and load-balancing requests. The impure shell owns sockets, the buffer pool, health checks, syscalls, and metrics emission. The core has no socket, no wall-clock read on the datapath, no random source hidden inside it. Time and seeds are injected.

That shape matters because it makes the core deterministically simulatable. The same seed drives the same sequence. The same virtual clock jumps to the same instants. The same reconfiguration storm happens at the same step. A failure can print a seed and be replayed exactly.

Sōzu 2.1.0 ships a FoundationDB/VOPR-style deterministic simulation harness for the UDP core. The default sweep runs 256 seeds, each driving a randomized adversarial workload through client datagrams, backend replies, stale backend resolutions, reconfiguration bursts, flow-cap changes, clock jumps, drains, and mass teardown. After each action, the harness drains the core outputs and checks model invariants.

On top of that, the release includes an assertion-density sweep inspired by TigerBeetle’s TigerStyle. Across the proxy, command plane, and supervisor, Sōzu now carries roughly 1100 debug_assert! checks and multiple invariant sweeps. These assertions are compiled out of release builds, but they are live in tests, fuzzing, end-to-end runs, simulations, and developer builds. They turn a silent state drift into a loud, local failure.

Those numbers are useful because they are not volume metrics. Lines of code do not prove reliability. A 256-seed simulation sweep and dense invariants do tell you something: the code is being driven through adversarial state transitions, and the data structures are continuously asked to prove that they still make sense.

For a proxy, that distinction matters. A wrong counter is not just a counter. It may mean a flow is leaked. A stale timer is not just a timer. It may mean a backend keeps receiving traffic after the state says otherwise. A silent mismatch between a routing table and a slab is not just an internal inconsistency. It is the kind of thing that becomes a production symptom several layers away from the bug.

Deterministic simulation as a direction

The UDP simulator is also a signal about where we want Sōzu engineering to go next.

FoundationDB made deterministic simulation famous in infrastructure software: run the system inside a simulated world, inject failures, explore thousands of schedules, and make every failure reproducible from a seed. TigerBeetle pushes a complementary discipline: state your invariants directly in the code, assert both the positive and the negative space, and make illegal state impossible to ignore during testing.

Sōzu 2.1.0 applies those ideas to the UDP core. The next architectural effort is to make more of Sōzu fit this shape: more sans-io components, more injected clocks and deterministic boundaries, more layers that can be simulated across the relevant parts of the OSI stack before they are exposed as production behavior.

This is also why Moonpool matters to Clever Cloud. Moonpool, developed by PierreZ, is the deterministic-simulation engine we use at Clever Cloud for this direction in Rust. Version 0.7.0 has now landed publicly on crates.io, including moonpool and moonpool-sim. Sōzu’s UDP harness is currently an in-tree synchronous simulator shaped around the pure UDP core, but the broader direction is the same: deterministic workloads, virtual time, reproducible seeds, and networked systems that can be made to fail before production gets the chance.

The primary benefit is reliability. We want fewer edge-case bugs in protocol and reconfiguration code. The second benefit is velocity. When more of the proxy is structured as pure state machines with explicit I/O boundaries, new protocol and load-balancing behavior becomes safer to evolve. The third benefit is operability. Hot reload, overload, and failure behavior become easier to reason about because the code has been exercised under those exact shapes.

That is the next layer under the programmable edge. The knobs exposed to users are only worth exposing if the machinery beneath them is deterministic enough to trust.

What this unlocks

For managed Kubernetes, UDP support gives Sōzu a stronger basis for direct transport services. A platform can offer web traffic, TCP services, and UDP services under a more coherent load-balancing model, rather than splitting responsibilities between unrelated components.

For PaaS, it opens the way to product features around datagram workloads without starting from a separate operational stack. DNS-like services, syslog-like flows, NTP-like probes, and generic UDP applications can be reasoned about through the same proxy vocabulary: listeners, clusters, backends, health, metrics, and hot reconfiguration.

For self-hosted Sōzu operators, it means the project covers more of the infrastructure edge. If you already use Sōzu because you want an open-source, hot-reconfigurable proxy with signed releases and a Rust codebase you can audit, 2.1.0 expands the class of traffic you can bring under that umbrella.

There is an observability consequence too. UDP traffic now has native proxy metrics. You can ask how many flows are active, how many were shed, why datagrams were dropped, whether backends are healthy, and how long flows live. This is what turns a protocol feature into something operators can run.

Reliability also comes from the release around UDP

The headline is UDP, but 2.1.0 also continues the operational work from 2.0.

Hot reconfiguration is one of Sōzu’s core promises, so state replay correctness matters. This release fixes a case where a listener whose configuration changed while it remained active could be replayed as remove plus add without re-emitting activation. That kind of bug is exactly why the state model has to be tested as a lifecycle, not only as isolated commands.

The release also fixes an arithmetic-underflow panic in the pattern trie for hostnames whose leftmost segment is a regex. It fixes the release pipeline by pinning the cosign binary to the 2.x line, after a tooling change broke the signature artifact flow during the 2.0.2 release.

These are not the parts of the release that users will see first. They are still part of the product. At Clever Cloud’s scale, operational quietness is a customer benefit. A proxy that reconfigures safely, signs its artifacts predictably, and turns edge cases into tests is a proxy that lets applications keep serving traffic while the platform moves underneath them.

What comes next

UDP support will continue to mature with real-world use. There is room for performance work, batching, and broader operational feedback. But the larger direction is architectural: make more of Sōzu deterministic, make more of it sans-io where that makes sense, and make more failure modes reproducible before they can become incidents.

That is the lesson from Sōzu 2.1.0. The programmable edge is not only a set of user-facing toggles. It is also a way of building infrastructure software: protocol by protocol, state machine by state machine, with enough observability to operate it and enough simulation to trust it.

Sōzu is open source under AGPL-3.0, with its command library under LGPL-3.0. The code, release notes, issues, and design discussions live at github.com/sozu-proxy/sozu. Thank you to the contributors and operators who keep pushing the project toward a broader, safer, more programmable edge.


References

Sōzu

Protocols and algorithms

Testing

Blog

À lire également

Sōzu 2.1.0: UDP load balancing for the programmable edge

Sōzu is the open-source reverse proxy and load balancer that sits in front of every application running on Clever Cloud.
Company

Clever Cloud introduces the Ultimate Sovereignty Clause to guarantee lasting digital sovereignty

Clever Cloud is introducing the Ultimate Sovereignty Clause, a contractual mechanism designed to ensure that a cloud service remains sovereign within a European framework, even if its provider were to come under non-European control.
Company

Clever Cloud opens the private beta of Openvisio, the sovereign video conferencing solution operated in Europe

Clever Cloud opens the private beta of Openvisio, its sovereign video conferencing solution operated in Europe. Apply to test the add-on in your organization.
Company