# Batching and execution limits

Batching divides suitable processing into chunks. Concurrency determines how much work can run at once. Both help handle larger datasets, but they solve different problems and remain subject to handler and workspace limits.

## Configure a batchable step

Use batching only when the handler supports it. Set a chunk size appropriate for the source and destination, and use cursor-based progression. A cursor records where processing should continue; it is not an arbitrary row offset.

For a source, chunk size can guide how many records are fetched at a time. For a batchable destination, the handler can receive successive slices of upstream records. Supported jobs retain progress so recovery can continue after completed chunks rather than restarting every chunk.

Test the same small dataset with and without batching. Record identities, numbering, and final results should remain consistent. Some handler configurations cannot be safely sliced and therefore remain a single operation.

## Understand parallelism

Independent graph branches can execute concurrently, bounded by per-run and shared execution capacity. A ready step can still wait for a slot, provider capacity, a child-workflow limit, or a metered resource budget.

Increasing job-level concurrency does not automatically increase the platform's total capacity. It can increase provider rate limiting, model cost, or pressure on a database. Start conservatively and measure actual duration and failure rate.

## Plan for budgets and limits

Jobs can enforce maximum input records, output records, bytes, deadlines, and model usage. Python snippets have their own allocation and timeout bounds. An oversized result is not necessarily repaired by more retries; reduce the input scope or split the work.

Metered operations can wait before starting. Distinguish time spent waiting for capacity from time spent executing the handler. Cancelling queued work should prevent new useful work, but a chunk already writing may reach its safe completion boundary.

A checkpointed batch is not one transaction across the entire dataset. Earlier committed chunks can remain after a later chunk fails. Use stable keys and verify partial results before repeating the run.

See [reliability](/docs/workflows/reliability), [subworkflows](/docs/workflows/subworkflows), and [monitoring runs](/docs/workflows/monitor-runs).
