[Tutorial] Run your own satellite (part 10) - Introducing mud and ranged-loop

$balancer.Balancer, $balancer.Drain, $balancer.Invariant

$balancer.Balancer: Rebalances disk usage across nodes within the same group (grouped by an attribute, eg: last_net, etc…), without necessarily fixing rule violations.

$balancer.Invariant: Fixes placement rule violations — e.g. two pieces of a segment ending up in the same subnet when the placement’s rules forbid that (a “clumping” violation).

$balancer.Drain: Moves pieces off specific nodes that operators want emptied (e.g. nodes being decommissioned).


All this technology is very new (Mar 2026), would be thrill to hear the use case or if storj have use this in production yet?

What is the similar and different between satellite repair and $balancer.Invariant? When to use which?

I think this is mostly about economic, with traditional RS: 29/35/80, satellite operator need to pay atleast: x29 pieces for download, upload is free, so if move fewer than 29, use balancer.Invariant, if move more, use the repair mechanic and only pay for maximum 29 pieces.

Another factor is - repair can only be trigger when heathy pieces drop below certain threshold, this give satellite more flexibility to control when to do it.

What is the different between Graceful Exit and $balancer.Drain?

The most prominent I think is GE is storagenode initiate, but drain/balance is satellite initiate, it use GET_REPAIR / PUT_REPAIR, so traffic is indistinguishable from the normal repair mechanic.

Minimum command:

./satellite-modular ranged-loop-once \
--components='$balancer.Invariant' \
--identity-dir=id/satellite \
--invariant.placement="-1" \ # -1 is all placement ids (placement 0 is the default placement)
--database-options.url="postgres://my_role:123456@127.0.0.1:26257/my_database?sslmode=verify-full&sslrootcert=ca.crt" \
--metainfo.database-url="postgres://my_role:123456@127.0.0.1:26257/my_metainfo_database?sslmode=verify-full&sslrootcert=ca.crt"
./satellite-modular ranged-loop-once \
--components='$balancer.Balancer' \
--identity-dir=id/satellite \
--database-options.url="postgres://my_role:123456@127.0.0.1:26257/my_database?sslmode=verify-full&sslrootcert=ca.crt" \
--metainfo.database-url="postgres://my_role:123456@127.0.0.1:26257/my_metainfo_database?sslmode=verify-full&sslrootcert=ca.crt"
./satellite-modular ranged-loop-once \
--components='$balancer.Drain' \
--identity-dir=id/satellite \
# --drain.node-filter \
# --drain.selector \
# --drain.placement="-1" \
--database-options.url="postgres://my_role:123456@127.0.0.1:26257/my_database?sslmode=verify-full&sslrootcert=ca.crt" \
--metainfo.database-url="postgres://my_role:123456@127.0.0.1:26257/my_metainfo_database?sslmode=verify-full&sslrootcert=ca.crt"

Note that, all this should serve as introduction, personally I don’t really know how all this work :slight_smile:.