Skip to content

feat: Add least (weighted) connections load balancing#821

Open
simbiont666 wants to merge 3 commits intocloudflare:mainfrom
simbiont666:least_connection_load_balancing
Open

feat: Add least (weighted) connections load balancing#821
simbiont666 wants to merge 3 commits intocloudflare:mainfrom
simbiont666:least_connection_load_balancing

Conversation

@simbiont666
Copy link

closes #144

Hi! This is my attempt at implementing a least (weighted) connections selection algorithm.

What's here

New API on LoadBalancer

I added select_with_lease() and select_with_lease_with() methods specifically for the LeastConnections selector. They work just like select() / select_with(), but return a (Backend, LeastConnLease) tuple. The lease should be held for the entire duration of the proxied request - in practice this means storing it in CTX struct and letting it drop naturally when the request completes.

State preservation across rebuilds

This was the trickiest part and the exact issue raised in #269 (2)- when LoadBalancer::update() rebuilds the selector, inflight counters must survive. The solution is LeastConnStateStore, which lives inside LeastConnectionsConfig and maps backend hashes to Weak<AtomicU32>. On rebuild, Weak::upgrade() recovers any counter that still has live references (active leases or the previous selector), so inflight counts carry over seamlessly. If you don't need state persistence across updates (static backends), the default build() path works out of the box with no extra config.

Notes

  • When backends have equal load, a rotating tie breaker provides round robin fairness
  • A new example at pingora-proxy/examples/least_connections.rs demonstrates basic usage

Let me know if anything looks off or could be done better. Thanks!

Comment on lines -86 to -91
// We pass the state store least connections through config so that
// when the selector is rebuilt, counters for unchanged backends can be reused
let mut upstreams = LoadBalancer::<LeastConnections>::from_backends_with_config(
Backends::new(discovery::Static::try_from_iter(["1.1.1.1:443", "1.0.0.1:443"]).unwrap()),
Some(LeastConnectionsConfig::new()),
);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm not sure whether I should keep the part about creating a LoadBalancer with config

for now, I removed it so the example focuses on working with lease and CTX

@drcaramelsyrup drcaramelsyrup added the enhancement New feature or request label Feb 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement least connection load balancing algorithm

3 participants