A practical field guide from Automation Ace.
How to Process Records with a Sequential Queue Using Webhooks and Zapier Tables
Zapier runs Zap steps sequentially within a single run, but multiple Zap runs triggered at the same time run in parallel. When the order of processing matters — sequential API calls to a rate-limited endpoint, operations that must not overlap, or tasks where record N must complete before record N+1 begins — parallel execution breaks things. The solution is a queue architecture: records wait in a table, and a dedicated processing Zap picks up one item at a time, processes it, marks it done, and triggers the next. Zapier Tables provides the queue store; webhooks provide the trigger mechanism.
When a Sequential Queue Is Needed
Common scenarios where parallel execution is a problem and sequential processing is required:
- Rate-limited APIs: An API allows only 1 request per second, but 50 records arrive at once. Processing all 50 in parallel blows the rate limit.
- Dependent operations: Each step depends on the result of the previous one — creating a parent record first, then child records using the parent's ID.
- External system serialization: A downstream system can only handle one webhook at a time and returns errors when multiple arrive simultaneously.
- Ordered processing: Records must be processed in arrival order — first-in, first-out — not in whatever order parallel Zap runs happen to complete.
Architecture Overview
The queue pattern uses three Zaps and a Zapier Tables table:
- Zap A — Enqueuer: Triggered by the source event (form submission, webhook, scheduled trigger). Writes the payload as a new row in Zapier Tables with status = "pending".
- Zap B — Processor: Triggered by a webhook. Reads the next "pending" record from Zapier Tables, processes it, marks it "done", then sends a webhook to itself to process the next item.
- Zap C — Kickstarter (optional): Sends a webhook to Zap B on a schedule (e.g., every 15 minutes) to restart the queue if it stalled. Alternatively, Zap A sends the kickstart webhook after writing each new row.
Step 1: Set Up the Zapier Tables Queue
Create a Zapier Tables table with these fields:
- Payload (text/long text) — the data to process, stored as JSON string
- Status (single select) — values:
pending,processing,done,error - Created At (date) — for ordering (FIFO)
- Error Message (text) — optional, for logging failures
- Retry Count (number) — optional, for tracking retry attempts
Step 2: Zap A — Enqueue Records
- Trigger: whatever source event generates records (form submission, webhook, scheduled poll, etc.)
- Action: Zapier Tables — Create Record
- Payload: map trigger fields into a JSON string (or use a Code step to build the JSON)
- Status:
pending - Created At: current timestamp
- Action (optional): Webhooks by Zapier — POST to Zap B's Catch Hook URL — to immediately kick off processing when a new item is enqueued rather than waiting for the scheduled kickstarter.
Step 3: Zap B — Process One Item
This is the core of the pattern. Zap B processes one record per run:
- Trigger: Webhooks by Zapier — Catch Hook (no payload needed; the hook just signals "process next item")
- Action: Zapier Tables — Find Record
- Filter: Status = "pending"
- Sort: Created At ascending (oldest first, for FIFO)
- Limit: 1
- Action: Filter by Zapier — only continue if a record was found (check that the record ID field is not empty)
- Action: Zapier Tables — Update Record — set Status = "processing" (claims the record, prevents a concurrent Zap B run from picking the same item)
- Action(s): Your actual processing steps — the API calls, data transformations, notifications, etc. Map fields from the "Find Record" step's payload output (parse the JSON in a Code step if needed)
- Action: Zapier Tables — Update Record — set Status = "done" (or "error" if a preceding step failed)
- Action: Webhooks by Zapier — POST to Zap B's own Catch Hook URL — triggers the next iteration immediately
The final webhook self-trigger is the key: after processing one item and marking it done, Zap B immediately queues itself to process the next pending item. This creates a chain that drains the queue sequentially, one item per Zap run.
Preventing Duplicate Processing
The "processing" status update (step 4 above) is the concurrency guard. If two Zap B runs start simultaneously (e.g., from a kickstarter and a self-trigger arriving at the same time), both will query for the oldest "pending" record and find the same one. The first to update its status to "processing" effectively claims it. The second will also update it to "processing", and both will process the same record — a race condition.
To reduce this risk: use the Zapier Tables record ID in the Update step rather than a filter-based lookup, and consider adding a brief Code step delay after the Find Record step before the status update to spread any simultaneous starts. For workflows where exact-once processing is critical, additional deduplication logic in the processing step (checking a flag in an external system) provides a stronger guarantee.
Error Handling
If the processing steps fail, add a Zap with an "Error" trigger (Zapier's built-in error handling, available on some plans) that catches the failure and updates the record status to "error" with the error message. Alternatively, use a Code step with try/catch to handle errors within the processing logic and update the status to "error" on failure, then still fire the self-trigger to continue processing remaining items.
Queues are one of several ways to hand work between Zaps; see record-driven handoffs.
Queue Draining and Monitoring
The queue self-drains: as long as each Zap B run fires the self-trigger at the end, the chain continues until no "pending" records remain. When the queue is empty, the Find Record step returns no result, the Filter step stops execution, and the chain terminates naturally. The next kickstarter firing (or the next enqueue) restarts it.
Monitor queue depth by checking the count of "pending" records in Zapier Tables. A Zapier Tables view filtered to Status = "pending" sorted by Created At gives a live view of the queue.
The sequential queue pattern solves one of Zapier's most common architectural challenges: guaranteed ordering with one-at-a-time processing. Zapier Tables provides persistent state; the self-triggering webhook provides the sequencing mechanism. The pattern scales naturally — a 5-item queue and a 5,000-item queue both drain the same way, one at a time, in FIFO order.
For sequential looping patterns within a single Zap step, see sequential looping in Zapier steps. For using Zapier Storage API as a lightweight state store for smaller queues, see the Zapier Storage API guide. For help designing a queue-based processing workflow, talk to Automation Ace.
Disclaimer: This article may include links to apps, products, or services. Some links may be affiliate links, which means Automation Ace may earn a commission at no extra cost to you.