Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.getbindu.com/llms.txt

Use this file to discover all available pages before exploring further.

Two requests hit your agent at the same time. Both want a 30-second answer. Without a scheduler, the second caller waits 30 seconds for the first one to finish, then 30 more for their own. A single-threaded agent is a queue of one — and queues of one are how production starts melting. The scheduler sits between the HTTP layer and the worker that actually runs your handler. Submission is non-blocking — the caller gets a task_id immediately. Workers pull tasks from the queue and execute them in parallel. The agent stops being a bottleneck and starts being a service. In memory for local dev, Redis for production. Same bindufy(config, handler) either way; you just flip two environment variables.
Single process? In-memory is fine. Multiple processes or restart-survival required? Switch to Redis with two env vars. Details below.

How the Bindu Scheduler Works

The scheduler sits between the TaskManager and the worker pool. When a task is submitted, the TaskManager enqueues the task ID. Workers dequeue task IDs and execute them. The storage layer holds the full task data.

The Scheduling Model

Non-blocking

Task submission returns immediately. Execution happens asynchronously in a worker.

Concurrent

Multiple workers pull from the same queue and execute tasks in parallel.

Durable

Redis-backed queue survives agent restarts. In-flight tasks are not lost.

Backends

Bindu supports two scheduler backends:
MemoryRedis
SetupNoneRequires Redis instance
DurabilityLost on restartSurvives restarts
Multi-workerSingle process onlyDistributed workers
Use caseLocal developmentProduction
Config"type": "memory""type": "redis"

Configuration

Scheduler backends are picked via environment variables. Same pattern as Storage — connection strings don’t belong in a Python dict that ends up in git.

Memory (development)

# Default — no env vars needed.
SCHEDULER_TYPE=memory
The in-memory scheduler uses an asyncio queue inside the agent process. Fast, zero setup, and tasks are gone if the process stops. Good for uv run agent.py while you’re building.

Redis (production)

SCHEDULER_TYPE=redis
REDIS_URL=redis://localhost:6379/0
Put both in .env for local development; pull them from your orchestrator’s secret manager in production. The config dict your agent code uses stays clean.

The Task Execution Lifecycle

Here is how the scheduler fits into the full task lifecycle: The client never waits for execution. It submits, gets a task_id, and polls or uses push notifications to know when the task is done.

Worker Concurrency

By default, Bindu runs a single worker. You can increase concurrency by configuring the number of workers:
{
  "scheduler": {
    "type": "redis",
    "url": "redis://localhost:6379/0",
    "workers": 4
  }
}
With Redis, you can also run multiple agent instances pointing at the same queue. Each instance runs its own worker pool, and tasks are distributed across all of them automatically.
# Instance 1
REDIS_URL=redis://redis:6379/0 uv run python main.py

# Instance 2 (same Redis, same queue)
REDIS_URL=redis://redis:6379/0 uv run python main.py
Both instances compete for tasks from the same queue. Redis ensures each task is delivered to exactly one worker.

Redis Setup

For production deployments, you need a running Redis instance.

Docker (Quick Start)

docker run -d \
  --name bindu-redis \
  -p 6379:6379 \
  redis:7-alpine

Environment variables

SCHEDULER_TYPE=redis
REDIS_URL=redis://localhost:6379/0

With authentication

REDIS_URL=redis://:your-password@localhost:6379/0

Combining Storage and Scheduler

In production, you typically run both Postgres and Redis together:
STORAGE_TYPE=postgres
DATABASE_URL=postgresql://bindu:secret@localhost:5432/bindu
SCHEDULER_TYPE=redis
REDIS_URL=redis://localhost:6379/0
The queue holds task IDs. The database holds task data. Workers read from both. This separation means the queue stays lean and fast while the database handles the heavy state.

Real-World Use Cases

When many tasks arrive at once, the queue absorbs the burst. Workers process at their own pace without dropping requests or blocking the HTTP layer.
A task that takes minutes to complete does not block the agent from accepting new requests. The worker handles it in the background while the HTTP server stays responsive.
With Redis, tasks that were queued but not yet started survive an agent restart. When the agent comes back up, workers pick up where the queue left off.
Deploy multiple agent instances behind a load balancer, all pointing at the same Redis queue. Tasks are distributed across instances automatically. No coordination code required.

Security Best Practices

Use environment variables

Redis connection strings don’t belong in a Python dict that ends up in git. Use REDIS_URL in .env or your orchestrator’s secret manager.

Enable Redis Auth

In production, configure Redis with a password and use TLS if the connection crosses a network boundary.

Sunflower LogoThe scheduler is what separates receiving work from doing work — so your agent can always say yes, even when it’s busy.