Skip to content

Big Data Ingestion Patterns — Complete Guide

DodaTech Updated 2026-06-23 7 min read

In this tutorial, you'll learn about Big Data Ingestion Patterns. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

Big Data ingestion is the Process of moving data from source systems into storage or processing platforms — and choosing the right ingestion pattern determines the reliability, latency, and cost of your entire data pipeline.

What You'll Learn

In this tutorial, you'll learn the main data ingestion patterns — batch ingestion, streaming ingestion, change data capture (CDC), log ingestion, and API polling — with Python examples for each pattern.

Why It Matters

Data ingestion is where pipelines break most often. A poorly designed ingestion pattern causes data loss, duplicate records, excessive latency, and snowballing operational costs.

Real-World Use

Netflix ingests 1.5 trillion events daily from 230 million subscribers across multiple patterns: Kafka streams for real-time viewing events, S3 batch uploads for content metadata, and CDC from relational databases for user profile changes.

flowchart TD
  subgraph Sources
    A[Databases]
    B[Logs]
    C[APIs]
    D[Message Queues]
    E[IoT Devices]
  end
  subgraph Ingestion Patterns
    F[Batch Ingestion]
    G[Streaming Ingestion]
    H[CDC]
    I[Log Ingestion]
    J[API Polling]
  end
  subgraph Storage
    K[Data Lake S3]
    L[Kafka Topics]
    M[Warehouse]
  end
  A --> H
  B --> I
  C --> J
  D --> G
  E --> F
  H --> L
  I --> K
  J --> F
  G --> L
  F --> K

Batch Ingestion

Batch ingestion loads data in scheduled intervals (hourly, daily). It's simple, cost-effective, and suitable for non-latency-sensitive use cases.

import time
from datetime import datetime

def simulate_batch_ingestion():
    source_data = [
        {"id": 1, "name": "Alice", "signup_date": "2026-06-20"},
        {"id": 2, "name": "Bob", "signup_date": "2026-06-21"},
        {"id": 3, "name": "Charlie", "signup_date": "2026-06-22"},
    ]

    last_ingested_id = 0
    batch_count = 0

    def ingest_batch(source, last_id, batch_size=2):
        new_records = [r for r in source if r["id"] > last_id][:batch_size]
        if new_records:
            print(f"[{datetime.now().strftime('%H:%M:%S')}] Batch {batch_count}:")
            for record in new_records:
                print(f"  Ingested: {record}")
            return max(r["id"] for r in new_records)
        return last_id

    while last_ingested_id < len(source_data):
        batch_count += 1
        last_ingested_id = ingest_batch(source_data, last_ingested_id)
        time.sleep(0.5)

    print(f"\nBatch ingestion complete. {len(source_data)} records ingested.")

simulate_batch_ingestion()

Expected output:

[HH:MM:SS] Batch 1:
  Ingested: {'id': 1, 'name': 'Alice', 'signup_date': '2026-06-20'}
  Ingested: {'id': 2, 'name': 'Bob', 'signup_date': '2026-06-21'}
[HH:MM:SS] Batch 2:
  Ingested: {'id': 3, 'name': 'Charlie', 'signup_date': '2026-06-22'}

Batch ingestion complete. 3 records ingested.

Batch ingestion uses a watermark (last_ingested_id) to track progress. Each batch loads only new records since the last watermark.

Streaming Ingestion

Streaming ingestion processes data continuously as it arrives. It's more complex but provides sub-second latency.

import time
import random

def simulate_streaming_ingestion():
    print("Starting stream ingestion (Ctrl+C to stop)...")
    events_ingested = 0
    start = time.time()

    source_events = ["click", "view", "purchase", "search"] * 10000

    for event_type in source_events[:20]:
        event = {
            "type": event_type,
            "user_id": random.randint(1000, 9999),
            "timestamp": time.time(),
            "value": random.random() * 100,
        }
        events_ingested += 1
        elapsed = time.time() - start
        print(f"[{elapsed:.3f}s] Ingested: {event['type']} user={event['user_id']}")

        time.sleep(random.uniform(0.05, 0.2))

    rate = events_ingested / (time.time() - start)
    print(f"\nStream rate: {rate:.1f} events/second")

simulate_streaming_ingestion()

Expected output (approximate):

Starting stream ingestion (Ctrl+C to stop)...
[0.000s] Ingested: click user=5432
[0.123s] Ingested: view user=7890
[0.198s] Ingested: purchase user=1234
...
[2.500s] Ingested: search user=9876

Stream rate: ~7.5 events/second

Streaming ingestion decouples producers and consumers through a message queue (Kafka, Kinesis). The ingestion rate adapts to source throughput.

Change Data Capture (CDC)

CDC captures database changes (inserts, updates, deletes) in real time by reading the database Transaction log.

import json
import time

def simulate_cdc_ingestion():
    transaction_log = [
        {"lsn": 100, "operation": "INSERT", "table": "users", "data": {"id": 1, "name": "Alice"}},
        {"lsn": 101, "operation": "UPDATE", "table": "users", "data": {"id": 1, "name": "Alice Smith"}},
        {"lsn": 102, "operation": "DELETE", "table": "users", "data": {"id": 2}},
        {"lsn": 103, "operation": "INSERT", "table": "orders", "data": {"id": 100, "user_id": 1, "amount": 49.99}},
    ]

    state = {}
    last_lsn = 0

    def apply_change(change):
        table = change["table"]
        op = change["operation"]
        data = change["data"]

        if table not in state:
            state[table] = {}

        if op == "INSERT":
            state[table][data["id"]] = data
            print(f"CDC INSERT: {table}[{data['id']}]")
        elif op == "UPDATE":
            state[table][data["id"]] = data
            print(f"CDC UPDATE: {table}[{data['id']}]")
        elif op == "DELETE":
            del state[table][data["id"]]
            print(f"CDC DELETE: {table}[{data['id']}]")

    for change in transaction_log:
        if change["lsn"] > last_lsn:
            apply_change(change)
            last_lsn = change["lsn"]
            time.sleep(0.3)

    print("\nReplicated state:")
    print(json.dumps(state, indent=2))

simulate_cdc_ingestion()

Expected output:

CDC INSERT: users[1]
CDC UPDATE: users[1]
CDC DELETE: users[2]
CDC INSERT: orders[100]

Replicated state:
{
  "users": {
    "1": {"id": 1, "name": "Alice Smith"}
  },
  "orders": {
    "100": {"id": 100, "user_id": 1, "amount": 49.99}
  }
}

Tools like Debezium and AWS DMS implement CDC by reading database binlogs (MySQL) or WAL (PostgreSQL) and streaming changes to Kafka.

Log Ingestion

Log ingestion collects application and system logs for analysis.

import json
import time

def simulate_log_ingestion():
    log_entries = [
        {"level": "ERROR", "service": "auth", "message": "Connection timeout to DB", "ip": "10.0.0.1"},
        {"level": "INFO", "service": "api", "message": "Request processed in 45ms", "ip": "10.0.0.2"},
        {"level": "WARN", "service": "auth", "message": "Rate limit approaching", "ip": "10.0.0.1"},
        {"level": "ERROR", "service": "payment", "message": "Payment gateway declined", "ip": "10.0.0.3"},
    ]

    log_aggregator = []

    for entry in log_entries:
        log_aggregator.append(entry)
        print(f"LOG {entry['level']}: {entry['service']} - {entry['message']}")

    print(f"\nTotal logs ingested: {len(log_aggregator)}")

    error_count = sum(1 for e in log_aggregator if e["level"] == "ERROR")
    print(f"Errors detected: {error_count}")

simulate_log_ingestion()

Expected output:

LOG ERROR: auth - Connection timeout to DB
LOG INFO: api - Request processed in 45ms
LOG WARN: auth - Rate limit approaching
LOG ERROR: payment - Payment gateway declined

Total logs ingested: 4
Errors detected: 2

Flume, Filebeat, and Fluentd are common log ingestion agents. They tail log files and forward entries to HDFS, Kafka, or Elasticsearch.

Common Mistakes Beginners Make

1. Not handling duplicates

Network retries cause duplicate messages. Design idempotent ingestion — processing the same message twice should produce the same result.

2. Ignoring schema evolution

Source schemas change. Use schema registries (Avro, Protobuf) and design your ingestion to handle backward-compatible schema changes.

3. Overwhelming downstream systems

A sudden data burst can saturate your warehouse. Use Rate Limiting, buffering (Kafka), and backpressure handling in ingestion.

4. No monitoring for ingestion lag

Ingestion lag (time between event creation and ingestion) is a key health metric. Alert when lag exceeds thresholds.

5. Forgetting about data retention

Source systems may delete old data after ingestion. Ensure you have the retention policy and backup Strategy before cleaning sources.

Practice Questions

  1. What is the difference between batch and streaming ingestion? Batch ingestion loads data at scheduled intervals (hourly/daily) with higher latency but lower cost. Streaming ingestion processes data continuously with sub-second latency but higher complexity.

  2. How does Change Data Capture (CDC) work? CDC reads database Transaction logs (binlog, WAL) and streams changes to a target system. It captures inserts, updates, and deletes without impacting the source database.

  3. Why is idempotent ingestion important? Network retries and exactly-once delivery guarantees can produce duplicate messages. Idempotent ingestion ensures duplicates don't create incorrect results.

Challenge

Design a CDC pipeline for a PostgreSQL database that streams changes to Kafka, transforms them with Kafka Streams, and lands them in both S3 (Parquet) and a real-time dashboard. Handle schema changes gracefully.

Real-World Task

Set up a filebeat agent on your local machine to tail a log file and forward entries to a local Elasticsearch instance via Logstash. Verify the ingested logs in Kibana.

FAQ

**What ingestion pattern should I use for IoT sensor data?**

Streaming ingestion with MQTT or Kafka. IoT data is continuous, time-sensitive, and high-volume. Batch ingestion would lose the real-time value.

**Is it OK to mix batch and streaming in the same pipeline?**

Yes. This is the Lambda architecture: streaming for real-time views, batch for reconciling accuracy. The Kappa architecture uses streaming for everything.

**How do I handle schema changes in ingested data?**

Use a schema registry (Confluent Schema Registry, Apicurio) with Avro or Protobuf. Define compatibility rules (backward, forward, full) to control what changes are allowed.

**What tools are commonly used for data ingestion?**

Kafka, Flume, Sqoop, NiFi, StreamSets, Airbyte, Fivetran, and cloud-native tools like AWS Glue and GCP Dataflow. Choose based on your source SQL databases and target systems.

**How do I monitor ingestion health?**

Track ingestion lag, record count, error rate, and throughput. Use Prometheus metrics or Kafka consumer lag monitoring. Docker containers simplify running ingestion agents.

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

What's Next

Data Pipeline Orchestration
NoSQL Distributed Databases
Data Lake vs Data Warehouse

Congratulations on completing this Big Data Ingestion tutorial! Here's where to go from here:

  • Practice daily — Consistency is more important than long study sessions
  • Build a project — Apply what you learned by building something real
  • Explore related topics — Check out other tutorials in the same category
  • Join the community — Discuss with other learners and share your progress

Remember: every expert was once a beginner. Keep coding!

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro