Schedule icon
Query icon
If icon
Fail icon
Set icon
Log icon

Monthly NYC Taxi Metrics with DuckDB as a Backfill Partition Job

Compute monthly NYC taxi trip metrics with DuckDB from public Parquet files in Kestra, as an idempotent job ready for partitioned backfills.

Categories
Data

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.

How it works

  1. 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.
  2. 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.
  3. Otherwise 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.
  4. 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.
  5. The 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.

What you get

  • Real monthly metrics from a public dataset, with no account, credentials or download step.
  • An idempotent job: one result per month, overwritten on re-run.
  • A data-quality gate that refuses to store empty months.
  • Retries for brief network errors, and a clear error in the logs when a month fails, without a duplicate alert, since the controller reports failed partitions.
  • A template for the partition contract the backfill controller expects: partition_start inclusive, partition_end exclusive.

Who it's for

  • Anyone trying the safe-backfill-controller blueprint.
  • Data engineers looking for a DuckDB-over-HTTP pattern for remote Parquet files.

Why orchestrate this with Kestra

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.

Prerequisites

  • Outbound HTTPS from the Kestra worker to d37ci6vzurychx.cloudfront.net.
  • No secrets are needed.

Inputs

  • 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

  • {{ outputs.metrics }} (flow output) / {{ outputs.monthly_metrics.row }}: month, trips, avg_distance_miles, avg_fare_usd and revenue_usd (whole dollars).
  • KV key nyc_taxi_metrics_<yyyy_MM>: the stored metrics for the month.

Quick start

  1. Save the flow and run it with the defaults to get January 2024's metrics.
  2. To backfill many months, run safe-backfill-controller with this flow as job_flow_id.

How to extend

  • Load the results into a warehouse table instead of the KV store, for example with io.kestra.plugin.jdbc.postgresql.Query using an upsert on the month.
  • Switch to green taxi or for-hire vehicle data by changing the file name in the URL.
  • Add metrics such as tips, airport trips or trips per borough using the TLC zone lookup.

Links

Orchestrate with Kestra
Orchestrate DuckDB with Kestra
Share this Blueprint
See How

New to Kestra?

Use blueprints to kickstart your first workflows.