Skip to main content

Scaling & Concurrency

When you scale from “a few calls” to “lots of calls”, four things matter:
  • Your scheduling limits (campaign caps)
  • Concurrency controls (how many calls happen at once)
  • API rate limits (429 responses)
  • Idempotency & deduplication (safe retries for API + webhooks)

Who this is for

  • Teams launching outbound campaigns or high-volume automations.
  • Developers designing a reliable integration (no duplicate side effects).

Understand the two layers of limits

1) Campaign-level limits (batch engine pacing)

Campaign requests include:
  • max_concurrent_calls: how many calls can be in-flight at once for that campaign
  • max_calls_per_day: a daily cap for how many calls the campaign will place
  • Schedule parameters that determine when contacts are eligible:
    • timezone
    • working_days
    • start_time / end_time
These limits affect how many calls the background scheduler tries to launch.

2) API-level limits (your integration throughput)

Even if a campaign schedules successfully, your integration still might hit rate limits if you poll too aggressively or trigger too many requests at once.
  • On 429, handle retries using backoff.
  • Use idempotency keys for create/write endpoints so retries do not create duplicates.
See:

Configure concurrency safely (batch campaign example)

Here’s an example payload that sets both pacing controls:

Pause/Resume to adjust without breaking history

If you need to reduce load:
  • Use Pause to stop future scheduled calls from firing.
  • Use Resume to continue when things look good again.
This is critical for reliable operations: you avoid “half-processed” states where already-completed calls are affected. For the exact semantics, see the Public API:

Reliable retries: API and webhooks

API writes: use X-Idempotency-Key

For create/update/write operations, always send:
  • X-Idempotency-Key: <uuid>
This prevents duplicate campaign/call records when your request is retried.

Webhook receivers: dedupe by event ID

Your webhook endpoint may receive duplicates (for example after retries). Implement idempotency by:
  • Persisting the webhook id / event_id you’ve processed.
  • Ignoring duplicates.
See:

Troubleshooting scaling problems

If you see unexpected behavior, check:
  • Are you sending a unique X-Idempotency-Key on every retry?
  • Are you respecting rate limits (429)?
  • Are you increasing max_concurrent_calls gradually?
  • Are you using webhooks (push) instead of polling too frequently?

Next steps