IP Hash load balancing makes it look like your users are always talking to the same server, even though they might be hitting different ones behind the load balancer.

Let’s watch it in action. Imagine we have two web servers, 192.168.1.10 and 192.168.1.11, and a load balancer at 192.168.1.5. We’ll use haproxy for this.

Here’s a basic haproxy.cfg:

frontend http_frontend
    bind *:80
    mode http
    default_backend http_backend

backend http_backend
    mode http
    balance iphash
    server web1 192.168.1.10:80 check
    server web2 192.168.1.11:80 check

Now, if you make requests from two different client IP addresses, say 10.0.0.1 and 10.0.0.2, to 192.168.1.5:80:

  • Requests from 10.0.0.1 will consistently go to either 192.168.1.10 or 192.168.1.11.
  • Requests from 10.0.0.2 will consistently go to the other server.

The balance iphash directive is the magic here. It takes the client’s IP address, hashes it, and uses the resulting hash value to consistently pick a backend server. This means all requests from a single client IP will always be directed to the same backend server, as long as that server is available.

This is incredibly useful for applications that store user session data client-side (like in a cookie) or rely on in-memory session state on the server. If a user’s requests bounce between servers, their session data might be lost, leading to a broken experience. IP Hash ensures that once a user is assigned to a server, they stay with that server for the duration of their session.

The core problem IP Hash solves is maintaining session state without a centralized, shared session store. While solutions like Redis or Memcached for session management are robust, they add complexity and a single point of failure. IP Hash offers a simpler, albeit less flexible, way to achieve session persistence by leveraging the client’s IP address as the session identifier.

Internally, haproxy (or any load balancer using this method) applies a hashing algorithm to the source IP address of the incoming connection. This algorithm produces a numerical output. This number is then typically mapped (often using a modulo operation) to the available servers in the backend pool. The result is a deterministic mapping: the same input IP address will always produce the same output server.

The exact hashing algorithm can vary between load balancers, but the principle remains the same. For example, haproxy uses a CRC32-based hashing by default for balance iphash. The hash_type option can be used to specify different hashing algorithms like consistent (for better server rebalancing) or map (to use a pre-defined mapping file).

The key levers you control are the balance algorithm itself, and potentially the hash_type and hash_map parameters if your load balancer supports them. For instance, with haproxy, you could specify balance ipv6 if you’re dealing with IPv6 addresses, or balance source which is a more generic term for IP-based hashing.

If you’re using balance iphash and add or remove servers from your backend pool, you might see a significant redistribution of traffic. This is because the modulo operation will change when the number of available servers changes. For example, if you had 3 servers and a hash value of 10, it might map to server 1 (10 % 3 = 1). If you add a fourth server, that same hash value of 10 now maps to server 2 (10 % 4 = 2). This can temporarily disrupt sessions for a portion of your users until they establish new connections. This is why balance consistent (also known as Ketama hashing) is often preferred for its ability to minimize disruption during server pool changes.

The next concept you’ll likely encounter is how to handle clients behind a NAT gateway, where multiple users share a single public IP address.

Want structured learning?

Take the full Load-balancing course →