Chapters

14 Edge Processing: Stream Window Contracts

analytics-ml
edge
patterns
processing
stream

14.1 Start With the Decision

Two edge services can report the same average from different time windows. A stream contract must name the window, clock, and late-data rule.

14.2 Route Overview

This is part 3 of 3. Review Edge Processing: Aggregation Decisions for the preceding evidence.

14.3 Learning Objectives

  • Define event-time and processing-time window contracts.
  • Verify edge summaries against late and missing samples.

14.4 Chapter Roadmap

  • Edge Stream Window Contracts
  • Summary
  • Key Takeaway
  • Concept Check
  • Quick Knowledge Check
  • Concept Relationships
  • How This Concept Connects
  • See Also
  • Related Resources
  • Try It Yourself
  • Four Edge Patterns Exercise
  • Quiz: Edge Processing Patterns
  • What’s Next

14.5 Edge Stream Window Contracts

14.5.1 Start With the Story

Picture an IoT team using the ideas in Edge Stream Window Contracts during a live operations review. A device has produced messy evidence, an analytic step is about to change an alert or control decision, and someone has to explain why the result should be trusted.

Read this page as that path from sensor evidence to accountable action. Start with what the system observes, keep the model or data treatment visible, and finish with the check that would convince an operator, maintainer, or auditor to act.

14.5.2 Learning Objectives

After this page, you should be able to:

  • Explain why unbounded IoT streams need explicit window rules before they can produce reliable metrics.
  • Choose tumbling, sliding, or session windows based on the operating question being answered.
  • Estimate how window choice changes edge memory, CPU, and battery load.
  • Specify late-event, timestamp, reboot, and replay metadata so emitted metrics remain auditable.

14.5.3 Why Windows Follow Edge Patterns

Edge Processing Patterns compares filter, aggregate, infer, and store-forward designs. Those patterns decide where and why work happens. This page narrows in on the stream contract that makes edge outputs interpretable: how a never-ending event flow is carved into finite windows, how much state each window keeps, and what metadata travels with each emitted result.

Use it when a gateway emits local counts, averages, trends, session summaries, exception rates, or model features that downstream systems will compare over time.

14.5.4 Windowed Stream Computing

Batch analytics runs over a finite dataset that sits still. Edge and streaming analytics face an endless flow of events with no natural “end” at which to compute an average or a count. The answer is the window: you carve the infinite stream into finite chunks and compute over each chunk.

How you carve it determines the meaning of the result. The three fundamental window types — tumbling, sliding, and session — answer different questions, and choosing the wrong one gives numbers that are technically correct but answer a question you did not ask.

Intuition: a window is a stopwatch strategy. Reset it every minute (tumbling), keep a rolling last-five-minutes view (sliding), or start it when activity begins and stop it after a quiet gap (session). Same stream, three very different reports.

Worked example: a cold-chain gateway receives one temperature event every second from each trailer. If operations wants a compliance report, a tumbling one-hour window can produce one non-overlapping min/max/average for each trailer. If dispatch wants early warning that a trailer is warming, a sliding ten-minute window updated every minute gives a fresher trend. If the trailer sleeps between trips, a session window can group each active delivery run and close after a quiet gap. The raw stream is identical in all three cases; the window changes the business question answered by the same events.

This is why the window definition belongs in the data contract. A downstream dashboard that says “average temperature” is ambiguous unless it also says whether the value came from a clock-aligned bucket, a rolling lookback, or one activity session. The wrong window can make alerts late, double-count events, or merge two separate operating periods.

Unbounded event stream

Choose window rule

Tumbling window

Sliding window

Session window

Aggregate and emit result

14.5.5 Overview Knowledge Check

14.5.6 Tumbling, Sliding, Session

Tumbling: fixed size, NON-overlapping, contiguous.
          Every event lands in exactly one window.  e.g. "count per 1 min"
Sliding:  fixed size, OVERLAPPING (slide < size).
          Events fall in several windows.  e.g. "5-min avg, updated every 1 min"
Session:  DYNAMIC length, defined by activity; a window closes after a
          gap (timeout) of inactivity.  e.g. "one user visit"

Worked example: same stream, three answers

Temperature events arriving continuously:

  Tumbling(1 min): one average per clock minute, no overlap
                   -> clean, non-double-counted per-minute stats
  Sliding(5 min, 1 min): a smoothed 5-minute average refreshed
                   each minute -> good for trends/alerts, but each
                   event is counted in up to 5 windows
  Session(gap=30 s): groups bursts of readings from one device
                   wake-cycle; closes 30 s after the last reading
                   -> length varies with the device's activity

Pick by the question: “how many per minute?” is tumbling; “what is the current smoothed rate?” is sliding; “what happened during one burst of activity?” is session. Using a sliding window where you meant tumbling silently double-counts events.

Worked example continuation: suppose the stream has events at 00:05, 00:15, 00:55, 01:05, and 01:40. Tumbling one-minute windows count three events in minute 00 and two in minute 01. A two-minute sliding window updated each minute reports all five events at 02:00 because the lookback overlaps both minutes. A session window with a 30-second gap splits the first three events into one burst and the last two into another. None of those answers is wrong; each reflects a different operating question and a different amount of state held by the gateway.

In a review, write the window rule beside the metric. For example, “door opens per minute” should say tumbling 60 seconds, aligned to the gateway clock, keyed by door id. “Recent vibration trend” should say sliding 5 minutes with a 30-second slide. “Pump run” should say session gap 2 minutes, keyed by pump id. Those labels prevent a maintainer from comparing incompatible numbers.

14.5.7 Practitioner Knowledge Check

14.5.8 Window State Has Cost

At the edge, where memory is scarce, the practicalities of maintaining windows matter as much as their semantics.

Sliding windows cost more

Because events belong to many overlapping windows, sliding windows keep more in-flight state and recompute more often than tumbling ones. On a constrained gateway, that memory and CPU cost is real.

Incremental aggregation

Sums, counts, and averages can be updated incrementally as events arrive and leave a window, avoiding a full recompute. Percentiles and distinct-counts are harder and often use approximate sketches.

Session gaps need a timeout

A session window cannot close until a gap of inactivity passes, so it holds state until the timeout fires. Choosing the gap is a trade-off between splitting one activity and merging two.

Bounded state or it grows

Every open window is memory. Streaming systems must expire and emit windows promptly; a stuck or ever-growing window is a classic cause of edge memory exhaustion.

So window choice is both a semantic and a resource decision. Tumbling is cheapest and cleanest for periodic aggregates; sliding gives smooth, responsive trends at higher cost; session captures natural bursts of activity but must hold state until a quiet gap. On the edge, the right window is the one that answers the question with the least state held open.

Worked example: a vibration gateway with 128 MB of RAM can keep a one-minute tumbling count as a few counters, but a ten-minute sliding window updated every second may need many overlapping buckets or a ring buffer of recent samples. If the gateway also tracks per-device sessions, each active device keeps its own timeout and partial aggregate. The engineering decision is not just accuracy; it is whether the available memory, CPU, and battery budget can support the state implied by the chosen window.

Make the state budget explicit before implementation. For a 100 Hz vibration stream, a tumbling one-minute average only needs a running sum, a count, and perhaps a min/max pair for the current minute. A sliding ten-minute window with a one-second slide covers 600 seconds of recent data, so a naive design can drift toward 60,000 retained samples per sensor. A practical edge design stores smaller per-second buckets in a ring buffer and subtracts expired buckets as the window advances, but that still multiplies memory by the number of sensors and keyed streams.

The same logic applies to correctness. Late events need a cutoff rule, clock drift needs a timestamp policy, and reboot recovery needs a decision about whether partial windows are replayed, discarded, or emitted with a quality flag. Those operational details are easy to hide in code, but they decide whether edge results are repeatable during outages. A good review therefore checks three items: the window semantics match the question, the state has a bounded maximum, and the emitted result records the window start, window end, key, and any lateness or recovery caveat.

14.5.9 Under-the-Hood Knowledge Check

14.5.10 Release Checklist

Before shipping an edge stream window contract, verify these records:

  • Every emitted metric names its window type, window size, slide interval or session gap, key, and clock alignment rule.
  • State has a bounded maximum for each keyed stream, including worst-case device counts and reconnect bursts.
  • Late, out-of-order, duplicate, and replayed events have explicit accept, drop, update, or quality-flag policies.
  • Reboot recovery says whether partial windows are discarded, restored from durable state, or emitted with caveats.
  • Downstream dashboards can see window start, window end, source clock, lateness status, and any aggregation or recovery caveat.

14.5.11 See Also

14.5.12 Next

Return to Edge Processing Patterns, then continue to Cyber-Foraging and Caching for opportunistic offload and cache decisions.

14.6 Summary

  • Four edge processing patterns address different IoT requirements: Filter (threshold alerts), Aggregate (statistical summaries), Infer (ML-based detection), and Store-Forward (intermittent connectivity)
  • Pattern selection depends on primary priority: bandwidth reduction, real-time response, reliability, or privacy
  • Edge ML trade-offs balance latency (10-50 ms edge vs 200-500 ms cloud) against accuracy (85-92% edge vs 95-99% cloud)
  • Batch vs streaming trade-offs balance power efficiency against detection latency
  • Cost analysis shows edge saves money only at scale (>10,000 sensors) or when latency/privacy requirements justify hardware investment
  • Hybrid architectures typically provide the best balance: edge for time-critical decisions, cloud for complex analytics
Key Takeaway

The four edge processing patterns — Filter, Aggregate, Infer, and Store-Forward — each solve a different problem. Filter reduces bandwidth by sending only exceptions. Aggregate computes local statistics for trend analysis. Infer runs ML models for intelligent detection. Store-Forward handles intermittent connectivity. Hybrid architectures combining edge speed with cloud analytics consistently outperform either approach alone, but edge only saves money at scale (>10,000 sensors) or when latency and privacy requirements justify hardware investment.

14.7 Concept Check

Quick Knowledge Check

Q: How do you choose between Filter, Aggregate, Infer, and Store-Forward patterns?

Filter when only exceptions matter (threshold violations). Aggregate for trend analysis (hourly statistics). Infer when ML-based detection adds value over simple rules. Store-Forward for intermittent connectivity (buffer during outages).

Q: When does edge computing NOT save money?

Edge computing costs more than cloud when: (1) data volumes are low (<1 GB/month), (2) deployment scale is small (<1,000 sensors), (3) bandwidth is free or cheap, or (4) data reduction factor is under 10x. The Danfoss supermarket example saves money at 40,000 stores, but a single store would lose money on the edge investment.

14.8 Concept Relationships

Builds on:

Four Patterns in Detail:

  • Filter Pattern - 99%+ bandwidth reduction by sending only threshold violations
  • Aggregate Pattern - Statistical summaries (min/max/avg) for trend analysis
  • Infer Pattern - ML models run locally, send anomaly alerts only
  • Store-Forward Pattern - Buffers data during outages, syncs when reconnected

Real-World Examples:

  • Danfoss Supermarkets - 95.5% data reduction across 40,000 stores using three different patterns
  • Agricultural Soil Monitoring - Cost analysis shows cloud-only cheaper until very large scale

14.9 See Also

Related Resources

Pattern Implementation:

Architecture Context:

Case Studies:

  • Danfoss Case Study (in chapter) - Three patterns for three sensor types
  • Agricultural Cost Analysis (in chapter) - When edge investment does not pay off

14.10 Try It Yourself

Scenario: Industrial motor monitoring with vibration sensors at 1 kHz sampling.

Pattern 1: Filter

def filter_pattern(vibration_g, threshold=5.0):
    """Send only threshold violations"""
    if vibration_g > threshold:
        return {"alert": True, "value": vibration_g, "pattern": "filter"}
    return None  # Don't transmit normal readings

# Test: 8 samples, 3 exceed threshold (5.0)
readings = [2.1, 3.5, 2.8, 6.2, 4.1, 7.8, 3.2, 5.9]
alerts = [filter_pattern(r) for r in readings if filter_pattern(r)]
print(f"Filter: {len(readings)} readings -> {len(alerts)} alerts")

Pattern 2: Aggregate

import statistics

def aggregate_pattern(readings_1sec):
    """Compute 1-second statistics from 1000 Hz samples"""
    return {
        "min": min(readings_1sec),
        "max": max(readings_1sec),
        "avg": statistics.mean(readings_1sec),
        "stddev": statistics.stdev(readings_1sec),
        "pattern": "aggregate"
    }

# Test: 1000 samples -> 4 values = 250x reduction
samples_1khz = [2.1 + (i * 0.01) for i in range(1000)]
summary = aggregate_pattern(samples_1khz)
print(f"Aggregate: 1000 samples -> 4 values = 250x reduction")

Pattern 3: Infer (simplified)

def infer_pattern(vibration_rms, threshold_trained=4.5):
    """Simplified ML inference: anomaly score based on trained threshold"""
    anomaly_score = vibration_rms / threshold_trained
    if anomaly_score > 1.2:  # 20% above normal
        return {"anomaly": True, "score": round(anomaly_score, 2),
                "pattern": "infer"}
    return None  # Normal operation

# Test: 5.8 g RMS is above trained baseline of 4.5 g
result = infer_pattern(5.8)
print(f"Infer: {result}")

Pattern 4: Store-Forward

class StoreForwardBuffer:
    def __init__(self, max_size_mb=100):
        self.buffer = []
        self.max_size = max_size_mb * 1024 * 1024

    def store(self, reading):
        self.buffer.append(reading)
        if len(self.buffer) > 1000:  # Simplified FIFO
            self.buffer.pop(0)

    def forward(self, network_available):
        if network_available and self.buffer:
            print(f"Forwarding {len(self.buffer)} buffered readings")
            self.buffer.clear()
            return True
        return False

# Test: buffer during outage, then forward
buffer = StoreForwardBuffer()
for i in range(50):
    buffer.store({"reading": i})

buffer.forward(network_available=False)  # No sync
print(f"Buffer size: {len(buffer.buffer)} readings")
buffer.forward(network_available=True)   # Sync successful
print(f"After sync: {len(buffer.buffer)} readings")

What to Observe:

  • Filter drastically reduces transmissions (99%+) but loses trend information
  • Aggregate preserves statistics while achieving 250x reduction
  • Infer requires trained model but enables intelligent detection
  • Store-Forward ensures no data loss during outages

Extension Challenge: Combine patterns: Filter + Aggregate. Send hourly aggregates for normal operation, immediate alerts for threshold violations.

Quiz: Edge Processing Patterns

14.11 What’s Next

Next TopicDescription
Edge Stream Window ContractsWindow semantics, state budgets, and replay metadata for edge processing outputs
Cyber-Foraging and CachingOpportunistic compute offloading and caching strategies
Edge Patterns Practical GuideInteractive tools, worked examples, and common pitfalls

14.12 Continue Your Route

This final part closes the route from Edge Stream Window Contracts through What’s Next. Return to Edge Processing: Aggregation Decisions or continue from the analytics-ml module index.