Batch: Picture, Rhythm, Example

Concepts covered: Batch Processing

A batch pipeline has 3 moving parts beyond the data itself: a scheduler that knows when to fire, a job that does the work, and the storage the job reads from and writes to. The scheduler is the only part awake all the time, and its whole task is to watch a clock. The job is where compute starts, runs, and shuts down, and that lifecycle is what this section traces, minute by minute.

The scheduler submits the job once a night. The job reads yesterday's signups, writes one table, and exits. Between runs the middle box has no running process.
  • signups db (source, application database)
  • nightly count job (transform, scheduler)
  • daily_counts (storage, warehouse table)
  • morning dashboard (consumer, dashboard)
  • signups db -> nightly count job
  • nightly count job -> daily_counts
  • daily_counts -> morning dashboard

One run, minute by minute

ClockWhat happensCompute state
02:00:00The scheduler reaches the trigger time and submits the jobStarting: a machine is requested
02:01:00The job's process is up and connects to the signups databaseRunning
02:01:30It reads every signup dated April 24Running: reading
02:06:00It counts the rows per country in memoryRunning: computing
02:07:30It overwrites `daily_counts` with the new rowsRunning: writing
02:08:00The job reports success and its process exitsShut down
02:08 until 02:00 next dayNothing runs. The scheduler watches the clockOff

Three points on that timeline matter more than the rest. Compute starts at 02:00, when the scheduler submits the job and a machine is allocated. Compute runs from 02:01 to 02:08, and this is the only period in which data is touched. Compute shuts down at 02:08, and from then until the next trigger the pipeline costs nothing and does nothing. A batch pipeline is defined as much by the 23 hours and 52 minutes it is off as by the 8 minutes it is on.

The window is the boundary

SELECT
  country,
  COUNT(*) AS signups
FROM signups
WHERE signup_date = DATE '2026-04-24'
GROUP BY country

The WHERE clause draws the window. The run at 02:00 on April 25 owns signups dated April 24 and nothing else. A signup at 23:59 on April 24 is counted 2 hours and 9 minutes after it happened. A signup at 00:01 on April 25 belongs to the next window and waits until 02:08 on April 26, which is 26 hours and 7 minutes. Two records created 2 minutes apart show up in the output 24 hours apart, and that gap is the price of a daily window.

Every run replaces its result

The animation wrote daily_counts in overwrite mode, and that is the usual batch choice. Each run produces the complete answer for its window and replaces whatever the previous run wrote for it. If the job fails at 02:05 and someone restarts it at 02:20, the second attempt reads the same April 24 rows, computes the same counts, and leaves the table exactly as a successful first attempt would have. A batch run is a unit you can repeat, because its window closed when the day ended.

A user signs up at 02:03 on April 25, while the nightly job is already running. When does that signup first appear in daily_counts?

About this lesson

This section is part of the Batch vs Streaming: Beginner lesson on DataDriven, the home of data engineering. Lessons cover SQL, Python, Spark, data modeling and pipeline architecture, and each section pairs its explanation with worked examples and practice you run as you go.