Overcoming HubSpot 20-Second Workflow Execution Timeouts
Explore strategies to bypass HubSpot’s strict 20-second custom code execution timeout using Workflood async queues, batching, and gVisor sandboxes.
The Problem: The 20-Second Hard Limit
HubSpot native custom code actions enforce a strict **20-second execution timeout** and a **128MB memory ceiling**.
If your custom action performs any of the following, it will frequently timeout: - Batch searching 500+ records across multi-tier association trees. - Calling slow third-party enrichment APIs (ZoomInfo, Clearbit, OpenAI). - Calculating historical pipeline velocity over 12 months of deal history. - Performing PDF generation or large file transformations.
When a HubSpot custom code action times out, the workflow halts, leaving records in a broken or unassigned state.
How Workflood Solves Execution Limits
Workflood decouples action execution from HubSpot's synchronous workflow canvas:
- **Immediate Webhook Acknowledgement:** HubSpot's webhook step receives a `202 Accepted` response in <100ms.
- **Dedicated Redis / BullMQ Queue:** The action payload is pushed into an isolated, reliable job queue.
- **gVisor Micro-Containers:** Execution runs with up to **512MB RAM** and extended timeouts:
- - **Single Portal Plan:** **60-second** execution timeout (3x HubSpot native).
- - **Multi-Portal / Agency Plan:** Up to **5-minute (300s)** execution timeout (15x HubSpot native).
- **Asynchronous API Write-Back:** Once computation finishes, Workflood writes the results back to HubSpot using the pre-authenticated SDK.
Timeout Comparison Matrix
| Feature | HubSpot Native Data Hub | Workflood Single Portal | Workflood Multi-Portal / Agency |
|---|---|---|---|
| **Max Execution Time** | **20 seconds (Hard Cap)** | **60 seconds** | **300 seconds (5 min)** |
| **Memory Allocation** | 128 MB | 512 MB | 1024 MB+ |
| **Cold Starts** | 500ms – 2000ms | <50ms | Zero cold starts |
| **Failure Handling** | Halts entire workflow | Auto-retries with jitter & Slack alerts | Auto-retries & dead-letter queue |
Code Example: Chunked Batch Processing
For heavy operations involving hundreds of records, use chunked pagination:
export default async function main() {
let after: string | undefined = undefined
let totalProcessed = 0
do {
const page = await hubspot.client.crm.contacts.basicApi.getPage(
100, // Batch size
after,
['email', 'annualrevenue', 'hs_lead_status']
)
// Process chunk in parallel
await Promise.all(
page.results.map(async (contact) => {
// Business logic calculation
totalProcessed++
})
)
after = page.paging?.next?.after
} while (after && totalProcessed < 2000)
return { totalProcessed, status: 'completed' }
}Frequently Asked Questions
Can I set a custom timeout per action in Workflood?
Yes. In the Workflood action editor settings, you can configure the exact timeout in seconds per action up to your workspace plan limit.
