Streaming vs Batch Processing — Data Engineering

Streaming vs Batch Processing Dua paradigma utama dalam memproses data. Pilihan antara keduanya tergantung pada seberapa cepat data harus tersedia setelah…

Batch processing memproses data yang sudah terkumpul secara berkala, misalnya tiap malam. Stream processing (streaming) memproses tiap kejadian begitu datang. Bayangin cuci piring. Cara batch: piring ditumpuk seharian, lalu dicuci sekali malam hari. Hemat air dan sabun, tapi piring bersih baru ada besok. Cara streaming: tiap piring dicuci begitu selesai dipakai. Selalu bersih, tapi kamu bolak-balik ke wastafel seharian. Bedanya bukan mana yang lebih canggih, tapi seberapa cepat hasilnya harus ada, dan berapa harganya.

🧪 Tebakan cepat: pesanan Toko Buku dihitung streaming dengan jendela per minggu, dan satu event pesanan datang telat. Minggu 28 September keluar berapa buku: 13 kayak batch, atau kurang? Tebak dulu, jawabannya ada di bagian "Data telat dan watermark".

Batch, micro-batch, streaming

Batch Micro-batch Streaming
Kapan diproses terjadwal, misalnya tiap 00.00 tiap beberapa detik atau menit, dalam kelompok kecil tiap event, begitu datang
Latency (kejadian sampai hasil) menit sampai sehari detik sampai menit milidetik sampai detik
Tool Airflow + SQL atau Python, dbt Spark Structured Streaming Apache Flink, Kafka Streams
Contoh laporan harian, melatih ulang model tiap malam dashboard yang diperbarui tiap menit deteksi fraud, stok saat flash sale, alert

Streaming lebih tepat kalau data harus diproses dalam hitungan detik setelah masuk: menahan pembayaran yang mencurigakan, menjaga stok biar gak terjual melebihi persediaan, dashboard live, peringatan error. Kalau hasil yang terlambat beberapa jam atau sehari masih oke, batch lebih sederhana dan lebih murah.

Latency, kelengkapan, biaya

Tiga hal ini selalu ditukar satu sama lain:

Event time dan processing time

Di streaming, tiap pesanan dikirim sebagai event: pesan kecil berisi order_id, created_at, dan jumlah bukunya. Tiap event punya dua waktu:

Biasanya selisihnya cuma detik. Tapi event pesanan 8 (Maya, Minggu 4 Oktober 20.30) tertahan di queue job yang macet, kayak item 9 yang di-retry. Event itu baru sampai Senin 5 Oktober 12.00, setelah event pesanan 9 (Senin 11.20). Menurut event time, pesanan Maya masuk minggu 28 September. Menurut processing time, masuk minggu 5 Oktober. Pertanyaan pemilik soal kapan orang membeli, jadi yang benar event time.

Jendela: tumbling, sliding, session

Stream gak pernah selesai, jadi "jumlahkan semuanya" harus diganti "jumlahkan per jendela (window) waktu". Ini hasilnya dari 14 pesanan bersih (21 buku), menurut event time:

Jendela Artinya Hasil di Toko Buku
Tumbling 1 hari potongan tetap, gak tumpang tindih; tiap event masuk tepat satu jendela 28 Sep 3, 29 Sep 2, 30 Sep 3, 1 Okt 3, ... , 3 Okt 0, ... , 9 Okt 1
Tumbling 1 minggu sama, per Senin minggu 28 Sep 13, minggu 5 Okt 8
Sliding 3 hari, geser 1 hari jendela tumpang tindih; tiap event masuk 3 jendela 28 sampai 30 Sep 8, 29 Sep sampai 1 Okt 8, 2 sampai 4 Okt 2
Session, jeda 24 jam jendela berakhir kalau 24 jam gak ada event; panjangnya beda-beda 5 session: 3, 5, 4, 6, 3 buku

Session paling menarik kalau dihitung di batch, karena butuh window function. Di SQLite (Lab dan Playground):

WITH RECURSIVE bersih AS (
  SELECT *, ROW_NUMBER() OVER (PARTITION BY order_id, book_id ORDER BY id) AS ke
  FROM order_items
),
pesanan AS (
  SELECT o.id AS order_id, o.created_at, SUM(b.qty) AS buku
  FROM orders o
  JOIN bersih b ON b.order_id = o.id AND b.ke = 1
  GROUP BY o.id, o.created_at
),
jeda AS (
  SELECT *, (julianday(created_at) - julianday(LAG(created_at) OVER (ORDER BY created_at))) * 24 AS jam
  FROM pesanan
),
sesi AS (
  SELECT *, SUM(CASE WHEN jam IS NULL OR jam > 24 THEN 1 ELSE 0 END) OVER (ORDER BY created_at) AS sesi
  FROM jeda
)
SELECT MIN(created_at) AS jendela, MAX(created_at) AS terakhir, COUNT(*) AS pesanan, SUM(buku) AS buku
FROM sesi
GROUP BY sesi
ORDER BY sesi;
jendela terakhir pesanan buku
2026-09-28 09:15:00 2026-09-28 13:02:00 2 3
2026-09-29 20:11:00 2026-09-30 08:40:00 2 5
2026-10-01 10:05:00 2026-10-02 12:00:00 3 4
2026-10-04 20:30:00 2026-10-07 14:45:00 5 6
2026-10-08 16:10:00 2026-10-09 10:30:00 2 3

Data telat dan watermark

Prosesor streaming gak bisa menunggu selamanya sebelum menutup jendela. Dia pakai watermark: jam internal yang bilang "semua event sebelum waktu ini dianggap sudah datang". Bentuk yang umum: event time terbesar yang sudah terlihat, dikurangi waktu tunggu. Jendela ditutup dan hasilnya keluar begitu watermark melewati ujung jendela. Event yang datang setelah jendelanya ditutup namanya telat (late data), dan secara default dibuang.

Ini jendela minggu 28 September (berakhir Senin 5 Okt 00.00), dihitung di Lab dengan cara kerja jendela event time Flink:

Watermark menunggu Jendela keluar Isinya Pesanan Maya
0 jam Senin 5 Okt 11.20, waktu event pesanan 9 datang 12 buku dibuang: jendelanya sudah tutup waktu dia datang 12.00
12 jam Selasa 6 Okt 09.00, waktu event pesanan 10 datang 13 buku dihitung

Jawabannya 12, dan itu jawaban tebakannya: tanpa waktu tunggu, satu buku hilang tanpa error. Waktu tunggu 12 jam bikin hasilnya lengkap, tapi keluarnya sehari lebih lambat. Watermark cuma maju kalau ada event baru, dan pesanan Toko Buku jarang. Batch harian malah sudah punya angka lengkap 13 sejak Senin 00.00. Event telat juga bisa dikirim ke jalur terpisah (side output) buat dibetulkan belakangan, jadi gak dibuang.

Pertanyaan pemilik gak butuh streaming

Pemilik membaca "buku paling laku per kota per minggu" tiap Senin pagi. Batch harian jam 00.00 (DAG Airflow dari pelajaran sebelumnya) sudah memuat hari Minggu dari database dengan lengkap, termasuk pesanan Maya, cuma dengan kerja beberapa detik per hari. Kalau pakai streaming untuk pertanyaan ini, yang bertambah cuma Kafka, prosesor yang nyala terus, dan urusan watermark, padahal pesanannya cuma 14 dalam dua minggu. Streaming baru layak kalau ada keputusan yang harus diambil dalam hitungan detik: menolak pembayaran palsu, mengunci stok saat flash sale, membunyikan alarm saat checkout gagal beruntun.

Banyak tim pakai keduanya. Arsitektur Lambda menjalankan jalur batch (lengkap) dan jalur streaming (cepat) berdampingan. Risikonya, ada dua kode yang harus menghasilkan angka yang sama. Arsitektur Kappa cuma pakai streaming, dan menghitung ulang dengan memutar ulang event lama dari Kafka. Kafka dibahas di pelajaran Kafka for Data Pipelines, dan dashboard real-time di pelajaran Real-time Analytics Pipeline.

⚠️ Jebakan yang sering ketemu

TL;DR: Batch memproses data yang sudah terkumpul secara terjadwal: sederhana, murah, lengkap, tapi latency-nya menit sampai sehari. Streaming memproses tiap event begitu datang (Flink, Kafka Streams; micro-batch di Spark Structured Streaming): cocok kalau data harus diproses dalam hitungan detik, kayak fraud detection dan dashboard live, tapi biayanya jalan terus karena selalu nyala. Kelompokkan menurut event time (created_at), bukan processing time. Jendela tumbling gak tumpang tindih, sliding tumpang tindih, session berakhir setelah jeda tanpa event (Toko Buku: 5 session dengan jeda 24 jam). Watermark menentukan kapan jendela ditutup: dengan waktu tunggu 0 jam, pesanan Maya yang datang telat dibuang dan minggu 28 September jadi 12 buku; dengan 12 jam jadi 13, tapi sehari lebih lambat. Pertanyaan mingguan pemilik cukup dijawab batch harian. Kafka dibahas di pelajaran Kafka for Data Pipelines.

Yang akan kamu pelajari