<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hilary Wambwa</title>
    <description>The latest articles on DEV Community by Hilary Wambwa (@hilary_wambwa_dd49d0404fa).</description>
    <link>https://dev.to/hilary_wambwa_dd49d0404fa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3377706%2F4e03174e-b8f5-48f3-96a2-5e99503febae.jpg</url>
      <title>DEV Community: Hilary Wambwa</title>
      <link>https://dev.to/hilary_wambwa_dd49d0404fa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hilary_wambwa_dd49d0404fa"/>
    <language>en</language>
    <item>
      <title>Apache Kafka Deep Dive: Core Concepts, Data Engineering Applications, and Real-World Production Practices</title>
      <dc:creator>Hilary Wambwa</dc:creator>
      <pubDate>Thu, 11 Sep 2025 10:42:17 +0000</pubDate>
      <link>https://dev.to/hilary_wambwa_dd49d0404fa/apache-kafka-deep-dive-core-concepts-data-engineering-applications-and-real-world-production-2g6d</link>
      <guid>https://dev.to/hilary_wambwa_dd49d0404fa/apache-kafka-deep-dive-core-concepts-data-engineering-applications-and-real-world-production-2g6d</guid>
      <description>&lt;h3&gt;
  
  
  Kafka Architecture
&lt;/h3&gt;

&lt;p&gt;Kafka is an distributed streaming system that uses producers to publish data and consumers to subscribe to the data in real time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Topics&lt;/strong&gt; are hosted in &lt;strong&gt;partitions&lt;/strong&gt;. Several partitions make up a &lt;strong&gt;broker&lt;/strong&gt;. A &lt;strong&gt;cluster&lt;/strong&gt; is a group of brokers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Brokers&lt;/strong&gt; are servers that store and serve data. A cluster is made up of several brokers in communication. A broker stores topics in partitions.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;topic&lt;/strong&gt; is a logical stream of data. Think of it as a table in a structured database. Like data in a table, events are written to a topic.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;partition&lt;/strong&gt; is a unit of parallelism and scalability. Think of it as a subtopic. It is what makes Kafka distributed as partitions are distributed to brokers. A topic with 10 partitions can be processed by up to 10 consumers in parallel within a consumer group.&lt;/p&gt;

&lt;p&gt;An &lt;strong&gt;offset&lt;/strong&gt; is a position of a record in a partition. A partition contains messages. Each message is assigned a unique automatically increasing offset showing position of message in partition’s log.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ZooKeeper&lt;/strong&gt; is a historic external coordinator for Kafka. Imagine Kafka are roads and highways transporting data, then zookeeper is the traffic command center that assigns partitions, configures topics, monitors health of brokers. Since it is external, data engineers have to configure it separately. If zookeeper fails, an entire Kafka cluster drops.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kafka Raft&lt;/strong&gt; enables zookeeper to manage its own ‘traffic’ where Kafka brokers elect a ‘controller’ from a quorum of brokers to configure topics and assign partitions. If the controller fails, another broker takes over.&lt;br&gt;
Cluster setup and scaling.&lt;/p&gt;

&lt;p&gt;Scaling in Kafka means it is able to accommodate extra load by adding more brokers. Done in 3 steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A new broker registers with the cluster, updating the cluster metadata.&lt;/li&gt;
&lt;li&gt;Existing partitions are moved to the new broker to balance the load/redistribute.&lt;/li&gt;
&lt;li&gt;Consumers adjust to new partition assignments to maintain parallel processing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Producers and Consumers
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Producers&lt;/strong&gt;&lt;br&gt;
These produce, write or publish data into topics.&lt;/p&gt;

&lt;p&gt;Each message has a key attached to determine partition destination. Think of separate lines in a distribution center as partitions. If you use the same key (say, a user’s ID), all messages for that user go to the same partition, keeping things in order. For example, if you’re tracking orders for “User123,” all their order events are in one partition. This sends an order for “User123” to the “orders” topic, and Kafka figures out the partition based on the key.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Acknowledgment modes&lt;/strong&gt;&lt;br&gt;
Acks is how Kafka acknowledges a message.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Acks=0&lt;/em&gt;; Producer sends a message and does not wait for a reply/ acknowledgement. Fast and risky.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Acks=1&lt;/em&gt;; Producer waits for lead broker to acknowledge message. However, if lead broker crashes before copying message to other brokers, data is lost.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Acks=all&lt;/em&gt;; producer waits for all backup brokers (in sync replicas) to acknowledge the message. Slow but reliable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For critical stuff like bank transactions, you’d go with acks=all. Netflix, for example, uses this for their event streaming to make sure no data gets lost, as they handle billions of events daily.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consumers&lt;/strong&gt;&lt;br&gt;
These consume, read or subscribe data from topics.&lt;/p&gt;

&lt;p&gt;Consumer groups are like a team of workers. These consumers in one group are assigned to partitions in a topic. In case of a consumer fail, Kafka assigns partition to another consumer in the group.&lt;/p&gt;

&lt;p&gt;There are two ways to keep track of last message processed by consumers using offset.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatic Commits: Consumer activities are saved every few seconds (set by auto.commit.interval.ms). Easy but prone to skips and duplicates if anything crashes mid process.&lt;/li&gt;
&lt;li&gt;Manual Commits: The consumer decides when to save its progress, giving more control.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Message Delivery &amp;amp; Processing
&lt;/h3&gt;

&lt;p&gt;Message Delivery Semantics are mechanisms about whether a message sent by a producer will be delivered to a consumer and under what conditions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;At-most-once:&lt;/em&gt; Message is delivered zero or once. Might get lost, but never duplicated.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;At-least-once:&lt;/em&gt; message is delivered one or more times. Won’t get lost, but duplicates are possible.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Exactly-once:&lt;/em&gt; message is delivered exactly one time. No losses, no duplicates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These messages are retained via three methods:&lt;br&gt;
&lt;strong&gt;Time-based (e.g., keep data for 7 days)&lt;/strong&gt;&lt;br&gt;
Messages deleted after a specified time. Perfect for when data is only relevant for a specific period of time. Example: Consider a building management system that monitors temp readings from IOT sensors installed in a building. It only requires data that is hours or minutes long to make decisions and discards message after decision is made.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Size-based (e.g., max 1 GB).&lt;/strong&gt; &lt;br&gt;
This limits space a topic partition can use. In cases of the size exceeding limit, Kafka starts deleting the oldest messages. Used in cases where control over storage costs is critical.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Log compaction (keep the latest value per key).&lt;/strong&gt;&lt;br&gt;
Only most recent message for each key in a topic is kept. This is for keeping a single source of truth for each key ideal for monitoring the latest edition of an entity e.g., user profile updates.&lt;/p&gt;

&lt;h3&gt;
  
  
  Back pressure &amp;amp; Flow Control
&lt;/h3&gt;

&lt;p&gt;Back pressure is when producers write messages faster than consumers can read them. This can lead to consumers crashing or performance slowing down.&lt;/p&gt;

&lt;p&gt;There are several ways to handle slow consumers;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Consumer group scalability:&lt;/em&gt; Adding more consumers to handle the available partitions thus distributing load and reducing back pressure.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Pause and resume:&lt;/em&gt; consumers can pause and resume reading messages from specific partitions to clear backlog without overwhelm of messages&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Buffer management:&lt;/em&gt; Consumers use buffers that are configured to limit amount of data read per request. Lowering the limit prevents backlog of data in memory, reducing overload.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How can we monitor the speed of consumers?&lt;/strong&gt;&lt;br&gt;
This measures how far behind a consumer as far as the latest message in a partition is concerned.&lt;br&gt;
Lag = Latest Offset - Consumer Offset&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monitoring tools&lt;/strong&gt;&lt;br&gt;
The kafka-consumer-groups.sh tool displays lag for each partition in a consumer group.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command line&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;kafka-consumer-groups.sh --bootstrap-server localhost:9092 --group order-consumers --describe&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Metrics APIs&lt;/strong&gt;&lt;br&gt;
Kafka exposes JMX metrics like &lt;em&gt;kafka.consumer:consumer-lag&lt;/em&gt; for monitoring. Grafana can scrape these metrics for real-time dashboards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Third-Party Tools&lt;/strong&gt;&lt;br&gt;
Confluent Control Center or Burrow provide user-friendly interfaces for lag monitoring. According to a Confluent blog, monitoring lag is critical for ensuring SLAs in production systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Serialization &amp;amp; Deserialization
&lt;/h2&gt;

&lt;p&gt;In Kafka, messages are stored and transmitted as raw bytes. Serialization is the process of converting data like a JSON object into a byte stream that Kafka can handle. Deserialization takes that byte stream and turns it back into something meaningful, like a python dictionary or a JSON object, for the consumer to process. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JSON:&lt;/strong&gt; It’s human-readable, widely supported, and great for quick prototyping. Great for getting started, but for production and numerous messages, its size and lack of schema management can become a hinderance.&lt;br&gt;
Example:&lt;br&gt;
&lt;em&gt;{&lt;br&gt;
  "order_id": "12345",&lt;br&gt;
  "amount": 99.99&lt;br&gt;
}&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Avro:&lt;/strong&gt; a binary format designed for efficiency. Utilizes a schema used by producers and consumers to maintain consistency.&lt;br&gt;
The schema is stored separately in the Confluent Schema Registry. This way, one can add new fields to schema or make them optional without breaking consumers.&lt;br&gt;
Here’s an example Avro schema for an order:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9yjiuqbnjzwfdn8l64a0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9yjiuqbnjzwfdn8l64a0.png" alt=" " width="800" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When serialized, this schema produces a compact binary representation, unlike JSON’s bulky text.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Protobuf:&lt;/strong&gt; Like Avro, it’s a binary format, but it’s designed for cross-language compatibility; Java, Python, C++ and high performance; often smaller than avro.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz8sm2q0wh66dpsnma809.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz8sm2q0wh66dpsnma809.png" alt=" " width="800" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced Kafka Concepts
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Replication
&lt;/h3&gt;

&lt;p&gt;To prevent chaos if something goes wrong, Kafka creates multiple copies (replicas) of each partition and spreads them across different brokers&lt;br&gt;
Leader &amp;amp; follower replicas. &lt;br&gt;
&lt;strong&gt;Leader replicas&lt;/strong&gt; is the primary broker of a partition carrying out all reads and writes. &lt;br&gt;
&lt;strong&gt;Follower replicas&lt;/strong&gt; are backup brokers. They don’t serve directly but keep an ‘eye’ or copy of the leader’s activities.&lt;br&gt;
&lt;strong&gt;ISR (In-Sync Replicas)&lt;/strong&gt; are a list of replicas that are fully up-to-date with the leader’s data. If a follower falls behind, it’s kicked out of the ISR until it catches up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to configuring replication:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;replication.factor:&lt;/em&gt; How many total replicas (leader + followers) each partition should have. A replication.factor=3 means one leader and two followers.&lt;br&gt;
&lt;em&gt;min.insync.replicas:&lt;/em&gt; The minimum number of replicas that must be in sync for the leader to accept writes. Setting min.insync.replicas=2 ensures at least two replicas (including the leader) are up-to-date before acknowledging a write. &lt;/p&gt;

&lt;h3&gt;
  
  
  Fault tolerance
&lt;/h3&gt;

&lt;p&gt;A brief process of how Kafka handles failures&lt;br&gt;
&lt;strong&gt;Normally;&lt;/strong&gt; The leader replica for a partition ; Broker 1 handles all reads and writes, while followers; Brokers 2 and 3 replicate the data in real time.&lt;br&gt;
&lt;strong&gt;Failure;&lt;/strong&gt; If Broker 1 crashes, Kafka’s controller, part of the cluster management, handled by ZooKeeper or Kraft, detects the failure and promotes a follower to become the new leader.&lt;br&gt;
&lt;strong&gt;Recovery;&lt;/strong&gt; When Broker 1 comes back online, it rejoins as a follower, catching up on any missed messages before re-entering the ISR.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kafka Connect
&lt;/h3&gt;

&lt;p&gt;A scalable, easy to use framework built into Kafka to stream data. It’s a plug and play where only the connectors are configured while Kafka connect does the heavy lifting of integration. Two types of connectors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Source connectors: pull data into Kafka&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy7m0tmebf7k78k9x2203.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy7m0tmebf7k78k9x2203.png" alt=" " width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sink connectors: push data out of Kafka&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77vggczwttebo6fb7r8i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77vggczwttebo6fb7r8i.png" alt=" " width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each connector breaks the data flow into tasks, which run in parallel for scalability.&lt;/p&gt;

&lt;p&gt;An example is where a CDC pipeline is created to pull data from a postgres DB and post them on a Casandra DB with a postgres-Debezium source connector and debezium-Cassandra sink connector as shown in the above code snippets. &lt;br&gt;
Similarly, consider a retail company using a MongoDB source connector to feed inventory updates into Kafka, then a sink connector to push alerts to a notification system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kafka Streams
&lt;/h3&gt;

&lt;p&gt;A java library used to build real time data processing applications. It utilizes Kafka capabilities of scale and fault tolerance without the need of a separate system to process, analyze, and transform your data on the fly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stateless operations:&lt;/strong&gt; Each message (data record) is processed independently, with no context carried over.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Map:&lt;/em&gt; Transform data, like renaming.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Filter:&lt;/em&gt; Keep only certain records.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;FlatMap:&lt;/em&gt; Split one record into multiple.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Stateful operations:&lt;/strong&gt; These operations require maintaining “state” (context) across multiple messages.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Count: Track the number of orders per item.&lt;/li&gt;
&lt;li&gt;Aggregate: Sum up or average values.&lt;/li&gt;
&lt;li&gt;Join: Combine streams.
States are managed using state stores, which are backed by Kafka topics.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Windowing
&lt;/h3&gt;

&lt;p&gt;This is grouping data into time-based “windows” for analysis, perfect for real-time trends.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Tumbling:&lt;/em&gt; Fixed, non-overlapping time intervals (e.g., every 5 minutes).&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Hopping:&lt;/em&gt; Fixed intervals that overlap (e.g., 5-minute windows advancing every 1 minute). Like checking messages every minute but looking at the last 5 minutes.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Session:&lt;/em&gt; Dynamic windows based on user activity (e.g., group orders from the same customer if they’re within 10 minutes of each other).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ksqlDB
&lt;/h3&gt;

&lt;p&gt;SQL-like interface for streaming queries. It is like a streaming database developed on Kafka to query real time data using simple SQL commands. It operates on three terms:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Streams:&lt;/strong&gt; This is an immutable sequence of events. Take an example of a temperature monitoring system. Stream in this case is temperature updates sent by a sensor.&lt;/p&gt;

&lt;p&gt;This stream, stored in a Kafka topic called temperature_readings, keeps growing as new readings arrive.&lt;/p&gt;

&lt;p&gt;To define a temperature stream:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7n5hd94u72emr3gdlqh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7n5hd94u72emr3gdlqh.png" alt=" " width="800" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tables:&lt;/strong&gt; These are a snapshot of what’s happening now and represent the current state of data.&lt;br&gt;
Think of a stream as a log of every temperature reading ever sent, while a table is like a dashboard showing the most recent reading for each sensor.&lt;br&gt;
Lets create a table of latest temperatures.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F86cdofwfjqz9lky7vkqa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F86cdofwfjqz9lky7vkqa.png" alt=" " width="800" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Queries:&lt;/strong&gt; To analyze tables and streams using SQL.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Push Queries:&lt;/em&gt; Continuously deliver results as new data arrives, like a live feed of temperature alerts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwrnjsopbjpz3kekqozbc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwrnjsopbjpz3kekqozbc.png" alt=" " width="800" height="122"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Pull Queries:&lt;/em&gt; Fetch the current state from a table.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcdc8wdxhgpibxrtjjsjx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcdc8wdxhgpibxrtjjsjx.png" alt=" " width="800" height="77"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Transactions &amp;amp; Idempotence
&lt;/h3&gt;

&lt;p&gt;Kafka’s transactions and idempotence features are used to ensure every message is processed exactly once no duplicates, no misses by allowing the processing of data across multiple topics and partitions as a single, atomic unit. &lt;/p&gt;

&lt;p&gt;This in turn enables exactly-once semantics (EOS), a holy grail for applications where precision is non-negotiable, like financial systems. EOS means a message is delivered and processed exactly once, despite the occurrence of network failures or broker crashes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Idempotence&lt;/strong&gt; ensures that even if a producer retries sending a message due to a broker failure, Kafka recognizes it as a duplicate and only records it once. This is achieved using a unique producer id and sequence numbers for each message.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Use Case:&lt;/em&gt; A bank uses Kafka to process transactions. Without EOS, a transfer could be recorded twice, overcharging a customer. &lt;/p&gt;

&lt;h3&gt;
  
  
  Security in Kafka
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Authentication&lt;/strong&gt; in Kafka is used to prevent unauthorized access of messages and topics.&lt;br&gt;
&lt;em&gt;SASL(Simple Authentication and Security Layer):&lt;/em&gt; Think of it as a versatile ID checker. It supports protocols like PLAIN (username/password), GSSAPI (Kerberos for enterprise environments), and SCRAM (secure password-based authentication). &lt;br&gt;
&lt;em&gt;Kerberos&lt;/em&gt; is common in large organizations like banks, where strict identity verification is a must.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;OAuth:&lt;/em&gt; This is like using a third-party app like Google to log in. It’s great for modern, cloud-native setups.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authorization (Access Control Lists, ACLs)&lt;/strong&gt;&lt;br&gt;
Once users are verified, you need to control what they can do. Authorization in Kafka uses ACLs to define permissions. ACLs specify who can perform actions e.g., read, write, delete on topics or consumer groups.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Encryption (TLS)&lt;/strong&gt;&lt;br&gt;
Encryption ensures messages stays confidential. Kafka uses Transport Layer Security to encrypt data in transit between producers, consumers and brokers, as well as between brokers. &lt;br&gt;
&lt;em&gt;Enabling TLS&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F898vibzoy0muypudi5j9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F898vibzoy0muypudi5j9.png" alt=" " width="800" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Operations &amp;amp; Monitoring
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Consumer lag&lt;/strong&gt;&lt;br&gt;
This measures how far behind a consumer as far as the latest message in a partition is concerned.&lt;br&gt;
Lag = Latest Offset - Consumer Offset&lt;br&gt;
Lag shows how quick consumers can handle the incoming data volume. If lag keeps growing, a real-time pipeline might not be so “real-time” anymore.&lt;br&gt;
To monitor this, we can set alerts for lag thresholds e.g., &amp;gt;1000 messages using tools like Prometheus and Grafana.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Broker health &amp;amp; under-replicated partitions&lt;/strong&gt;&lt;br&gt;
Brokers are the heart of a Kafka cluster. Broker health metrics, especially under-replicated partitions (URPs), tell if brokers are keeping up with replication.&lt;/p&gt;

&lt;p&gt;Kafka uses replication to ensure fault tolerance. Each partition has a leader replica and follower replicas. If followers can’t keep up with the leader, URPs are displayed, signaling potential data loss risks if the leader fails. &lt;/p&gt;

&lt;p&gt;To monitor this, we check the UnderReplicatedPartitions metric via Kafka’s JMX metrics or tools like Prometheus. A non-zero value indicates trouble.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Throughput &amp;amp; latency&lt;/strong&gt;&lt;br&gt;
Throughput is a measure of how many messages a cluster processes per second. Latency tracks how long it takes for a message to go from producer to consumer.&lt;/p&gt;

&lt;p&gt;Low throughput or high latency can choke a pipeline. For example, if streaming real-time analytics, slow throughput could delay driver updates, impacting user experience.&lt;/p&gt;

&lt;p&gt;Monitoring is via metrics like &lt;em&gt;BytesInPerSec&lt;/em&gt;, &lt;em&gt;BytesOutPerSec&lt;/em&gt;, and &lt;em&gt;MessageInPerSec&lt;/em&gt; for throughput, and &lt;em&gt;RequestLatencyAvg&lt;/em&gt; for latency, using JMX. &lt;br&gt;
Latency can be reduced by optimizing network settings or reducing partition counts for low-traffic topics.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scaling Kafka
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Partition count tuning&lt;/strong&gt;&lt;br&gt;
More partitions mean more parallelism, letting consumer groups process messages faster. A topic with 10 partitions can be consumed by up to 10 consumers in a group, speeding up throughput. However, too many partitions can increase overhead, like having too many queues confusing your baristas. &lt;/p&gt;

&lt;p&gt;A good rule of thumb, per the Kafka documentation, is to start with 1–2 partitions per broker and adjust based on throughput needs.&lt;br&gt;
&lt;strong&gt;NOTE:&lt;/strong&gt; A a topic’s partition count can’t be changed without recreating it, so it is wise to plan ahead. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adding brokers&lt;/strong&gt;&lt;br&gt;
Adding brokers increases storage and throughput capacity, it is like opening a new counter to serve more customers.&lt;br&gt;
New brokers are added the cluster, and Kafka redistributes partitions to balance the load. The cluster metadata is updated via the Kafka controller.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rebalancing partitions&lt;/strong&gt;&lt;br&gt;
After adding brokers or tuning partitions, rebalancing partitions is necessary to spread the load evenly, like reassigning baristas to quieter queues. &lt;/p&gt;

&lt;p&gt;kafka-reassign-partitions.sh tool moves partitions between brokers, ensuring no single broker is overwhelmed while others sit idle.&lt;br&gt;
Tip: Rebalancing can be resource-intensive, so schedule it during low-traffic periods&lt;br&gt;
Weaving it all together, tune partitions to match throughput needs, add brokers to handle more traffic, and rebalance to keep things smooth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance Optimization
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Batching and compression&lt;/strong&gt;&lt;br&gt;
Producers send messages to brokers, but sending each message individually is like inefficient. Batching groups multiple messages into a single request, reducing network overhead and boosting throughput.&lt;br&gt;
To configure this, we use linger.ms, which sets how long a producer waits to accumulate messages before sending a batch. A small delay 5milliseconds can dramatically increase throughput by allowing more messages to be sent together. Another setting, batch.size, controls the maximum size of a batch (in bytes).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Page cache usage&lt;/strong&gt;&lt;br&gt;
Kafka uses the operating system’s page cache, a portion of RAM used to cache disk data. When producers write messages to a partition, they’re stored on disk but also kept in the page cache. Consumers reading recent messages can often pull them directly from memory, avoiding slow disk I/O. This is especially powerful for Kafka’s log-based architecture, where messages are appended sequentially, making cache hits common.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disk and network considerations&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Disk considerations:&lt;/strong&gt;&lt;br&gt;
Kafka stores messages on disk in a log-based structure, making disk performance critical. To optimize this:&lt;br&gt;
&lt;em&gt;Use SSDs:&lt;/em&gt; Solid-state drives (SSDs) offer faster I/O than traditional HDDs, reducing write and read latency.&lt;br&gt;
&lt;em&gt;Separate log directories:&lt;/em&gt; Spread Kafka’s log directories (log.dirs) across multiple disks to parallelize I/O.&lt;br&gt;
&lt;em&gt;Avoid overloading disks:&lt;/em&gt; Monitor disk I/O using tools like iostat. If disk utilization nears 100%, add more disks or brokers to distribute load.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Network considerations:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;High-Bandwidth NICs:&lt;/em&gt; Use network interface cards (NICs) with at least 1 Gbps (preferably 10 Gbps) to handle high message volumes. &lt;br&gt;
This ensures Kafka can handle large bursts of traffic without bottlenecks.&lt;br&gt;
&lt;em&gt;Enable compression:&lt;/em&gt; Compression reduces network load. For network-bound clusters, lz4 compression offers a good balance of speed and efficiency.&lt;br&gt;
&lt;em&gt;Monitor network latency:&lt;/em&gt; Use metrics like network-io-rate to spot bottlenecks. If latency spikes, consider upgrading network hardware or optimizing producer/consumer configurations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Cases
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Uber's Real-Time Ad System&lt;/strong&gt;&lt;br&gt;
Imagine running Uber Eats ads where every click or impression is money on the line. Mess up, and you’re either losing revenue or overcharging advertisers. In 2021, Uber built a slick system using Apache Kafka, Flink, Pinot, and Hive to process ad events (clicks, impressions) in near real-time with exactly-once precision, no duplicates, no losses. It’s like a coffee shop where every order is tracked perfectly, even during a rush.&lt;/p&gt;

&lt;p&gt;Kafka acts as the reliable message queue, with topics like “Mobile Ad Events” split into partitions for parallel processing. Producers (the app) send events with acks=all for reliability, while Flink jobs (consumers) aggregate, attribute, and load data across two regions for failover. &lt;/p&gt;

&lt;p&gt;Exactly-once semantics: Flink’s “read_committed” mode and Kafka’s transactions, paired with unique record UUIDs, ensure no double-counting. Retention policies keep 3-day backups for recovery, and replication across brokers guarantees fault tolerance. Flink’s 1-minute windowing handles back pressure, while consumer lag monitoring keeps the pipeline smooth.&lt;/p&gt;

&lt;p&gt;This setup powers ad auctions, billing, and analytics, processing millions of events weekly with sub-2-minute latency. Uber’s use of Kafka’s partitioning, transactions, and scalability shows how theory fuels real-world wins, delivering fast, accurate insights for advertisers.&lt;/p&gt;

&lt;p&gt;Link to article : &lt;a href="https://www.uber.com/en-KE/blog/real-time-exactly-once-ad-event-processing/" rel="noopener noreferrer"&gt;https://www.uber.com/en-KE/blog/real-time-exactly-once-ad-event-processing/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pinterest&lt;/strong&gt;&lt;br&gt;
Pinterest hales massive data with 459 million users pinning images non-stop. To manage this data of 40 million messages per second, 50 GB/s traffic, pinterest leans on Apache Kafka, running 50+ clusters with 3,000 brokers. &lt;/p&gt;

&lt;p&gt;Kafka’s topics and partitions are central, handling 3,000+ topics and 500K partitions for user events and database changelogs. Static “brokersets” ensure even partition distribution, boosting scalability. Producers like Singer (logging) and Maxwell (DB ingestion) publish compressed messages. Consumers, such as S3 Transporter for analytics and Flink/Kafka Streams for real-time spam detection or recommendations, use consumer groups to scale processing.&lt;/p&gt;

&lt;p&gt;Serialization uses compact formats to ease CPU strain during upgrades. For performance optimization, SSDs replace magnetic disks, slashing I/O latency, while batching and compression boost throughput.&lt;/p&gt;

&lt;p&gt;Pinterest powers real-time monetization and safety pipelines, processing petabytes for ML and metrics. Kafka’s partitioning, replication, and monitoring make this data chaos a seamless, scalable win.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhv96vgjt91agc30w7ih3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhv96vgjt91agc30w7ih3.png" alt=" " width="800" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Link to article: &lt;a href="https://www.confluent.io/blog/running-kafka-at-scale-at-pinterest/" rel="noopener noreferrer"&gt;https://www.confluent.io/blog/running-kafka-at-scale-at-pinterest/&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>BRIEF INTRODUCTION TO DOCKER AND DOCKER COMPOSE</title>
      <dc:creator>Hilary Wambwa</dc:creator>
      <pubDate>Wed, 27 Aug 2025 10:18:03 +0000</pubDate>
      <link>https://dev.to/hilary_wambwa_dd49d0404fa/brief-introduction-to-docker-and-docker-compose-2hc2</link>
      <guid>https://dev.to/hilary_wambwa_dd49d0404fa/brief-introduction-to-docker-and-docker-compose-2hc2</guid>
      <description>&lt;h2&gt;
  
  
  DOCKER
&lt;/h2&gt;

&lt;p&gt;Docker is a tool to develop and run applications in containers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A container&lt;/strong&gt; provides an isolated environment for an application and its dependencies(libraries) to ensure it runs across environments (OS systems/machines). It is in itself a running instance of an image.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An image&lt;/strong&gt; is a blueprint containing everything needed to run an application (code, libraries e.t.c).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;br&gt;
Docker has two installation options.&lt;br&gt;
&lt;strong&gt;Docker desktop:&lt;/strong&gt; &lt;br&gt;
&lt;a href="https://docs.docker.com/desktop/setup/install/windows-install/" rel="noopener noreferrer"&gt;https://docs.docker.com/desktop/setup/install/windows-install/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker engine via WSL Linux distribution:&lt;/strong&gt; &lt;a href="https://gist.github.com/dehsilvadeveloper/c3bdf0f4cdcc5c177e2fe9be671820c7" rel="noopener noreferrer"&gt;https://gist.github.com/dehsilvadeveloper/c3bdf0f4cdcc5c177e2fe9be671820c7&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s do it practically:&lt;br&gt;
In this example, we will have three files.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Requirements text file&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
This file contains libraries needed to run our application (e.g pandas)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Python file(main.py)&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Import pandas&lt;br&gt;
print("Trump")&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Dockerfile&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
This is a script/instruction that guide how an image is created.&lt;/p&gt;

&lt;h5&gt;
  
  
  Specify an official Python base image. Instead of installing python, we pull this image from the registry
&lt;/h5&gt;

&lt;p&gt;FROM python:3.13-slim&lt;/p&gt;

&lt;h5&gt;
  
  
  Set working directory
&lt;/h5&gt;

&lt;p&gt;WORKDIR /app&lt;/p&gt;

&lt;h5&gt;
  
  
  Copy requirements file and install dependencies
&lt;/h5&gt;

&lt;p&gt;COPY requirements.txt .&lt;br&gt;
RUN pip install -r requirements.txt&lt;/p&gt;

&lt;h5&gt;
  
  
  Copy contents in project directory to our app directory.
&lt;/h5&gt;

&lt;p&gt;COPY . .&lt;/p&gt;

&lt;h5&gt;
  
  
  Run the application
&lt;/h5&gt;

&lt;p&gt;CMD ["python", "main.py"]&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker Compose
&lt;/h2&gt;

&lt;p&gt;Docker compose is a tool that makes it easy for data engineers/developers to define and run multi container Docker applications.&lt;/p&gt;

&lt;p&gt;Imagine you're building a complex data pipeline via docker that needs multiple databases, Kafka and a CDC tool e.g. Debezium. Without Docker compose you'd be typing in multiple commands to get each of these containers up and running for every service needed to run your application for instance you'd start with something like Docker run for your databases adding in all those parameters for ports volumes and networks again diving back into the terminal typing another lengthy docker run command with even more parameters to ensure that it runs your app.&lt;/p&gt;

&lt;p&gt;This process can be very error prone as there is more potential for typos or mistakes that could send you back to square one.&lt;/p&gt;

&lt;p&gt;Enter Docker compose where you define your multi container setup in a single yaml file that outlines which images to user build the ports the volumes and how these containers should talk to one another configurations for services are defined.&lt;/p&gt;

&lt;p&gt;In a .yml file which uses yaml syntax a service definition in Docker compose tells Docker how to run a specific container based on an image including configurations like ports volumes environment variables and dependencies on other services. With just a simple docker-compose up command Docker compose gets to work bringing your entire application to life seamlessly. When you're done you can simply run docker compose down to tear it all down.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Here are some commands for managing containers and images:&lt;/em&gt;&lt;br&gt;
&lt;em&gt;&lt;strong&gt;docker build -t app&lt;/strong&gt;&lt;/em&gt;: Build an image from a Dockerfile &lt;br&gt;
&lt;strong&gt;&lt;em&gt;docker images&lt;/em&gt;&lt;/strong&gt;: List downloaded images.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;docker run &lt;/em&gt;&lt;/strong&gt;: Start a container from an image.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;docker ps&lt;/em&gt;&lt;/strong&gt;: List running containers.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;docker ps -a&lt;/em&gt;&lt;/strong&gt;: List all containers.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;docker stop &lt;/em&gt;&lt;/strong&gt;: Stop a container.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;docker rm &lt;/em&gt;&lt;/strong&gt;: Remove a container.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;docker rmi &lt;/em&gt;&lt;/strong&gt;: Remove an image.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;docker-compose up&lt;/em&gt;&lt;/strong&gt;: Start all services defined in compose&lt;br&gt;
&lt;strong&gt;&lt;em&gt;docker-compose down&lt;/em&gt;&lt;/strong&gt;: Stop and remove all services&lt;/p&gt;

</description>
    </item>
    <item>
      <title>15 Must-Know Data Engineering Tricks</title>
      <dc:creator>Hilary Wambwa</dc:creator>
      <pubDate>Sun, 10 Aug 2025 22:31:18 +0000</pubDate>
      <link>https://dev.to/hilary_wambwa_dd49d0404fa/15-must-know-data-engineering-tricks-18ec</link>
      <guid>https://dev.to/hilary_wambwa_dd49d0404fa/15-must-know-data-engineering-tricks-18ec</guid>
      <description>&lt;p&gt;Think of data engineering as the behind-the-scenes hero that makes sense of the massive amounts of data modern companies deal with every day.&lt;br&gt;
Here are 15 tricks that will help you navigate this field.&lt;/p&gt;

&lt;h2&gt;
  
  
  Batch vs Streaming ingestion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Batch Ingestion:&lt;/strong&gt; Fixed chunks of data is ingested on a fixed schedule or manually into a system. &lt;br&gt;
&lt;strong&gt;&lt;em&gt;Example:&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;processing daily sales data for a retail company from a transactional database to a warehouse.&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;Streaming:&lt;/strong&gt; Data or events are ingested into a system in real time or near real time based on a trigger. &lt;br&gt;
&lt;strong&gt;&lt;em&gt;Example:&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;processing data from a temperature monitoring IOT sensor in a green house.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Change Data Capture (CDC)
&lt;/h2&gt;

&lt;p&gt;Style of data movement where every change (inserts, updates, deletes) is captured in real time to move data from one data source to target without reprocessing the entire datasets.&lt;br&gt;
Three ways to perform CDC:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log based: Every database transaction is logged in a log file. Pick up the changes and move from the log to target. Efficient, no impact on source system&lt;/li&gt;
&lt;li&gt;Query based: Querying the data in the source based on a timestamp to pick up the changes. Source must have a column tracking the last modification timestamp.&lt;/li&gt;
&lt;li&gt;Triggers: Database triggers are created to log/store the changes in a separate audit table which are then read and propagated to the target database.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; &lt;em&gt;A healthcare institution stores patient records in a transactional database. This data is moved to an Amazon Redshift warehouse via log-based change data capture therefore storing patients’ historical data for tracking and compliance.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Idempotency
&lt;/h2&gt;

&lt;p&gt;Given that the same input is used, a data pipeline/processes should produce the same results regardless of the number of times it runs or system failures such as network, server or API.&lt;br&gt;
Without idempotency, scheduled retries could lead to duplication of data, incomplete data states as well as costly computation and storage.&lt;br&gt;
How to practice idempotency:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use unique IDs for each data operation/record.&lt;/li&gt;
&lt;li&gt;Verify the state of data to confirm if incoming data matches current data.&lt;/li&gt;
&lt;li&gt;Deduplication: Kafka’s exactly-once semantics, ensures messages are processed only once by tracking offsets and transaction IDs.&lt;/li&gt;
&lt;li&gt;Using unique constraints/upsert operations on databases e.g INSERT ... ON CONFLICT DO NOTHING/UPDATE in SQL to avoid duplicates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  OLTP vs OLAP
&lt;/h2&gt;

&lt;p&gt;OLTP is a database design system which entails transactional/read-write operations (insert, update, drop) of high volume and frequent datasets.&lt;br&gt;
OLAP is designed to optimize complex queries and aggregations often used in data warehouses to analyze large historical data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Columnar vs Row-based Storage
&lt;/h2&gt;

&lt;p&gt;To understand this let’s consider a table with sales data; 1 million rows and the following rows (customer_id, date, amount, order_id). &lt;/p&gt;

&lt;p&gt;In a Columnar based storage, each column data is stored separately in memory i.e all 1 million customer_id are stored together separate from date, amount and order_id. This is perfect for OLAP systems where aggregation is common e.g SUM(amount) query only reads amount column, skipping the rest. It minimizes disk I/O.&lt;/p&gt;

&lt;p&gt;In a Row based storage, data is stored by row where all attributes of one record are stored together. This is perfect for OLTP where read-write operations are commonly done on entire records.&lt;/p&gt;

&lt;h2&gt;
  
  
  Partitioning
&lt;/h2&gt;

&lt;p&gt;This is dividing data into small partitions using attributes such as date and geographical regions. It is useful in optimizing querying and processing such that in a large dataset, the system uses partitions to only query the relevant data instead of the whole dataset.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Horizontal partitioning: Partitioning a subset of rows based on attributes such as date.&lt;/li&gt;
&lt;li&gt;Vertical partitioning: Splitting a table into columns, most frequently queried columns are stored in one partition while those less frequently queried stored in another.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ETL vs ELT
&lt;/h2&gt;

&lt;p&gt;ETL (Extract, Transform, Load): Extract data from source, transform and load into target. Common in structured data warehouses.&lt;br&gt;
ELT (Extract, Load, Transform): Extract data from source, loads into target then transform the data. Common in cloud data lakes as they leverage the cloud’s compute power.&lt;/p&gt;

&lt;h2&gt;
  
  
  CAP Theorem
&lt;/h2&gt;

&lt;p&gt;In a distributed system where data is stored across different nodes, when a communication failure between nodes occurs, a system must choose between consistency (all nodes show the same data) or availability (the system remains operational). Partition tolerance is a constant, so the trade off is between consistency and availability.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Examples:&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Consistency: Every read operation retrieves the most recent write. Crucial for data accuracy. Consider banking where if a user transfers Ksh.1000, all nodes update to reflect this immediately.&lt;br&gt;
Availability: System must remain operational to respond to requests. Responsive over accuracy. Social media platform retrieves posts even though some nodes are disconnected, sometimes showing outdated posts.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Windowing in Streaming
&lt;/h2&gt;

&lt;p&gt;When streaming, data comes in fast and continuously. Processing and analyzing the data requires bounded chunks of data to calculate averages, sums e.t.c. Windowing is dividing this data in bounded streams(windows). These windows are based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Time: 5-minute bounds&lt;/li&gt;
&lt;li&gt;Count: Every 100 events&lt;/li&gt;
&lt;li&gt;Session: A user’s browsing/shopping session.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Example:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;A ride hailing company uses time-based windows to adjust price based on real time demand (ride duration or number of requests)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  DAGs and Workflow Orchestration
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Directed Acyclic Graph (DAG)&lt;/strong&gt; uses nodes and directed edges to create an execution order for tasks avoiding cycles meaning tasks cannot loop back to earlier steps.&lt;br&gt;
&lt;strong&gt;Workflow orchestration&lt;/strong&gt; is the managing and scheduling of these tasks. Apache Airflow is an example of workflow orchestration tool.&lt;br&gt;
A DAG is written using python to extract air quality data from an API, transform the data and load it in a database. An airflow scheduler provides execution order while the web UI monitors the DAG. If the DAG fails(error), airflow logs the error, retries the task and displays or sends an alert.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retry Logic &amp;amp; Dead Letter Queues
&lt;/h2&gt;

&lt;p&gt;Retry logic is redoing a task over and over where the retry is not only done after some time and not immediately (configurable delays) but also the retry time increases exponentially with each attempt (exponential backoff) i.e. 1s, 2s, 4s, 8s. This helps avoid overwhelming target system with retries as well as increasing wait time to allow system recovery.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backfilling &amp;amp; Reprocessing
&lt;/h2&gt;

&lt;p&gt;Backfilling is input of historical data to a system to fill gaps or correct errors especially when introducing a new pipeline.&lt;br&gt;
Reprocessing on the other hand is re-running pipelines on existing data to fix errors, increase accuracy of the data or when introducing new transformations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Example:&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;A marketing firm introduces a new analytic platform. It has to backfill years of campaign data for historical analysis.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Governance
&lt;/h2&gt;

&lt;p&gt;These are rules that define the management and protection of an organization’s data to ensure security, quality and compliance.&lt;br&gt;
It helps to define who owns the data, who accesses it and what is included in the metadata.&lt;/p&gt;

&lt;h2&gt;
  
  
  Time Travel &amp;amp; Data Versioning
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Time travel:&lt;/strong&gt; This is the ability to query data as it existed at a certain time in the past. Imagine debugging a pipeline and need to see what your data looked like last week before a bug corrupted it. Time travel enables one to rewind the data at the specific time without altering it.&lt;br&gt;
&lt;strong&gt;Data Versioning:&lt;/strong&gt; Monitoring changes to dataset overtime similar to version control in software engineering i.e., Git. Each change creates a new version of data allowing analysis of how data has evolved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Distributed Processing Concepts
&lt;/h2&gt;

&lt;p&gt;Distributed processing is carrying out complex tasks involving large data using multiple connected nodes (servers/cloud instances). This divides tasks into smaller and parallel tasks. The opposite is centralized processing where one machine carries out all the tasks.&lt;br&gt;
Distributed processing relies on several concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parallel processing: This is executing several tasks simultaneously.&lt;/li&gt;
&lt;li&gt;Partitioning: Dividing data in small chunks where each node processes a partition independently.&lt;/li&gt;
&lt;li&gt;Fault tolerance: Ability to continue operating despite system failure. In this case if a node fails while processing, another node is used to recompute the task.&lt;/li&gt;
&lt;li&gt;Load balancing: Distribution of tasks equally across nodes to avoid bottlenecks and delays.&lt;/li&gt;
&lt;li&gt;Distributed coordination: Tasks have to be managed for synchronization. A good example is Apache Zookeeper.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Understanding Data Warehousing for Retail Analytics: A Comprehensive Guide</title>
      <dc:creator>Hilary Wambwa</dc:creator>
      <pubDate>Sat, 26 Jul 2025 11:06:56 +0000</pubDate>
      <link>https://dev.to/hilary_wambwa_dd49d0404fa/understanding-data-warehousing-for-retail-analytics-a-comprehensive-guide-24e5</link>
      <guid>https://dev.to/hilary_wambwa_dd49d0404fa/understanding-data-warehousing-for-retail-analytics-a-comprehensive-guide-24e5</guid>
      <description>&lt;h2&gt;
  
  
  What is it?
&lt;/h2&gt;

&lt;p&gt;A data warehouse is a central store used for managing large volumes of historical and current data for an organization. Unlike operational and transactional databases, it is optimized for analysis and business intelligence.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are its components?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Database
&lt;/h3&gt;

&lt;p&gt;This is the core storage component in a data warehouse built upon a data model. Dimensional modelling is the preferred method of coming up with the blueprint/data model for this database because it is both query optimizing and easy to grasp i.e. Fact table for quantitative measurable metrics and dimension tables for descriptive/attribute content adding meaning to fact tables. &lt;br&gt;
Two schema designs are used in this modelling:&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Star schema:&lt;/em&gt;&lt;/strong&gt; simple and intuitive. It is denormalized, query optimizing, compatible with reporting and BI tools but storage inefficient.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Snowflake schema:&lt;/em&gt;&lt;/strong&gt; complex and extends star schema by normalizing tables. It is normalized, storage efficient, maintains data integrity by reducing redundancy but makes queries and ETL processes more complex due to multiple joins.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Data Sources
&lt;/h3&gt;

&lt;p&gt;Since data warehouses are central, they fetch data from multiple sources:&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Transactional databases:&lt;/em&gt;&lt;/strong&gt; handle real time, small scale, frequent, read-write operations (OLTP). Normalized to reduce redundancy. Example: A retail MySQL dB managing daily sales. &lt;br&gt;
&lt;strong&gt;&lt;em&gt;Customer Relationship Management (CRM):&lt;/em&gt;&lt;/strong&gt; systems that store company interactions with customers and prospects. Example: A CRM containing customer profiles, sales leads, campaigns and purchase history.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Enterprise Resource Planning (ERP):&lt;/em&gt;&lt;/strong&gt; integrate and manage core business processes; Finance, HR, supply chain and inventory. Highly normalized for operational efficiency. Example: ERP table for inventory containing ItemID, StoreID, Quantity, Cost, Date_of_purchase.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;APIs:&lt;/em&gt;&lt;/strong&gt; basically, how systems share data. In this context, a retail company’s website real time/ near real time traffic data (page views, user demographics) can be pulled using Google Analytics API and stored in a warehouse for analysis.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Flat Files:&lt;/em&gt;&lt;/strong&gt; simple, non-relational files stored in formats such as CSV, JSON, XML. Stored in local systems/cloud before ingesting into data warehouse. Example: A CSV file of customer survey responses stored in S3 buckets then loaded into data warehouse to analyze customer satisfaction.&lt;/p&gt;

&lt;h2&gt;
  
  
  How are these data sources integrated into the warehouse?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3. ETL/ELT Processes
&lt;/h3&gt;

&lt;p&gt;This is where ETL/ELT comes in handy.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Extraction:&lt;/em&gt;&lt;/strong&gt; Pulling data from sources mentioned above to ensure all relevant data is collected.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Transformation:&lt;/em&gt;&lt;/strong&gt; Cleaning and standardizing the data. Removing duplicates, handling missing values, ensuring data integrity i.e. standardize date formats. Different sources have different formats, conventions; An ERM may use Firstname, Lastname order while a CRM uses Lastname, Firstname order. &lt;br&gt;
To optimize performance and reduce query complexity, aggregation of the data is necessary e.g. aggregating daily transactional data to weekly sales.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Loading:&lt;/em&gt;&lt;/strong&gt; Organizing the data into an optimized structure i.e. in a star schema to improve query performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Take Note:&lt;/em&gt;&lt;/strong&gt; Stages can be very useful to store Flat files temporarily before loading them into tables. A good example is Snowflakes AWS S3 stage which is managed by snowflake. It may also be external e.g. AWS S3, Azure Blob, Google Cloud Storage but will require configuration. In the case of retail: An AWS S3 stage storing customer survey responses in a CSV file.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Query and reporting tools
&lt;/h3&gt;

&lt;p&gt;Allow users to interact with stored data, generate insights and build reports. These includes business intelligence platforms: Power BI, Tableau, Looker as well as SQL tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real World Applications
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Amazon employs Amazon Redshift, a cloud-based data warehouse, to handle vast amounts of data from its e-commerce platform, including clicks, impressions, website visitors, and purchase histories. This supports marketing analytics, tracks key performance indicators (KPIs) like conversion rates and churn, and enables reverse ETL to target audiences effectively.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Target Corporation, one of the largest retailers in the United States, uses a sophisticated data warehouse to power its analytics and decision-making. Their system, known as the “Guest Data Platform,” integrates data from various sources to create a unified view of each customer. This has enabled target to:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Implement highly successful personalized marketing campaigns&lt;/li&gt;
&lt;li&gt;Optimize store layouts based on customer behavior analysis&lt;/li&gt;
&lt;li&gt;Improve inventory management, reducing stockouts and overstocks&lt;/li&gt;
&lt;li&gt;Enhance their online and mobile shopping experiences&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dataengineering</category>
      <category>datawarehouse</category>
      <category>retailanalytics</category>
    </item>
  </channel>
</rss>
