New to Kestra?
Use blueprints to kickstart your first workflows.
Process data partitions in parallel with Python in Kestra. Fan out files into isolated Docker containers and track row counts and processing time as metrics.
Process a list of data partitions in parallel using isolated Python scripts, each running in its own Docker container, and emit custom metrics for every partition. This pattern solves a common data engineering problem: when a dataset is split into many files (Parquet, CSV, JSON), you want to process them concurrently rather than one at a time, while still tracking how many rows each file held and how long each unit of work took. By emitting Kestra counters and timers per partition, you turn an opaque batch job into an observable, measurable pipeline.
get_partitions task is an io.kestra.plugin.scripts.python.Script running on io.kestra.plugin.scripts.runner.docker.Docker. It builds a list of partition filenames and publishes them as a flow output with Kestra.outputs({'partitions': partitions}).process_partitions task is an io.kestra.plugin.core.flow.ForEach iterating over {{ outputs.get_partitions.vars.partitions }} with concurrencyLimit: 0, so every partition runs at the same time.partition task is another Python Script in Docker. It reads {{ taskrun.value }} to know which file it owns, simulates processing, then emits Kestra.counter('nr_rows', ...) and Kestra.timer('processing_time', ...), each tagged with the partition name.nr_rows counter and processing_time timer) visible in the Metrics tab.A bare Python script can loop over files, but it cannot natively retry a single failed partition, cap concurrency declaratively, surface per-partition metrics, or expose execution lineage. Kestra adds event triggers, automatic retries, declarative YAML for the whole fan-out, and built-in metric tracking. The ForEach task handles parallelism and concurrency limits for you, and each partition becomes an independently observable task run rather than a hidden iteration inside one process.
{{ secret('NAME') }} values.process_partitions task fan out into parallel partition runs.nr_rows and processing_time per partition.get_partitions with a real listing task (object storage, a database query, or a directory scan).partition for actual extraction, transformation, or loading logic.concurrencyLimit to throttle parallelism when downstream systems are rate sensitive.