← Back to list

Cost Optimization in Real-Time Streaming Systems

Introduction

Jatin Agrawal · 2026-05-17 10:49 · 0 claps · 6.5 min read
#real-time-analytics #cost-optimization #data-pipeline #real-time-streaming-data #flink-optimization
Open on Medium ↗
Wiki topics: GRW · Growth & Analytics 🔧 · Data Engineering 🎬 · Film & Television

Cost Optimization in Real-Time Streaming Systems

Introduction

Real-time streaming systems powered by Apache Kafka and Apache Flink have become the backbone of modern data infrastructure. They enable businesses to react to events as they happen — fraud detection, live dashboards, personalized recommendations, and operational alerting all depend on sub-second data processing.

However, this power comes at a steep cost. Running Kafka clusters with days of retention, over-provisioned Flink executors, and redundant computations across multiple consumers can easily balloon cloud bills into six or seven figures annually. The irony? Most of this spend is waste — paying for capacity that sits idle or data that nobody reads.

In this article, I’ll share four battle-tested strategies that can reduce your real-time infrastructure costs by 40–70% while maintaining (or even improving) system reliability:

  1. Kafka data minimization — keep only hot data on brokers, archive to S3

  2. Lag-based auto-scaling — dynamically right-size Flink executors

  3. On-the-fly aggregation — reduce data volume at the source

  4. Medallion architecture — compute once, serve many consumers

Strategy 1: Kafka Data Minimization + S3 Archival

The Problem

Most teams configure Kafka with retention periods of 7–30 days “just in case.” This means every broker needs enough disk to hold a month of data across all topics. For high-throughput systems processing millions of events per second, this translates to terabytes of expensive EBS storage attached to each broker node.

The reality? Real-time consumers process events within seconds of arrival. That 7-day retention window exists only for rare replay scenarios — debugging, backfills, or disaster recovery. You’re paying premium SSD prices to store data that’s accessed once in its lifetime.

The Solution

Separate hot and cold data paths. Keep only 1–2 hours of retention on Kafka (enough for consumer recovery) and continuously sink all data to S3 in columnar format (Parquet/ORC) for cheap long-term storage and on-demand replay

Implementation Details

Kafka Connect S3 Sink Connector: Continuously exports topic data to S3 in Parquet format, partitioned by date/hour for efficient querying

Retention Configuration: Set retention.ms to 2–4 hours and cleanup.policy=delete on production topics

Replay Mechanism: Use a lightweight consumer that reads from S3 and re-publishes to a replay topic when needed

Cost Comparison: S3 Standard at $0.023/GB/month vs Kafka EBS (gp3) at $0.08–$0.10/GB/month — a 4–5x reduction in storage cost

Results

A typical high-throughput system writing 500GB/day to Kafka with 7-day retention holds 3.5TB per broker. Reducing to 2-hour retention drops this to ~42GB — an 88% reduction in Kafka storage costs. The S3 archive costs a fraction and enables analytics queries via Athena/Spark that weren’t possible before.

Strategy 2: Lag-Based Auto-Scaling of Flink Executors

The Problem

Most Flink deployments are sized for peak load and left running 24/7. If your peak is 10x your average (common for e-commerce, media, fintech), you’re paying for 10x resources during off-peak hours — nights, weekends, and holidays.

Traditional auto-scaling based on CPU/memory doesn’t work well for streaming because these metrics lag behind the actual processing backlog. By the time CPU spikes, you’re already accumulating consumer lag and potentially violating SLAs.

The Solution

Use consumer lag (the difference between the latest offset and the consumer’s committed offset) as the primary scaling signal. Lag is a leading indicator — it grows before CPU pressure does, giving you time to scale up proactively. When lag drops below a threshold, scale down to save costs.

Implementation Details

Monitoring: Export kafka_consumer_group_lag metric to Prometheus. Alert on rate of change, not absolute value

Scale-up trigger: When lag exceeds 10K messages (or lag growth rate > 1K/sec), add TaskManagers. Use Flink’s Reactive Mode or Kubernetes HPA with custom metrics

Scale-down trigger: When lag stays below 1K for 10+ minutes, remove TaskManagers. Add a cooldown period to prevent flapping

Graceful scaling: Use Flink savepoints during scale-down to preserve exactly-once semantics. New TaskManagers restore from the latest checkpoint

Results

For a system with 10x peak-to-trough ratio, lag-based scaling typically achieves 40–60% reduction in compute costs. The system runs with 2 executors during quiet hours and scales to 10+ during peak, matching capacity to actual demand in real-time.

Strategy 3: On-the-Fly Aggregation

The Problem

Many real-time pipelines treat every event as sacred, passing raw granular data through multiple processing stages and storing it for downstream queries. But most consumers don’t need individual events — they need aggregates: counts per minute, averages per region, totals per product category.

Processing 10 million raw events per minute when your dashboard only displays 50 aggregated data points is a massive waste of compute and storage.

The Solution

Push aggregation as close to the source as possible. Use Flink’s windowing operators to pre-aggregate data before it hits storage or downstream consumers. This reduces data volume by 100–1000x while providing the exact metrics consumers need

Implementation Details

Tumbling windows: Fixed 1-minute buckets for real-time metrics (COUNT, SUM, AVG per dimension key)

Incremental aggregation: Use ReduceFunction instead of ProcessWindowFunction to minimize state — each window holds one accumulator, not all events

Multi-level aggregation: Aggregate at source (1-min), then roll up to 5-min, 1-hour, and 1-day granularities downstream

Late data handling: Allow 30-second lateness with a side output for late events. Recompute affected windows on arrival

Results

A clickstream pipeline processing 10M events/min reduced to 10K aggregated records/min — a 1000x reduction in downstream data volume. This cut Flink executor count from 10 to 2, reduced state size by 95%, and made dashboard queries 50x faster.

Strategy 4: Data validations on the Producer Side

The Problem

When data producers (applications, services, or upstream systems) send raw data to the central data platform, errors, inconsistencies, and schema violations often slip through. This results in downstream consumers (dashboards, analytics, ML models) spending significant resources on cleaning, validating, and correcting data. Multiple teams may duplicate validation logic, leading to wasted effort and inconsistent data quality.

The Solution

Shift data validation upstream to the producer side. Enforce schema checks, business rules, and quality constraints before data enters the central data lake or warehouse. This ensures only high-quality, consistent data is ingested, reducing downstream complexity and improving trust in shared datasets.

Implementation Details

  • Producer Validation Layer: Integrate validation logic directly into producer applications or ETL pipelines. Use schema enforcement (e.g., Avro, Protobuf), data quality checks (nulls, ranges, referential integrity), and business rule validation.
  • Validation Feedback Loop: If data fails validation, provide immediate feedback to producers for correction, preventing bad data from entering the system.
  • Centralized Validation Registry: Maintain a registry of validation rules and schemas, versioned and accessible to all producers, ensuring consistency across teams.
  • Monitoring & Alerting: Track validation failures and alert producers and data engineering teams for rapid resolution.

Results

By validating data at the source, downstream consumers receive clean, reliable datasets, eliminating redundant validation steps. Data quality issues are caught early, reducing operational overhead and improving confidence in analytics. Adding new consumers is simplified, as they can trust the integrity of ingested data without custom validation logic.

Strategy 5: Medallion Architecture for Multi-Consumer Reports

The Problem

When multiple teams or dashboards consume the same data, a common anti-pattern emerges: each consumer runs its own aggregation pipeline independently. Five dashboards viewing sales data means five separate Flink jobs doing essentially the same computation. This is both expensive and operationally fragile.

The Solution

Implement a medallion architecture (Bronze → Silver → Gold) where data is progressively refined through layers. The Gold layer contains pre-computed, business-level aggregates that serve all consumers. Compute once, serve many.

Implementation Details

Bronze layer: Raw event ingestion into a data lake (S3/Delta Lake). Append-only, full fidelity, partitioned by event time

Silver layer: Cleaned, deduplicated, enriched data with enforced schemas. Join with dimension tables (users, products, regions)

Gold layer: Pre-computed aggregates optimized for specific business questions. Materialized views refreshed on a schedule or trigger

  • Serving layer: Gold data served via Redis/DynamoDB for sub-ms latency, or directly queried via Presto/Trino for ad-hoc analysis

Results

Consolidating 5 independent aggregation pipelines into a single medallion architecture reduced total compute by 60–80%. Query latency dropped from seconds to milliseconds for dashboard consumers, and adding a new consumer became a configuration change instead of a new pipeline.

Where to Start

Start with the highest-impact, lowest-risk change for your system:

If storage is your top cost: Start with Kafka retention reduction + S3 sink

If compute is over-provisioned: Start with lag-based auto-scaling

If you have high event volume with low query diversity: Start with on-the-fly aggregation

If multiple teams consume the same data: Start with medallion architecture

Key Takeaways

• Real-time doesn’t mean expensive — most cost comes from waste, not from the streaming itself

• Separate hot and cold paths — don’t pay premium prices for data that’s rarely accessed

• Match capacity to demand — auto-scale based on actual backlog, not worst-case projections

• Reduce data early — every byte you don’t process downstream is pure savings

• Compute once, serve many — shared layers beat independent pipelines every time

The best optimization is the one you implement first. Pick one strategy, measure the impact, and iterate.


메타데이터
post_id
27fecae6d267
slug
cost-optimization-in-real-time-streaming-systems-27fecae6d267
url
https://medium.com/@jatinagrawal_93108/cost-optimization-in-real-time-streaming-systems-27fecae6d267
canonical_url
https://medium.com/@jatinagrawal_93108/cost-optimization-in-real-time-streaming-systems-27fecae6d267
author_url
https://medium.com/@jatinagrawal_93108
status
ok
fetched_at
2026-06-09 15:37:30