Skip to main content
A single agent.run(files=[File(...)]) handles one document. Folders, queues, and nightly drops also need concurrency limits, retry policy, and idempotent writes. The patterns below cover bounded async batches, in-process background runs, and scheduled AgentOS endpoints.

Concurrent batch over a list

The simplest batch is a folder of files. agent.arun is async, so a semaphore plus asyncio.gather is enough.
A semaphore bounds in-flight calls and memory use. It does not enforce requests-per-minute or token quotas. Add a rate limiter and retry policy for provider limits, and choose concurrency based on the model quota and downstream write capacity.

Background runs for long jobs

background=True returns a pending run while an asyncio task continues in the current process. Poll the persisted run state when the caller should not wait for the model response.
Content loaded from the database comes back as a plain dict, so validate it back into your schema. The database persists pending, running, and terminal state for polling. The work itself is an in-process asyncio task. If the process exits, Agno v2.7.2 does not resume that task from the database. Use a durable external queue or worker system when execution must survive process failure.

Scheduled batch with retries

For nightly intake (an SFTP drop, a Drive folder, a queue), put an AgentOS in front of your agent and let the scheduler fire the run on cron.
scheduled_intake.py
In the same scheduled_intake.py module, create the schedule before starting the server. ScheduleManager writes to the same db the AgentOS polls.
if_exists="update" updates a schedule found by name instead of creating another schedule. The lookup and write are not atomic, and v2.7.2 does not place a unique constraint on schedule names. Run schedule bootstrap once when multiple application workers can start concurrently. The option also does not make the scheduled endpoint idempotent. The executor retries failed HTTP or run attempts with the configured delay, and each attempt writes a row to agno_schedule_runs.
Make the endpoint idempotent before enabling retries. A response or polling failure can cause another attempt after the target already performed a side effect.
In Agno v2.7.2, a scheduler claim becomes stale after 300 seconds and the executor does not refresh the lock. A schedule that runs longer than five minutes can be claimed again. Keep the target idempotent and use an external scheduler or queue for long-running jobs.

Pattern comparison

The scheduler fires endpoints. Endpoints are agents, teams, or workflows. So a nightly job that ingests a folder, extracts each file, and writes to your warehouse is a workflow exposed at /workflows/<id>/runs, scheduled with the same ScheduleManager.create call. See Workflows.

Observability

Every execution attempt creates a row in agno_schedule_runs with status and timing. run_id and session_id are present when the target run starts successfully. Inspect recent activity with:
Failed attempts keep their error text. Retries are separate rows with the same schedule_id and an incrementing attempt. Monitor these rows and route exhausted failures to your operational queue.

Production checklist

Next steps

Developer Resources