Skip to content

This term

Horizontal Scaling

Handling more load by adding more instances of a service rather than a bigger machine, which works best when each instance is stateless and interchangeable.

Also called: Scaling out · Scale-out · Horizontal autoscaling

Often confused with

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.

Read the Load Balancing entry

Add workers until the backlog stops growing

20× slow motionService time S = 80 ms per job on average · 3 workers

Queue diagram: 12 messages waiting, 3 of 3 workers busy, 7 done, 1 failed → dead-letter queue.

Backlog
∞
grows without bound
Throughput
38/s
36.8/s done · 0.8/s failed → dead-letter queue
Average wait
∞
keeps growing
Utilisation ρ
1.33
≈ 3 of 3 busy
50 messages/s
3

ρ = λ × S ÷ c = 50/s × 80 ms ÷ 3 = 1.33

Backlog grows without bound. ρ = 1.33 ≥ 1: messages arrive faster than 3 workers can finish them. Add workers, speed up each job or slow the producer.
50 messages a second arrive and each send takes 80 ms, so three workers fall behind. Drag the worker slider to find where the queue starts to drain; on WhatsApp, the per-number throughput cap is the next ceiling.

Utilisation is at or above 1: the backlog grows without bound.

What is horizontal scaling?

Horizontal scaling, or scaling out, means handling more work by running more copies of a service side by side: more API instances behind a load balancer, more workers pulling from a queue. Vertical scaling, or scaling up, means moving the same single instance to a bigger machine with more CPU and memory. Scaling out has no hard ceiling in principle, adds redundancy (the basis of high availability) as a side effect and can follow demand up and down automatically; scaling up is simpler but tops out at the largest machine and leaves a single point of failure.

Scaling out works when instances are interchangeable, which means stateless. On a WhatsApp backend the stateless parts (the webhook receiver, the send API, the workers that call the Cloud API) scale out easily. The stateful parts need work first: conversation and session state must live in a shared store rather than in memory, scheduled broadcasts must run on exactly one instance, per-conversation order must be kept by partitioning work by the customer's wa_id, and every new instance opens more database connections.

WhatsApp adds a ceiling that no number of servers can lift: throughput (MPS) is set per business phone number, up to 80 messages per second by default and 1,000 after Meta's automatic upgrade for eligible numbers. Workers beyond that rate just collect Error 130429 (Rate Limit Hit). Scaling a WhatsApp sender therefore means scaling workers up to the cap, sharing a rate limiter across them, and adding phone numbers or qualifying for the upgrade when one number's cap is the bottleneck.

Horizontal scaling is often mentioned alongside load balancing, which spreads incoming requests across instances, and a message queue, which lets workers share a backlog. Scaling decides how much capacity exists; balancing and queueing decide how work reaches it. Load testing is how you find out where scaling out stops helping.

Key takeaways

  • Horizontal scaling adds more instances to share the load; vertical scaling makes one instance bigger.
  • Stateless API servers and queue workers scale out easily; sessions, locks, schedulers and ordering need shared state first.
  • More workers cannot beat a number's throughput: up to 80 messages per second by default, 1,000 after Meta's upgrade, with error 130429 beyond it.
  • Autoscale messaging workers on queue depth or age, not CPU, and cap the maximum at what downstream limits allow.
  • Horizontal scaling adds capacity; load balancing spreads traffic across it.

Why the difference matters

Why does horizontal scaling matter?

Message traffic is spiky: a Diwali campaign, a payday reminder run or a viral Click-to-WhatsApp ad can multiply volume tenfold in minutes. A backend that only scales up either sits on an oversized machine most of the year or falls over on the busiest day. Scaling out lets capacity follow demand, survives the loss of any one instance, and keeps costs closer to actual use. Knowing its limits, above all the per-number throughput cap, stops teams from paying for servers that cannot make a broadcast any faster.

How does horizontal scaling work?

  1. Step 1

    Make instances stateless

    Move sessions, conversation state, idempotency records and caches to a shared store such as Redis or the database, so any instance can handle any request.

  2. Step 2

    Put a queue between intake and sending

    The API and webhook receiver enqueue work and return quickly; a pool of workers drains the queue. Each side then scales on its own signal.

  3. Step 3

    Partition to keep order

    Route all jobs for one conversation to the same partition or ordered group by the customer's wa_id, so adding workers does not shuffle a customer's messages.

  4. Step 4

    Share limits across instances

    Enforce each phone number's messages-per-second budget with a shared limiter (the token bucket algorithm in Redis, for example), not a per-process one that multiplies with every new worker.

  5. Step 5

    Autoscale on the right signal

    Scale workers on consumer lag (queue depth or the age of the oldest job), keep a minimum of two for redundancy, and cap the maximum at what the throughput limit and database connections allow.

Example: A Bengaluru D2C brand's festive send

A Bengaluru skincare brand plans 300,000 marketing templates across two phone numbers, each at the default 80 messages per second, so 160 per second is the most the sends can go. Its first run autoscaled workers on CPU to 40 replicas; most of them spent the campaign receiving 130429. The second run scaled on queue depth with a maximum of 12 workers, a shared token bucket per phone_number_id set just under each number's limit, and a database connection pooler in front of Postgres. Throughput held at about 155 per second and the send finished in roughly 32 minutes without a throttling spike.

Horizontal scaling in code

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata: { name: wa-send-worker }
spec:
scaleTargetRef: { apiVersion: apps/v1, kind: Deployment, name: wa-send-worker }
minReplicas: 2 # redundancy even when idle
maxReplicas: 12 # beyond this, the per-number throughput cap is the limit
metrics:
- type: External # needs an external-metrics adapter for your queue
external:
metric:
name: queue_messages_ready
selector: { matchLabels: { queue: wa-send } }
target:
type: AverageValue
averageValue: "500" # aim for ~500 waiting jobs per worker

Scale workers on the backlog, with a floor for redundancy and a ceiling set by downstream limits.

Horizontal scaling: key facts and limits

Horizontal (scale out)
More instances; needs stateless, interchangeable services
Vertical (scale up)
A bigger machine; simple, but capped and a single point of failure
Per-number throughput
Up to 80 mps by default, 1,000 after Meta's upgrade
Over the throughput cap
Error 130429
Coexistence numbers
20 mps, incoming and outgoing combined
Sizing rule (Little's law)
Busy workers = arrivals per second x seconds per job

Common mix-ups

Common mistakes with horizontal scaling

  • Scaling past the downstream cap

    Doubling workers does not double sends once a number is at its throughput limit; it only produces 130429 errors and retries. Cap autoscaling at the limit and add numbers or qualify for the upgrade instead.

  • Hidden state in memory

    In-memory sessions, local caches of conversation state and cron jobs inside the app break or run twice when a second instance appears. Externalise state and run schedulers with a lock or leader election.

  • Running out of database connections

    Twenty instances with a pool of 20 each is 400 connections, more than many databases allow. Use a connection pooler and size pools from the database's limit downwards.

  • Autoscaling on CPU

    Send workers spend most of their time waiting on the network, so CPU stays low while the queue grows. Scale on queue depth or oldest-job age instead.

  • Breaking per-conversation order

    With many workers, two messages to the same customer can be sent out of order. Partition by wa_id or use ordered message groups so each conversation is handled in sequence.

Rules of thumb

Best practices for horizontal scaling

  • Load test with a mock of the Cloud API to find your real ceiling before a big campaign.
  • Scale the webhook receiver separately from send workers; inbound bursts and outbound campaigns peak at different times.
  • Keep at least two instances of everything, even at night: scaling out is also your redundancy.
  • Watch time-to-drain (queue depth divided by send rate) during campaigns, not only replica counts.

Horizontal Scaling FAQs

What is the difference between horizontal and vertical scaling?+
Horizontal scaling adds more machines; vertical scaling makes one machine bigger. Scaling out needs stateless services but has no hard ceiling and adds redundancy, while scaling up is simpler but tops out at the largest instance.
Will adding more servers make my WhatsApp broadcast faster?+
Only up to the throughput of the phone numbers you send from. Each number sends up to 80 messages per second by default, so past that point extra workers only produce error 130429; add numbers or qualify for the 1,000 mps upgrade instead.
What should I autoscale WhatsApp send workers on?+
Queue depth or the age of the oldest job, not CPU. Workers are I/O-bound, so CPU stays low while the backlog grows; set a minimum of two replicas and a maximum based on throughput and database limits.
Is horizontal scaling the same as load balancing?+
No. Horizontal scaling adds capacity; load balancing distributes requests across that capacity. You usually need both: more instances, and a balancer with health checks deciding which of them receive traffic.
When is vertical scaling the better choice?+
For stateful pieces that are hard to split, such as a primary database, and for small systems. Moving to a bigger database instance is often simpler than sharding, as long as you also run a standby for failover.

See InfiQ pricing

Try it on the official WhatsApp Business API

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