Bulk enrollment, a big import, a list-based re-sync, a data cleanup, can trigger a workflow on thousands of records almost simultaneously. If that workflow calls an external API through a custom code action or webhook, every one of those enrollments can fire a request in a tight window and blow past the receiving system's rate limit. The fix is pacing enrollment-triggered requests over time instead of letting them fire in a burst.
In This Article
Why this happens
HubSpot workflows can enroll a large batch of records almost simultaneously: a bulk import, a list-based enrollment, a re-sync after a data cleanup. If that workflow calls an external API (a custom code action, a webhook, a third-party integration), every one of those enrollments can fire a request in a tight window. Most external APIs, and HubSpot's own API, enforce rate limits per ten-second or per-day window. Blow past that limit and requests start getting rejected.
The result is inconsistent, hard-to-reproduce failures: some contacts process fine, others silently don't, and the pattern looks random unless you're specifically comparing enrollment timing against the receiving API's rate limit window.
A workflow tested on a handful of records almost never hits a rate limit, which is exactly why this problem tends to surface for the first time in production, during the first real bulk import or list-based enrollment.
Where teams usually notice it first
- A CRM sync or enrichment tool that works fine on small enrollments but drops records on large ones
- Custom code actions returning timeout or
429errors under load - External systems (billing, fulfillment, marketing platforms) getting a burst of requests that looks like a spike, not steady traffic
- A partner or vendor asking why they received thousands of requests in one minute
How to actually control it
A few approaches, roughly in order of how much control they give you:
Workflow delay steps
Simple, but blunt. Delays apply per-enrollment, not globally, so they don't prevent a burst if 500 contacts enroll at the same second.
Batching enrollment
Importing or enrolling contacts in smaller, staggered groups instead of one giant list, so the total volume never hits the API in one wave.
Throttling at the integration layer
Queuing enrollments and releasing them at a controlled rate so the receiving API never sees more than it can handle, regardless of how many contacts enroll at once.
Throttling at the integration layer
For portals where this is a recurring problem, high enrollment volume, external systems with strict limits, or workflows that touch third-party APIs, a dedicated throttling layer tends to be the more durable fix. It decouples "how fast HubSpot wants to enroll" from "how fast the receiving system can accept work," which means the workflow logic itself doesn't need to change every time enrollment volume grows.
The exact numbers, batch size, interval, retry behavior, depend entirely on the receiving system's documented rate limits. The point isn't the specific code, it's the shift from "fire every request the moment enrollment happens" to "release requests at a rate the other system can actually absorb."
If a workflow calls an external API and your portal has any workflow that could plausibly enroll hundreds or thousands of records at once, it's worth confirming today what the receiving system's rate limit actually is, and whether the current setup respects it.