Skip to main content
frogbot jobs:run loads your app configuration and initializes FrogBot, including application onInit, without starting Next.js. It stays running and polls on a cron schedule. Configure your tasks, workflows, and leases before starting workers.

Start a worker

This process schedules jobs and claims up to six jobs across all queues every five seconds. The first tick occurs at the next cron match in the process’s local timezone. Overlapping ticks are skipped until the current scheduling and batch execution finish. Value flags accept --flag value and --flag=value. Invalid, unknown, duplicate, or conflicting arguments exit 2 before boot. Boot, thrown tick, and shutdown failures exit 1; normal task retries remain governed by jobs configuration. During normal execution, SIGINT and SIGTERM stop new ticks, drain the active batch and pending heartbeat, close the database, and exit 0. Set your container’s shutdown grace period to accommodate the longest active batch. An exceptional completion or database-write failure can reject a batch before sibling work finishes; the worker can then exit 1 without draining those siblings. Forced termination and interrupted work rely on lease recovery, which is at least once and can occasionally duplicate work.

Disable web autorun

Pass this jobs object to buildConfig when dedicated workers own execution:
shouldAutoRun prevents web autorun from executing jobs, but scheduling happens before that check: an existing autorun entry can handle schedules once before stopping. autoRun: [] removes user-defined entries; scheduled agent triggers, piece triggers and AI fields append their own entry during configuration, so the empty array alone does not guarantee that web replicas never schedule jobs. Keep the execution guard even with an empty array. The worker CLI disables built-in autorun before initialization and uses its own tick loop.

Separate workers and scheduler

Use a shared database, the same application configuration and secrets, and compatible app versions across all replicas. Your image must include the FrogBot CLI, app config and its imports, dependencies, and a package manager. The template’s minimal Next.js standalone image contains only the traced web server; build a full application image for these commands. The following Compose fragment assumes acme/frogbot-app contains that full application, including its built Next.js app, and DATABASE_URL points to a shared Postgres or MongoDB database:
Workers execute batches; the scheduler only enqueues scheduled jobs. Both use --all-queues so the minute recovery sweep in default is scheduled and executed, alongside custom and agent queues. Recovery requires both to remain running: lease expiry alone does not release a job. If you restrict application workers to named queues, retain a scheduler and worker that cover default. The worker CLI’s --limit 0 never runs jobs. Without --handle-schedules, it performs no scheduling either. This differs from local API run({ limit: 0 }), which is unlimited.

Workers for durable waits

Workflow waits persist in the shared database and release the current worker. Resume wakes the same paused job in its original queue. Keep workers covering that queue, and keep a scheduler and worker covering default: the minute frogbot-sweep-waitpoints task proactively expires waits and recovers accepted responses whose jobs still need waking. The all-queue container setup above covers both. Failed wakes remain retryable by the scheduled sweep. Cancelled, superseded, or deleted paused jobs are not recreated, and their resume links return 409. See Dispatch and recovery limits. Set serverURL to the public web origin in the shared application configuration. Workers use it to generate approval links; recipients need the web service to open confirmation and submit a response. Keep wait names, task IDs, and branching compatible across the app versions serving a suspended workflow. Paused jobs become eligible once their waitUntil is strictly earlier than now: until for a delay, or the expiry for a resumable wait. Expiry continues the same job with { expired: true }, through a runner or the sweep. Neither is an in-process timer or a promise to execute at an exact instant. Worker ticks, active batches, and backlog affect wake-up time. A scheduler-only process cannot execute the sweep or resumed work. Paused jobs stay unfinished and retain their input, queue, replay history, and jobId reservation. They hold no lease until they run again. Resumed or expired waitpoints marked dispatched are retained; the sweep skips them rather than deleting or redispatching them. Deploy the waitpoint schema through your normal database migrations before starting SQL-backed workers.

SQLite and D1

SQLite-family claims use a single UPDATE … WHERE id IN (SELECT … LIMIT …) RETURNING id statement. They require SQLite 3.35.0 or newer, which introduced RETURNING. SQLite serializes writers; it does not use Postgres’s SKIP LOCKED. Returned row order is not guaranteed by SQL; FrogBot reads the claimed records back using the requested sort. D1 uses SQLite’s query engine. FrogBot’s D1 adapter uses the Drizzle D1 driver: the returning claim reads positional rows through the binding’s raw() method; lease updates without returned rows use run(). Use a current Wrangler release for local D1 development. Cloudflare’s guide requires Wrangler 3+ and uses Miniflare/workerd; getD1Database() provides a D1 binding for programmatic tests. These SQL and driver requirements do not establish verification against a remote D1 deployment.