Skip to content
InfiQ glossary · Reference sheetReliability & scale

Load Balancing

Spreading incoming webhook and API requests across several healthy server instances so that none is overloaded and a failed one stops receiving traffic.

Properties

Term
Load Balancing
Abbreviation
None
Level
Foundation
Audience
Developers
Reviewed
Also called
Load balancer · Traffic distribution

01 · Definition

What is load balancing?

Load balancing is distributing incoming requests across a pool of servers (instances, containers or pods) so that each handles a fair share and the service keeps running when one of them fails. A load balancer sits in front of the pool at a single address. For a WhatsApp integration that address is usually your webhook callback URL and your internal send API: Meta POSTs every inbound message and status to one HTTPS URL, and the load balancer decides which webhook receiver handles each request.

Two choices define a load balancer. The algorithm picks who gets the next request: round-robin takes turns, weighted round-robin favours bigger instances, least-connections picks the instance with the fewest open requests, and hash-based routing (consistent hashing) sends the same key, such as a wa_id or a tenant, to the same instance. The Health Check decides who is eligible at all: the balancer probes each instance, or counts its failed responses, stops sending traffic to one that fails, and adds it back once it recovers.

Load balancers also work at different layers. A layer 4 (TCP) balancer forwards connections without reading them. A layer 7 (HTTP) balancer terminates TLS, reads paths and headers, and can route /webhooks/whatsapp and /api/sends to different pools. Load balancing spreads traffic over the capacity you already have; Horizontal Scaling adds capacity to the pool, and together they are the basis of High Availability, with Failover covering the switch to a standby when a whole tier fails.

Key takeaways

  • Load balancing spreads requests across a pool of instances behind one address, so no instance is overloaded and failures are routed around.
  • The algorithm decides who gets the next request; the health check decides who is eligible at all.
  • Least-connections is a sound default for webhook receivers, whose requests vary in cost.
  • The balancer must pass the raw body unchanged, or X-Hub-Signature-256 verification fails.
  • Load balancing spreads traffic over existing capacity; horizontal scaling adds the capacity.

See InfiQ pricing

02 · Specifications

Load balancing: key facts and limits

Common algorithmsRound-robin, weighted, least-connections, consistent hash
Layer 4 vs layer 7TCP forwarding vs HTTP-aware routing with TLS termination
Health check typesActive probes and passive failure counting
Webhook payload sizeUp to 3 MB: raise body-size limits
Signature checkRaw body must reach the app unchanged
Meta on failed webhooksRetries with decreasing frequency for up to 7 days

03 · Operation

How does load balancing work?

  1. Put one address in front of the pool

    Register the load balancer's HTTPS URL as the webhook callback URL. TLS, with a valid CA-signed certificate, terminates at the balancer or passes through to the instances.

  2. Choose an algorithm

    Least-connections suits webhook receivers, whose requests vary in cost. Round-robin is fine when every request is cheap and the instances are identical. Consistent hashing on a key keeps related work on one instance.

  3. Configure health checks

    Probe a readiness endpoint every few seconds and remove an instance after a few consecutive failures. Readiness should reflect the instance itself, such as whether it can reach its queue, not whether Meta's API is slow.

  4. Drain before removing

    On deploys and scale-in, stop sending new requests to an instance but let in-flight ones finish (connection draining), so no webhook is cut off half-way and retried.

  5. Pass the request through intact

    Forward the raw body unchanged so X-Hub-Signature-256 still verifies, pass the client address in X-Forwarded-For, and raise body-size limits: WhatsApp webhook payloads can reach 3 MB.

04 · Code samples

Load balancing in code

# /etc/nginx/conf.d/whatsapp-webhooks.conf
upstream webhook_receivers {
least_conn; # fewest active requests wins
server 10.0.1.11:3000 max_fails=3 fail_timeout=10s;
server 10.0.1.12:3000 max_fails=3 fail_timeout=10s;
server 10.0.1.13:3000 max_fails=3 fail_timeout=10s;
keepalive 32;
}
server {
listen 443 ssl;
server_name hooks.example.in;
ssl_certificate /etc/ssl/hooks.example.in.pem;
ssl_certificate_key /etc/ssl/hooks.example.in.key;
client_max_body_size 4m; # webhook payloads can reach 3 MB
location /webhooks/whatsapp {
proxy_pass http://webhook_receivers;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 10s;
# Once a POST has reached an upstream, NGINX does not replay it on
# another server (unless non_idempotent is added). Keep it that way:
# your handler, not the balancer, owns retries.
proxy_next_upstream error timeout;
}
}

Open-source NGINX marks a server failed passively (max_fails within fail_timeout); cloud balancers and orchestrators probe a readiness endpoint actively.

05Playground

A working model of Load Balancing. Use its controls to replay it step by step.

Route ten webhooks: which instance takes each one?

10 / 10

Gives each chat to whoever has the fewest open conversations right now.

Incoming · 0 left

  1. All 10 conversations have been routed.

Conversation 10 of 10 · Least busy

wa 64018 · status deliveredgoes toMedia 3

Least busy: Media 3 has the fewest open chats (3 of 4).

  • Web 1

    3 of 3 open

    Full
    • Generalist
    1. wa 77310 · inbound text
    2. wa 77310 · status delivered
    3. wa 90233 · inbound documentneeds media(skill mismatch)
  • Web 2

    3 of 3 open

    Full
    • Generalist
    1. wa 98201 · status read
    2. wa 64018 · inbound text
    3. wa 98201 · inbound reply
  • Media 3

    4 of 4 open

    Full
    • media
    1. wa 98201 · status delivered
    2. wa 55102 · inbound imageneeds media
    3. wa 55102 · status read
    4. wa 64018 · status delivered

Waiting · 0

  1. Nobody waiting: every conversation found an agent.
Same 10 conversations, each strategy
StrategyRoutedWaitingSkill mismatches
Least busy1001
Round-robin1002
Sticky1002
Skills-based1000
Each card is a webhook receiver instance with room for a few concurrent requests; each chip is a request from Meta. Switch between round-robin, least-connections, consistent hashing on wa_id (sticky) and path-based routing of media to its own pool.

Conversation 10 of 10, wa 64018 · status delivered: Least busy: Media 3 has the fewest open chats (3 of 4).

06 · Cautions

Common mistakes with load balancing

  • Health checks that call Meta

    If readiness depends on the Graph API, one slow Meta response marks every instance unhealthy at once and the balancer has nowhere to send traffic. Check only what the instance itself controls.

  • Retrying POSTs at the balancer

    Letting the balancer replay a webhook or send request on another instance after a timeout can process it twice. Keep retries of non-idempotent requests off at the balancer and handle them in code.

  • Sticky sessions as a crutch

    Pinning users to instances hides state that belongs in a shared store, and unbalances the pool when one big tenant is busy. Keep receivers stateless and use hashing only where ordering truly needs it.

  • Default body limits and timeouts

    Many proxies cap bodies at 1 MB and close idle connections after 60 seconds. Raise the limit for 3 MB webhook payloads, and align timeouts across balancer, app and client.

  • Killing instances without draining

    Removing an instance mid-request cuts webhooks off and triggers Meta retries and duplicates. Fail readiness first, wait for in-flight requests to finish, then stop.

07 · Rationale

Why does load balancing matter?

Meta delivers webhook traffic in bursts: a broadcast to 50,000 customers produces a wave of sent, delivered and read statuses within minutes, and Meta retries any request that does not get a timely 200. A single receiver is both a bottleneck and a single point of failure, so one crash or deploy and statuses start backing up. A load balancer with honest health checks keeps the endpoint answering through deploys, crashes and spikes. That is what keeps your Webhook Acknowledgement fast and your delivery data fresh.

08 · Worked example: One receiver fails during a renewal campaign

Example: One receiver fails during a renewal campaign

A Chennai insurance broker runs three webhook receivers behind a layer 7 load balancer using least-connections. During a renewal-reminder broadcast, status webhooks climb from 20 to 600 requests a second. One receiver loses its queue connection; its readiness probe fails twice in ten seconds, and the balancer stops routing to it while the other two absorb the traffic. Meta sees nothing but fast 200 responses. The failed instance reconnects, passes its probe and rejoins the pool, with no events lost and no retry storm.

09 · Recommended practice

Best practices for load balancing

  • Run at least three instances across two availability zones, so one failure still leaves headroom.
  • Alert on the number of healthy instances, not only on error rates.
  • Log the instance ID with every request so a bad node is easy to spot.
  • Load-test through the balancer, not around it: its limits are part of your capacity.

10 · Questions and answers

Load Balancing FAQs

Do I need a load balancer for a WhatsApp webhook?
Not on day one, but yes once uptime matters. A single receiver is a single point of failure; two or more instances behind a balancer keep webhooks answering through crashes, deploys and broadcast spikes.
What is the difference between load balancing and horizontal scaling?
Horizontal scaling adds instances; load balancing spreads requests across them. You need both: extra instances are useless if traffic cannot reach them, and a balancer cannot rescue a pool that is too small.
Which load-balancing algorithm should I use for webhooks?
Least-connections is a sound default for webhook receivers. Their requests vary in cost (media, batched statuses), so sending each one to the least busy instance evens out load better than strict round-robin.
Will a load balancer break X-Hub-Signature-256 verification?
Not if it passes the body through unchanged. Signature checks fail when a proxy re-encodes, decompresses or rewrites the body; plain HTTP proxying that keeps the raw bytes verifies normally.

Put Load Balancing to work

InfiQ is an official Meta Business Partner. Start a 7-day free trial — no card needed — and see this running on your own number.