This document describes the batch processing system in Trigger.dev's RunEngine, which enables fair, efficient processing of large sets of task runs through a 2-phase streaming API with Deficit Round Robin (DRR) scheduling. For information about triggering individual runs, see Task Triggering Services. For information about general queue management, see Queue Management.
The batch processing system provides a mechanism to trigger and process multiple task runs as a coordinated group. It implements a 2-phase streaming API that allows runs to be added incrementally to a batch, and uses DRR scheduling to ensure fair processing across multiple concurrent batches.
Core Components:
| Component | File Location | Purpose |
|---|---|---|
BatchQueue | internal-packages/run-engine/src/batch-queue/index.js | DRR-based queue managing batch item processing |
BatchSystem | internal-packages/run-engine/src/engine/systems/batchSystem.ts | High-level batch operations (initialize, stream, complete) |
WaitpointSystem | internal-packages/run-engine/src/engine/systems/waitpointSystem.ts | Handles BATCH type waitpoints for blocking parent runs |
RunEngine | internal-packages/run-engine/src/engine/index.ts76-388 | Orchestrates all batch-related components |
The batch system is initialized in the RunEngine constructor and operates independently from the main run queue, with its own consumer pool and concurrency controls.
Sources: internal-packages/run-engine/src/engine/index.ts332-362 internal-packages/run-engine/src/engine/types.ts76-90
Sources: internal-packages/run-engine/src/engine/index.ts232-234 internal-packages/run-engine/src/engine/systems/batchSystem.ts327-330
The batch processing API operates in two distinct phases to support incremental addition of items:
STREAMING_BATCH_MAX_ITEMS items per batchThe separation between streaming and finalization allows the system to begin processing items immediately while still accepting new items, improving overall throughput.
Sources: apps/webapp/app/env.server.ts542-548 internal-packages/run-engine/src/batch-queue/types.js
The batch processing system uses DRR scheduling to ensure fair resource allocation across multiple concurrent batches. This prevents large batches from monopolizing processing capacity at the expense of smaller batches.
| Parameter | Environment Variable | Default | Purpose |
|---|---|---|---|
| Quantum | BATCH_QUEUE_DRR_QUANTUM | 5 | Items dequeued per batch per round |
| Max Deficit | BATCH_QUEUE_MAX_DEFICIT | 50 | Maximum accumulated deficit before reset |
| Master Queue Limit | BATCH_QUEUE_MASTER_QUEUE_LIMIT | Varies | Max batches in master queue |
DRR Algorithm:
This ensures:
Sources: internal-packages/run-engine/src/engine/index.ts341-345 apps/webapp/app/v3/runEngine.server.ts171-175
The batch processing system implements multiple layers of concurrency control and rate limiting to prevent resource exhaustion:
Each batch has an independent concurrency limit set at batch creation time:
This limit controls how many items from a single batch can execute simultaneously.
Sources: apps/webapp/app/env.server.ts548 apps/webapp/app/v3/runEngine.server.ts185
An optional global rate limiter restricts processing across all consumers:
| Setting | Environment Variable | Default | Description |
|---|---|---|---|
| Refill Rate | BATCH_RATE_LIMIT_REFILL_RATE | 100 | Tokens added per interval |
| Max Tokens | BATCH_RATE_LIMIT_MAX | 1200 | Token bucket capacity |
| Refill Interval | BATCH_RATE_LIMIT_REFILL_INTERVAL | "10s" | Time between refills |
The rate limiter uses a token bucket algorithm to smooth processing rates and prevent bursts that could overwhelm the system.
Sources: apps/webapp/app/env.server.ts545-547 apps/webapp/app/v3/runEngine.server.ts187-189
The batch processing system runs multiple consumers that process items from the worker queues:
| Setting | Environment Variable | Default | Purpose |
|---|---|---|---|
| Consumer Count | BATCH_QUEUE_CONSUMER_COUNT | 2 | Number of parallel consumers |
| Consumer Interval | BATCH_QUEUE_CONSUMER_INTERVAL_MS | 100 | Polling interval in milliseconds |
| Default Concurrency | BATCH_CONCURRENCY_LIMIT_DEFAULT | 1 | Default per-batch concurrency |
Consumers can be disabled independently from the main RunEngine worker using BATCH_QUEUE_WORKER_ENABLED.
Sources: apps/webapp/app/v3/runEngine.server.ts180-182 internal-packages/run-engine/src/engine/index.ts348-351
Batch processing integrates with the waitpoint system to enable batchTriggerAndWait patterns where a parent run blocks until all batch items complete.
When a parent run calls batchTriggerAndWait:
WaitpointSystem.blockRunWithWaitpoint()BatchSystem.tryCompleteBatch() is calledWaitpointSystem.completeWaitpoint() unblocks the parent runThe batch completion check is scheduled via the worker catalog job tryCompleteBatch:
Sources: internal-packages/run-engine/src/engine/workerCatalog.ts47-51 internal-packages/run-engine/src/engine/systems/waitpointSystem.ts366-497
The batch processing system uses a multi-level queue architecture with sharding for scalability:
The system optionally uses two-stage processing with blocking pop:
This is enabled via workerQueueBlockingTimeoutSeconds:
When enabled:
Sources: apps/webapp/app/v3/runEngine.server.ts177-179 internal-packages/run-engine/src/engine/types.ts82
Master queue sharding distributes batches across multiple Redis keys:
BATCH_QUEUE_SHARD_COUNT (default varies by deployment){keyPrefix}batch-queue:master:{shardIndex}Sharding benefits:
Sources: internal-packages/run-engine/src/engine/index.ts346 apps/webapp/app/v3/runEngine.server.ts176
| Variable | Default | Type | Description |
|---|---|---|---|
STREAMING_BATCH_MAX_ITEMS | 1000 | int | Maximum items per batch |
STREAMING_BATCH_ITEM_MAXIMUM_SIZE | 3,145,728 | int | Max item size in bytes (3MB) |
BATCH_CONCURRENCY_LIMIT_DEFAULT | 1 | int | Default per-batch concurrency |
BATCH_QUEUE_DRR_QUANTUM | 5 | int | DRR quantum value |
BATCH_QUEUE_MAX_DEFICIT | 50 | int | Maximum deficit accumulation |
BATCH_QUEUE_MASTER_QUEUE_LIMIT | varies | int | Max batches in master queue |
BATCH_QUEUE_SHARD_COUNT | varies | int | Number of master queue shards |
BATCH_QUEUE_CONSUMER_COUNT | 2 | int | Number of consumer workers |
BATCH_QUEUE_CONSUMER_INTERVAL_MS | 100 | int | Consumer polling interval |
BATCH_QUEUE_WORKER_ENABLED | false | bool | Enable batch consumers |
BATCH_RATE_LIMIT_REFILL_RATE | 100 | int | Rate limiter refill rate |
BATCH_RATE_LIMIT_MAX | 1200 | int | Rate limiter max tokens |
BATCH_RATE_LIMIT_REFILL_INTERVAL | "10s" | string | Rate limiter refill interval |
BATCH_METADATA_OPERATIONS_FLUSH_INTERVAL_MS | 1000 | int | Metadata flush interval |
BATCH_METADATA_OPERATIONS_FLUSH_ENABLED | "1" | string | Enable metadata flushing |
Sources: apps/webapp/app/env.server.ts542-558
The batch processing system is configured during RunEngine initialization:
The batch system is separate from the main run queue but shares the same tracer and meter for observability.
Sources: apps/webapp/app/v3/runEngine.server.ts161-190 internal-packages/run-engine/src/engine/index.ts332-362
The batch processing system tracks metadata for each batch to support monitoring and completion detection:
Metadata operations (item count, completion status, etc.) are batched and flushed periodically:
BATCH_METADATA_OPERATIONS_FLUSH_INTERVAL_MS (default: 1000ms)BATCH_METADATA_OPERATIONS_FLUSH_ENABLED (default: "1")BATCH_METADATA_OPERATIONS_FLUSH_LOGGING_ENABLED (default: "1")This batching reduces database write load during high-throughput batch processing.
The system tracks:
When all items reach a terminal state, the batch waitpoint is completed via the tryCompleteBatch worker job.
Sources: apps/webapp/app/env.server.ts556-558 internal-packages/run-engine/src/engine/workerCatalog.ts47-51
Refresh this wiki
This wiki was recently refreshed. Please wait 5 days to refresh again.