14 Edge Processing: Stream Window Contracts
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.
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
- Edge Processing Patterns for the filter, aggregate, infer, and store-forward choices that consume these windows.
- Edge Acquisition Timing and Buffer Contracts for source timestamps, clocks, and replay metadata upstream of windows.
- Edge Acquisition Sampling and Compression for reducing raw streams before or during local aggregation.
- Edge Patterns Placement and Cost Contracts for deciding where windowed processing should run.
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
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
14.8 Concept Relationships
Builds on:
- Edge Compute Patterns Overview - Foundation concepts
- Edge IoT Reference Model - Level 3 processing context
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
Pattern Implementation:
- Edge Patterns Practical Guide - Interactive tools and worked examples
- Edge Cyber-Foraging - Opportunistic compute offloading
Architecture Context:
- Edge, Fog, and Cloud Overview - Three-tier architecture
- Multi-Sensor Data Fusion - Combining patterns for sensor fusion
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.
14.11 What’s Next
| Next Topic | Description |
|---|---|
| Edge Stream Window Contracts | Window semantics, state budgets, and replay metadata for edge processing outputs |
| Cyber-Foraging and Caching | Opportunistic compute offloading and caching strategies |
| Edge Patterns Practical Guide | Interactive 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.
