New to Kestra?
Use blueprints to kickstart your first workflows.
Compute monthly NYC taxi trip metrics with DuckDB from public Parquet files in Kestra, as an idempotent job ready for partitioned backfills.
A small, real data job built to be backfilled. Given a month as partition_start and partition_end, it reads that month's NYC yellow taxi trips directly from the public TLC Parquet file with DuckDB, computes trip count, average distance, average fare and revenue, and stores the result under one key per month. Re-running a month overwrites its result, which makes the job safe to retry. It's the example job for the safe-backfill-controller blueprint, and it's a useful template for any partitioned job.
monthly_metrics (io.kestra.plugin.jdbc.duckdb.Query) runs one SQL query over https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_<yyyy-MM>.parquet. DuckDB loads its HTTP extension automatically and reads only the columns the query needs, so it never downloads the whole file. A month that isn't published yet fails here.quality_gate (io.kestra.plugin.core.flow.If) fails the run with empty_month when the window has no trips, so an empty partition is never stored or checkpointed as done.store_result (io.kestra.plugin.core.kv.Set) upserts the metrics as JSON under nyc_taxi_metrics_<yyyy_MM>, and log_result logs the headline numbers.monthly_metrics retries up to 3 times on brief network errors. If the month still fails, log_failure in the errors branch logs which task failed and why, and nothing is stored, so a later run can retry the month.monthly_refresh trigger (io.kestra.plugin.core.trigger.Schedule, shipped disabled) processes the previous month on the 15th, after TLC publishes it, by setting the partition inputs from trigger.date.partition_start inclusive, partition_end exclusive.safe-backfill-controller blueprint.The same flow serves the monthly schedule and historical backfills. Kestra passes the partition as typed inputs, keeps a log and output per month, and lets the controller run it per partition with checkpoints. There's no separate script to maintain for backfills.
d37ci6vzurychx.cloudfront.net.partition_start (DATE, default 2024-01-01): first day of the month, inclusive.partition_end (DATE, default 2024-02-01): first day of the next month, exclusive.{{ outputs.metrics }} (flow output) / {{ outputs.monthly_metrics.row }}: month, trips, avg_distance_miles, avg_fare_usd and revenue_usd (whole dollars).nyc_taxi_metrics_<yyyy_MM>: the stored metrics for the month.safe-backfill-controller with this flow as job_flow_id.io.kestra.plugin.jdbc.postgresql.Query using an upsert on the month.DuckDB plugin: https://kestra.io/plugins/plugin-jdbc-duckdb
NYC TLC trip record data: https://www.nyc.gov/site/tlc/about/tlc-trip-record-data.page
DuckDB reading Parquet over HTTP: https://duckdb.org/docs/extensions/httpfs/https
This blueprint has been created by Biplab Bera
