All Data Labs

Data engineering

Incremental Order Events Pipeline

medium3–4 hours4 datasets
Company
Instacart
Job positions
Data EngineerAnalytics Engineer
Topics
Data pipelinesIncremental loadingDeduplicationData quality testsSQL

The scenario

Instacart: Load raw order events one day at a time into clean tables that stay correct with duplicates, late events and a changing schema.

Instacart's apps send an event every time an order moves forward: placed, shopper assigned, picked and delivered. The events land in storage as one file per day. Analysts keep getting different order counts from the same data, and the operations team wants daily numbers it can trust. You're a data engineer on the fulfillment data team.

Your task

Build a pipeline that loads the daily event files one at a time into clean tables, producing an order table and daily metrics that are correct and do not change when the pipeline runs again.

Instructions

  1. 1Load the three event files in date order, one run per file, as if each one arrived on its own day. Profile each file before transforming it.
  2. 2Design a staging layer that keeps every event exactly once, even when the same event is sent twice or arrives in a later file.
  3. 3Handle the new column that appears in the third file without breaking the earlier loads.
  4. 4Build a fact_orders table with one row per order: order_id, store_id, order_date (the UTC date of the placed event), placed_at, final_status (delivered, canceled or in_progress) and minutes_to_deliver (from placed to delivered, rounded to 1 decimal place).
  5. 5Build a daily_order_metrics table with order_date, orders_placed, orders_delivered, orders_canceled and avg_minutes_to_deliver, rounded to 1 decimal place. A day's numbers must update when its late events arrive in a later file.
  6. 6Make every load safe to run twice: loading the same file again must not change the output tables. Add data tests for unique orders, valid statuses and events in a sensible order.
  7. 7Write a README that explains how to run the pipeline, the table design and every data problem you found.

Datasets

All files come in one download.

events_2025_10_01.csv

Events delivered on October 1, 2025, in the order they were received.

752 rows · 5 columns · 35 KB

ColumnTypeDescription
event_idintegerUnique ID of the event.
order_idintegerThe order the event belongs to.
store_idintegerThe store fulfilling the order.
event_typetextWhat happened: placed, shopper_assigned, picked, delivered or canceled.
event_timetextWhen it happened, in UTC.
Preview the first 5 rows
event_idorder_idstore_idevent_typeevent_time
90067640174105delivered2025-10-01T11:44:28Z
90059940154101picked2025-10-01T13:54:39Z
90066040170103shopper_assigned2025-10-01T22:52:29Z
90008240021105delivered2025-10-01T12:52:36Z
90056040144103delivered2025-10-01T11:19:55Z

events_2025_10_02.csv

Events delivered on October 2, 2025.

853 rows · 5 columns · 40 KB

ColumnTypeDescription
event_idintegerUnique ID of the event.
order_idintegerThe order the event belongs to.
store_idintegerThe store fulfilling the order.
event_typetextWhat happened: placed, shopper_assigned, picked, delivered or canceled.
event_timetextWhen it happened, in UTC.
Preview the first 5 rows
event_idorder_idstore_idevent_typeevent_time
90104540269101picked2025-10-02T19:10:44Z
90162240417102canceled2025-10-02T10:02:32Z
90107940278104placed2025-10-02T11:47:15Z
90087140225106picked2025-10-02T12:22:02Z
90153040393105delivered2025-10-02T19:20:53Z

events_2025_10_03.csv

Events delivered on October 3, 2025. The mobile team started sending the app version this day.

844 rows · 6 columns · 46 KB

ColumnTypeDescription
event_idintegerUnique ID of the event.
order_idintegerThe order the event belongs to.
store_idintegerThe store fulfilling the order.
event_typetextWhat happened: placed, shopper_assigned, picked, delivered or canceled.
event_timetextWhen it happened, in UTC.
app_versiontextVersion of the app that sent the event.
Preview the first 5 rows
event_idorder_idstore_idevent_typeevent_timeapp_version
90104240268102delivered2025-10-02T19:10:43Z5.13.0
90186640482106shopper_assigned2025-10-03T16:28:38Z5.13.0
90229440598101picked2025-10-03T19:00:26Z5.13.0
90176040454101shopper_assigned2025-10-03T18:23:06Z5.12.1
90193340501101placed2025-10-03T18:09:21Z5.13.0

stores.csv

Partner stores that fulfill orders.

6 rows · 3 columns · 1 KB

ColumnTypeDescription
store_idintegerUnique ID of the store.
store_nametextStore name.
citytextCity the store is in.
Preview the first 5 rows
store_idstore_namecity
101Greenway MarketSeattle
102Harbor FoodsSeattle
103Maple GroceryChicago
104Sunrise MartChicago
105Valley Co-opAustin

Hints

A later file can hold an event from an earlier day. Decide which day an order belongs to from the event's own timestamp, never from the file it arrived in.

When you combine files in pandas, a column missing from older files is filled with empty values, so the new column does not need special handling there.

events = pd.concat([day_1, day_2, day_3], ignore_index=True)

Deliverable

A public GitHub repo with your pipeline (Python, SQL or dbt), the fact_orders and daily_order_metrics outputs as CSV files, your data tests, and a README explaining how to run it and how it handles duplicates, late events and schema changes.

When you're done, post your repo in the Solutions tab to share it with other learners.

What grading checks

Use this checklist to review your own work before you post and share it.

  • Submitted GitHub repo is public and reachable.
  • Repo contains pipeline code in Python, SQL or dbt.
  • fact_orders output has one row per order with the correct final status and delivery minutes.
  • daily_order_metrics output matches the expected counts and averages for every day, including late events.
  • Loads are safe to run twice, and the README explains how.
  • Data tests cover unique orders, valid statuses and event order.
  • README explains how duplicates, late events and the new column are handled.