Infrarust v2.0.0-beta.2 - Load Balancing
One server, several backend addresses. Infrarust now spreads players across them, notices
which ones stopped answering, and keeps them out of rotation until they come back.
Load balancing
A server takes a list of addresses instead of a single one, and each address can carry a
weight:
# servers/lobby.toml
domains = ["play.example.com"]
balance = "least_conn"
addresses = [
{ address = "10.0.0.1:25565", weight = 3 },
{ address = "10.0.0.2:25565", weight = 1 },
"10.0.0.3:25565",
]| Strategy | What it does |
|---|---|
first_available
| Config order. Still the default, so upgrading changes nothing until you ask for it. |
round_robin
| Spreads players evenly, weights included. |
least_conn
| Sends each player to the least busy address. Best pick for a multi-address server. |
Balancing covers logins, server switches and limbo exits. Status pings use the same order,
so a dead first address no longer makes a healthy server look offline in the server list.
When a backend goes down
Infrarust learns this from real connection attempts. A few failures in a row and the
address stops receiving new players, though it stays at the very bottom of the list so a
full outage still gets a chance instead of an instant kick. It is retried later on a
backoff, and the retry comes from a background probe rather than from an unlucky player.
If every address of a server ends up down, Infrarust keeps balancing across all of them
instead of piling everyone onto the first one.
Slow start
slow_start = "45s"
slow_start_aggression = 2.0A server that just booted has a cold JIT and no chunks loaded. Slow start eases it up to
its normal share over the window you give it, rather than sending it a full load in the
first second. It applies whenever an address becomes healthy again, including a backend
the proxy just woke up itself.
Draining
Going down is what the proxy decides. Draining is what you decide, for a restart or a disk
swap:
curl -X POST -H "Authorization: Bearer $API_KEY" \
http://127.0.0.1:8080/api/v1/servers/lobby/backends/10.0.0.2:25565/drainA drained address takes no new players, and the ones already on it stay where they are, so
it empties on its own. enable puts it back, reset clears its failure history. The drain
survives a proxy restart. It is also a button in the dashboard.
Full page: https://infrarust.dev/configuration/load-balancing
Faster intercepted modes
client_only and offline still read every packet, but a packet that nothing modified is
now forwarded exactly as it arrived. Only the ones a filter or the proxy actually changes
get re-encoded and re-compressed.
For a compressed 512 B packet that is about 120 ns through the pipeline, against roughly
6 µs before. Encryption was reworked as well: decryption now computes its keystream in
batches instead of one block per byte.
The benchmark tool got the matching options, so you can measure the compressed path
yourself.
Minecraft versions and forwarding
Minecraft 26.1 and 26.2 are supported.
Velocity modern forwarding was broken in the intercepted modes and works again (#93, thanks
@Xtyling). The packet registry behind all of this was rebuilt so each packet carries its own
version mappings, which makes adding a new Minecraft version a much smaller change. A
snapshot test proves the rewrite produces byte-identical mappings.
Dashboard and API
The admin API went from mostly read-only to a real config surface. You can create, edit,
validate and delete servers, either as JSON or as raw TOML, and you can now read and rewrite
the global infrarust.toml the same way. Secrets leave the proxy redacted and are put back
when you save an untouched document, so editing a config through the web UI never wipes an
API key.
Servers that come from Docker or from your servers/ folder stay readable but refuse
writes, with a message saying which provider owns them.
New in the dashboard: a proxy config page, a backend table with per-address state
(healthy, probing, unhealthy, draining), drain and reset buttons, and a banner when
a change needs a restart. Backend health changes are pushed live over SSE.
enable_api and enable_webui are separate switches now. If you bind the API to loopback
without setting a key, one is generated at startup and logged; binding to anything else
still requires a key of your own.
Fixes and smaller changes
- Windows builds compile again, and sockets are set non-blocking properly
- systemd socket activation on Linux, which keeps the real player IP in rootless container
setups (#92, thanks @techchrism) - Plugin data folders are created when a plugin first needs one, instead of at load
(#89) - WASM plugins are enabled in the default build, so the released binaries load them with no
custom compile - Auth plugin: configurable behavior when a Mojang lookup fails, plus a real test suite
- OpenTelemetry export documented properly, with the full metric list and a collector setup
Docs
The v2 docs got a full pass. New pages: load balancing, authentication, server management,
plugin installation, in-game commands, architecture, performance tuning, zero-copy
forwarding, systemd, and a migration guide from v1.
Upgrading
Nothing to change in your configs. first_available is the default balancing strategy, so a
single-address server behaves exactly as it did in beta.1.
Two things to know if you build from source: the minimum Rust version is now 1.94, and the
wasm feature is part of the default set.
Thanks
@techchrism for socket activation, @Xtyling for the Velocity fix and the Minecraft 26.2
mappings, and everyone who reported bugs on Discord during the beta.