ANTIGRAVITY LABJP
Articles/Agents & Manager
Agents & Manager/2026-06-29Advanced

When Background Agents Run Twice — Stopping Double Execution with Leases and Fencing Tokens

The same scheduled job fires from two machines at once and they overwrite each other's output. Here is how to stop that failure mode at the root in Antigravity 2.0 background agents, using leases and fencing tokens, with working code.

background agents3Antigravity288distributed lockfencing tokenoperations19

Premium Article

One morning, an artifact that should have been freshly generated was half-overwritten with stale content. The logs told the story: the same scheduled job had fired from two machines at nearly the same minute, and one started writing before the other had finished.

As an indie developer at Dolice Labs, I run several blog operations on background agents. The intent was redundancy — while one machine sleeps, another picks up the work. But in the instant both were awake, both grabbed the same job. This is not a "forgot to take the lock" story. It happens even when you do take the lock. Let me walk through why, and how to stop it.

Why mutual exclusion alone does not stop double execution

The intuition is simple: take a lock at the start of the job, release it at the end. In the world of background agents, that premise quietly collapses.

A process can hold a lock and then stall for a long time — a long garbage-collection pause, an OS wake from sleep, a slow model call. Meanwhile the lock's TTL expires and another machine legitimately acquires it. The first machine wakes up still believing it owns the lock and begins writing. At that moment there are two lock holders in the world.

So the problem is not acquiring exclusivity; it is being unable to guarantee continued possession. Miss this distinction and every patch — longer TTLs, more heartbeats — only lowers the probability instead of eliminating it.

The idea of a lease

Reframe the lock as a lease: time-bounded ownership that is always assumed to expire. The holder must explicitly renew it before it lapses. The moment renewal stops, ownership is considered surrendered automatically.

The key property is that each time a lease is granted, the issued fencing token increases monotonically. Every acquisition produces a strictly larger token. That lets you distinguish an "old owner" from a "new owner" right before a write, using nothing but a numeric comparison.

AspectPlain mutual-exclusion lockLease + fencing token
Recovery from a stallThe old holder writes anywayThe old token is rejected at the write site
Ownership decisionRelies on "I think I hold it"Decided mechanically by number size
Effect of clock skewBreaks if TTL judgment driftsOrder is set by the token, not the clock
Required assumptionEveryone behaves honestlyThe write target can verify the token

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
Understand exactly why 'I acquired the lock, so I'm safe' breaks down (GC pauses, sleep/wake, clock skew) — and why a plain mutual-exclusion lock cannot prevent double execution
A complete implementation of double-execution prevention with a lease plus a monotonically increasing fencing token (acquire, renew, expire, and write-side verification). The bash and Python are copy-paste ready
From the real experience of running scheduled jobs across two Macs as an indie developer and watching output get corrupted, a clear rule for where the verification gate must live
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

Agents & Manager2026-06-29
Spotting Agents That Are Alive but Stuck — Designing a Progress Heartbeat and Watchdog
The process is alive but the work isn't moving — the nastiest state for a background agent. Here is how to switch from liveness to progress monitoring to detect it, and how to stop it safely, with working code.
Agents & Manager2026-06-28
Treating Built-in Guide Skills as Design Assets, Not Throwaway Prompts
Antigravity v2.2.1 added built-in Guide skills. Here is a concrete structure and set of judgment calls for running them as version-controlled, shared design assets instead of one-off instructions.
Agents & Manager2026-06-27
Keep a Tamper-Evident Audit Log of Your Autonomous Agent's Actions
To record the decisions and actions an Antigravity agent takes autonomously in a form you can trace and verify later, design an append-only audit log whose hash chain detects tampering. Includes the implementation.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →