This is a lease and fencing problem, and it’s solvable with one table and a few rules. In order:
1. Claiming and the attempt ID. Claim with a single conditional update, not a read followed by a write: set status='claimed', a fresh attempt_id and lease_expires_at, but only WHERE status='queued' (or the lease has expired). Treat the claim as won only if exactly one row changed. Then use a separate start call, carrying the attempt_id, to move the job to running. That cleanly separates “claimed” from “actually started.”
2. Heartbeats and recovery. The agent renews the lease with its attempt_id, and the update applies only if that attempt is still the current one. A schedule workflow in n8n finds attempts whose lease has expired, requeues them with attempt_no + 1, and after a maximum number of attempts moves them to dead-letter and alerts you.
3. Late callbacks. Use the attempt_id as a fencing token. Every callback carries it, and the final update applies only if it matches the current attempt. Otherwise return a 409 and log it. A slow attempt that wakes up after reassignment can’t overwrite anything.
4. Lost acknowledgements. Make completion idempotent: if the same attempt_id reports the same result again, return the stored result and change nothing. On the agent side, keep results in a local outbox and retry until acknowledged. Pass a stable idempotency key (job_id + step) to any downstream effect.
Data Tables or a database? The whole design rests on one atomic conditional update that tells you how many rows changed. I wouldn’t trust any table for that until you’ve tested it with many parallel claims. A transactional database (Postgres) gives you the guarantee directly, with n8n orchestrating around it.
Wait node? I’d keep the state in the table, not in a paused execution. A resume URL belongs to one execution, which makes duplicate and late callbacks harder to reason about. A plain authenticated webhook workflow that does the fenced update is simpler.
If you’d rather have this designed and kept running for you, Pond AI builds, runs and maintains custom agent systems like this, and sketches the whole flow on one page before any build starts. There’s a 7-day refund .
One question that decides the lease length and how strict step 4 must be: what’s your longest job runtime, and what does running a job twice cost you?
Disclosure: I’m affiliated with Pond AI.