A worker can restart successfully while a customer's catalog remains half updated or the same work gets applied twice.
Consider a supplier uploading a CSV file. The worker commits some products, then crashes before telling the queue it has finished. When the job arrives again, what prevents those changes from being repeated?
Vercel announced Daemons in public beta on October 15, 2026. It runs containerized processes that continuously pull work, maintains configured instance counts and restarts instances that exit or crash. That creates another option for hosting a background worker. Vercel's release announcement
Before choosing it, I would want a clear answer to what the next worker can safely do with the unfinished import. Process recovery needs to lead to recovery of the customer's work.
What Vercel Daemons adds
Vercel positions Daemons for processes that own a continuous work loop, such as queue consumers or workers retrieving tasks from a workflow engine. It runs alongside the application, without needing an inbound HTTP server. Daemons documentation
As checked on October 23, 2026, the beta has boundaries that affect the decision:
- Daemons run in production deployments; preview workers are unsupported.
- Instance counts are manually configured; autoscaling is unsupported.
- Local storage is ephemeral; persistent local storage is unsupported.
A file on the worker's disk therefore cannot be the only copy of an accepted upload or its progress. Check the current beta limits before committing to a deployment design. Beta capabilities and limits
Choose between Daemons, Queues and Workflows
For a small, bounded import that fits the request's execution limits and an acceptable customer wait, an existing HTTP handler may be sufficient. I would keep it unless there is a concrete reason to move the work.
A queue becomes useful when the request should finish before processing does, or when work needs buffering and redelivery. Vercel Queues documents at-least-once delivery, so a consumer must cope with a message arriving again. Its default push mode invokes a handler; poll mode lets a worker retrieve messages. A queue-backed job does not automatically require a daemon. Queues overview, push and poll consumption
A daemon supplies the running process for that polling loop. Durable workflow coordination has a different responsibility: retaining the sequence and progress of a process involving retries, waits or external events. Vercel Workflows documents that higher-level model. Workflows overview
For an import that must validate, wait for human approval and then publish, I would consider a workflow before building that coordination into a custom worker. If the existing queue consumer already meets the need, a new runtime needs a stronger justification than availability.
How a CSV import recovers after a worker crash
This is a fictional design example, not a client implementation or a tested Vercel deployment. Assume an immutable CSV with 1,000 valid rows, one unique supplier SKU per row. Imports for the same supplier are processed sequentially.
Record the accepted work outside the worker
Keep the uploaded file in durable object storage and create a persistent import record containing its location, supplier and status. Give that accepted import a stable ID. Retries of the same import retain it; an intentionally new import gets a new ID.
For each row, use the import ID and its position in that unchanged file as a processing identity. Separately, use the supplier and SKU to identify the catalog product being updated. These keys answer different questions: which row's work has been applied, and which product should change?
Also account for the gap between accepting the import and publishing its queue message. One option is to write the import record and a pending-dispatch entry in the same database transaction. A separate dispatcher publishes pending jobs and can retry after an uncertain result, which is why the import identity must survive redelivery. This is the transactional outbox pattern. Transactional outbox
Do not tell the customer their job is queued if the only evidence is a task sitting in process memory.
Commit the catalog change and row result together
For this example, keep the catalog and row-processing ledger in the same transactional database. Claim a row's processing identity under a unique constraint, apply its product update and record completion in one transaction. Concurrent duplicate attempts must be resolved through database constraints or locking.
A separate “already processed?” read followed by an unprotected write leaves a race. Recording completion before the product update can lose work; recording it afterwards in a separate transaction can repeat work.
AWS's Builders' Library makes this atomicity requirement explicit for idempotent operations: recording the request identity and performing its mutations must succeed or fail together. Idempotency means repeating the operation has the same intended effect as performing it once. Making retries safe with idempotent APIs
Now stop the worker after 300 rows have committed. On redelivery, the replacement worker can recognize those completed row identities and continue with the remaining 700. It should derive progress from committed results, rather than incrementing a counter every time a message is handled.

Illustrative database-only recovery path. Each row’s catalog update and completion record commit together; the uploaded file and progress live outside the worker. Redelivery depends on the queue’s lease, retry policy and retention. Required work commits before acknowledgment. External API effects need the separate retry design below.
Expect a crash after commit but before acknowledgment
Finishing the database work does not mean the queue has recorded success. The worker can commit the last row and the import's completed status, then die before acknowledging the message.
On redelivery, it must recognize the completed import and settle the delivery without applying those effects again. Acknowledging early reverses the problem: the queue may stop redelivering work whose effects never committed.
Vercel's Daemons guide advises acknowledging after processing. With Vercel Queues' polling SDK, acknowledgment happens automatically when the handler completes. Keep required durable work inside that handler, and let failures propagate rather than returning success while detached work continues. Shutdown and retry guidance, polling handler behavior
For a long import, configure and monitor the message lease and retention window. An expired lease can expose the job to another worker; expired retention can remove the message before the job finishes. Keep unfinished import records outside the queue so recovery remains visible. Queue visibility and retention
External actions need their own retry design
The transaction above protects changes inside one database. Suppose the import must also update a supplier's external system. That system may accept the update while its response is lost. A local record saying “pending” cannot establish that nothing happened remotely.
Use a stable operation identity with a downstream API's documented idempotency support where available. Check its scope and retention window, and preserve the intended request across retries. Without that support, define how to reconcile an uncertain outcome before repeating an action that could cause harm. Under this expanded design, keep the import pending or needing attention until required external updates are confirmed.
Workflow SDK's own idempotency guide describes this external-call problem and using stable step identities across retries. A workflow's saved progress does not, by itself, make every downstream action safe to repeat. Workflow step idempotency
If AI categorization is added, I would persist a selected result against the row and processing version before publishing it. An interruption should not silently turn a retry into a fresh decision. That is a useful boundary to define during an AI adoption pilot.
Graceful shutdown helps; abrupt crashes still matter
Vercel documents a default 30-second grace period after sending SIGTERM, configurable up to 3,600 seconds. During an orderly shutdown, stop taking new work and use that window to finish or safely leave the current unit of work. The platform also warns that an instance can stop at any time. Daemons shutdown behavior
I would size work units so they can reach a durable boundary predictably. Extending the grace period can help an orderly rollout, but it cannot recover state that existed only in memory when a process crashed.
Use the fictional import to review these failure points in an isolated test environment. These are proposed checks, not reported results:
- Crash before a row transaction commits: neither its product change nor completion record survives; retry that row.
- Crash after row 300 commits: retain those 300 results and finish the remaining 700 without duplicate application.
- Crash after final commit, before acknowledgment: recognize the completed import on redelivery and avoid repeating its effects.
- External update accepted, response lost: follow the downstream idempotency or reconciliation procedure; keep an unresolved outcome visible.
Design for repeated execution. These checks do not establish an exactly-once execution guarantee across the worker, queue, database and external services.
Make recovery visible and assign its owner
A running process is useful operational information. The customer also needs an import status based on durable evidence: accepted, processing, completed or needing attention, with committed progress and a useful error report.
Agree how long an import may go without progress before it is investigated. Separate temporary failures that merit bounded retries and backoff from invalid input or uncertain external actions that need a different response. Keep failed work visible after automated retries stop or queue retention expires.
Before release, I would ask the team to demonstrate:
- Where the accepted file, import record and unfinished work survive instance replacement.
- How duplicate deliveries are handled, including concurrent attempts.
- What identifies each external action, and who resolves an uncertain result.
- What the customer sees during recovery and how support finds the import.
- Who receives a stalled-job alert and who can authorize a retry or correction.
If nobody can explain the recovery path across those boundaries, that belongs in an architecture review before changing the hosting arrangement.
For the catalog import, I would approve a runtime only after the team can interrupt the worker and explain the resulting records. The useful outcome is an import someone can account for, including when its process has been replaced.