F5-CSE study materials
F5-CSE study resources

Least Connections (member) stops distributing load after two small nodes join the pool

F5-CSE · Put your knowledge to work in context.

All case studies

Least Connections (member) stops distributing load after two small nodes join the pool

vs-shop at 10.0.0.10:443 fronts app_pool with four members. Members .21 and .22 are 16-vCPU hosts; .23 and .24 are 4-vCPU hosts added last quarter. Load balancing is Least Connections (member). Source Address Translation is Auto Map, OneConnect is enabled with a 600-second idle timeout, and the HTTP profile is standard. There are no priority groups and monitoring is a simple TCP half-open check. Since the small hosts were added, .21 sits at 92% CPU while .23 and .24 sit near 20%. When the application team asks the BIG-IP how many connections each member has, the numbers look almost even - .21 reports 610 server-side connections and .23 reports 590 - yet the application logs show .21 handling roughly five times the request rate of .23. Nothing else changed except the addition of the two small hosts, and no member has been marked down for weeks.

1. Explain why the members receive such different request rates even though the connection counts look balanced.

Read the worked answer

Two mechanisms are compounding.

OneConnect changes what a 'connection' means. With OneConnect enabled, the BIG-IP holds a pool of server-side TCP connections open and multiplexes many client requests onto them. Once a member has a warm pool of idle server-side connections, subsequent client requests reuse them instead of triggering a new load-balancing decision. The per-member connection count therefore measures pooled, mostly idle TCP connections - not requests, not CPU, not queue depth.

A faster member recycles its pooled connections more often. .21 finishes requests faster, so each of its ~610 pooled connections carries more requests per second than each of .23's. Identical counts, wildly different throughput. The counts look even precisely because OneConnect drives them toward a stable pool size that has little to do with real work.

Least Connections (member) is sampled almost never. The method is consulted when a new server-side connection is needed. Most requests never get that far, so the original, roughly round-robin placement is frozen in place. The small hosts never shed load, and the big hosts never receive more.

So the graph is not lying, it is answering a different question: 'how many sockets are parked' rather than 'who is busy'. Least Connections (node) would at least aggregate counts across every virtual server using that node, but it is still connection-based and inherits the same blindness.

2. What configuration change would you make, and how would you validate that it worked?

Read the worked answer

Recommended: Ratio (member) with weights matching capacity. Set .21 and .22 to ratio 4 and .23/.24 to ratio 1, giving an 80/20 split across the two classes. This is deterministic and does not depend on connection counts. If the load profile varies through the day, Dynamic Ratio with a performance monitor (SNMP or the F5 agent) is better, because it re-weights from measured CPU or latency rather than a static number.

Alternative: keep Least Connections but switch to (node) so the count aggregates across every virtual server that uses the node, and shorten the OneConnect idle timeout so stale pooled connections do not inflate counts. This is an improvement, not a fix: the method still cannot see request rate.

Alternative: priority groups as overflow. Put .21/.22 in priority group 1 and .23/.24 in group 2 with 'Priority Group Activation: Less Than 2'. The small hosts then only receive traffic when fewer than two big hosts are available. Trade-off: you waste 8 vCPUs of capacity, but you get predictable performance and a clean degradation story.

Validate with the right metric. Pull requests per second per member from the application logs or from AVR/analytics - never from connection counts. Watch .21's CPU, and check that .23/.24 rise to roughly the intended share. Give it a full business cycle; ratio changes look immediate in connection counts but only settle in request rate once the existing pooled connections age out.

3. Someone suggests disabling OneConnect so the connection counts become meaningful again. What are the consequences?

Read the worked answer

The counts do become meaningful, and the price is high.

Server-side connection volume explodes. Instead of a few hundred pooled connections, you get one server-side TCP connection per active client connection - potentially tens of thousands. Every one of those costs memory on the BIG-IP and on the pool member, plus CPU for the TCP state machine on both sides.

SNAT port pressure. With Auto Map, the BIG-IP translates client traffic to the egress self IP. Each member is a separate destination tuple, so you have roughly 64k source ports per self IP per member - but a heavy connection rate with short-lived connections can still exhaust translation ports and produce 'unable to create SNAT connection' errors under load spikes. A SNAT pool widens the ceiling.

More TLS and application work on the servers. If the pool members also terminate TLS, every new connection means a new handshake; that can be the difference between a comfortable and an overloaded member.

What you gain is per-request state visibility and cleaner isolation between users - real benefits if the application misbehaves when connections are shared (for example, if it caches anything per-socket).

Use it surgically: disable OneConnect only on the virtual server whose application needs it, and measure the connection and port growth before and after. Do not disable it enterprise-wide just to make a graph readable - fix the load-balancing method and the dashboards instead.