NYC Taxi Analytics
Millions of New York yellow-cab trips ingested, cleaned and modelled end to end in Microsoft Fabric, from raw Parquet files to a Power BI report.
5.97M
trips processed
$159.5M
revenue analysed
3
orchestrated pipelines
Platform
Microsoft Fabric
Stack
- Microsoft Fabric
- Data Factory
- Lakehouse
- Data Warehouse
- Dataflow Gen2
- T-SQL
- Power BI
Context
As part of my exploration of data engineering, I built a project on open data from the NYC Taxi & Limousine Commission to produce an analytical Power BI report. The project follows a structured processing pipeline: ingestion of raw Parquet files, transformation and storage in a data warehouse, then modelling and visualisation through a semantic model.
By using Azure Data Factory for workflow orchestration and stored procedures for query optimisation, I designed an interactive dashboard highlighting taxi traffic trends in New York.
Solution architecture
- TLC
- Lakehouse
- Staging
- Warehouse
- Power BI
- Step 01Source
Data collection — NYC Taxi & Limousine Commission
The project uses the TLC Trip Record Data, which tracks the trips of New York City's yellow taxis. These taxis, also known as medallion taxis, can pick up passengers in all five boroughs but operate mostly in Manhattan.
Source — TLC Trip Record Data - Step 02Landing
Data landing — Fabric Lakehouse
I downloaded the data available for 2024 and loaded it into a Fabric lakehouse, which acts as the storage layer where these files land.
- →Yellow taxi trips are stored in Parquet format, one file per month.
- →A taxi zone lookup table is stored as CSV and holds static reference data about taxi zones.
- Step 03Orchestration
Data ingestion — Data Factory copy activity
Once the files are in the lakehouse, a Data Factory copy activity ingests them into a staging table of the data warehouse. The taxi zone lookup is also loaded into staging as a static table, processed once and left unchanged.
The trip file path is generated dynamically from the
v_datevariable, so the pipeline automatically picks up each new month of data:Data Factory expression@concat('yellow_tripdata_', variables('v_date'), '.parquet') - Step 04Bronze
Staging layer
- →The staging layer contains the main table
stg.nyctaxi_yellow, which stores the taxi trips. - →It also includes the static lookup table
stg.taxi_zone_lookup, which describes NYC taxi zones.
- →The staging layer contains the main table
- Step 05Silver
Cleaning & transformation — stored procedures & Dataflow Gen2
At this stage I cleanse and process the data before moving it to the presentation layer.
Out-of-period cleanup
- 01A stored procedure dynamically deletes data outside the current processing period. It takes two parameters:
@start_date(start of the period) and@end_date(end of the period). - 02A Set Variable activity defines
v_end_dateasv_dateplus one month, so the pipeline processes the correct time range. - 03A Stored Procedure activity calls
stg.data_cleaning_stg, mappingv_dateto@start_dateandv_end_dateto@end_date. - 04For consistency, the Copy to Staging activity empties
stg.nyctaxi_yellowbefore each run, so only data for the current period is processed.
Metadata logging
I created a
metadataschema with aprocessing_logtable that records every pipeline execution. After cleaning and transformation, a record is inserted with:- →
pipeline_run_id— unique identifier of the run. - →
table_processed— name of the processed table. - →
rows_processed— number of rows processed. - →
latest_processed_pickup— latest pickup datetime in the batch. - →
processed_datetime— execution timestamp.
The insertion logic is wrapped in a stored procedure so that logging runs systematically as part of the pipeline.
Self-advancing processing window
To always process the next available month,
v_dateis updated from the last processed data. A Script activity,Latest_Processed_Data, fetches the most recenttpep_pickup_datetime(when the meter was engaged) frommetadata.processing_log, then a Set Variable activity adds one month to it.The resulting pipeline,
pl_stg_processing_nyctaxi, automates ingestion, cleansing and tracking: it adjusts the processing period, loads staging, removes out-of-period records and updates the metadata table for full traceability.Enrichment with Dataflow Gen2
A Dataflow Gen2 moves the cleaned data from staging to the presentation layer. It left-joins
nyctaxi_yellowwithtaxi_zone_lookupto add borough and zone details for both pickup and drop-off, removes unnecessary columns, categorises values and loads the result intodbo.nyctaxi_yellow.The
pl_processing_nyctaxipipeline runs this dataflow, then calls theinsert_presentation_metadatastored procedure to log the number of rows, the latest pickup timestamp and the execution time fordbo.nyctaxi_yellow.Master pipeline
Finally, a master pipeline orchestrates
pl_stg_processing_nyctaxithenpl_processing_nyctaxisequentially: staging runs first, followed by transformation and loading into the presentation layer. This guarantees data consistency and end-to-end automation. - 01A stored procedure dynamically deletes data outside the current processing period. It takes two parameters:
- Step 06Gold
Presentation layer — semantic model
With
dbo.nyctaxi_yellowfinalised, I built a semantic model that structures and optimises the data for Power BI, with relationships and calculated measures for efficient querying. - Step 07Serving
Power BI report
The report analyses yellow-cab performance with key metrics such as total revenue, number of trips and passengers. Interactive filters let you explore trends by payment method, vendor and pickup/drop-off borough.
Summary
This project shows what Microsoft Fabric can do for data engineering and BI by combining pipelines, dataflows, stored procedures, scripts and semantic modelling. Raw NYC yellow-taxi data is ingested, cleaned, enriched and stored in a presentation layer, then modelled for a Power BI dashboard covering revenue, trip volume and passenger distribution.
Automation is built into every stage: pipelines orchestrate ingestion, transformation and loading, while metadata logging guarantees traceability. The result is a reliable, low-maintenance flow that keeps analytics up to date.
Next project · 02
Global Earthquake Monitor
API ingestion · Medallion lakehouse