Azure Stream Analytics: Making Sense of Data While It Is Still Flowing
A complete, plain-English guide to real-time event processing: inputs, queries, time windows, late data, outputs, streaming units, fault tolerance, monitoring and the design mistakes that quietly corrupt results.
Think of a river and a lake. A lake holds water that has settled; you can measure it, map it and study it at your leisure. A river never stops. If you want to know how fast it flows right now, or whether a flood is coming, you cannot wait for the water to settle. You must stand at the bank and measure as the water passes. Most business data used to be treated like a lake: collected for a day, then analyzed. But more and more data arrives like a river, from sensors, phones, payment systems and websites, and the value of an answer drops with every minute that passes.
Azure Stream Analytics is the service that stands at the riverbank. It reads a never-ending flow of events, applies rules and calculations in real time, and sends the results onward within moments. In this guide you will learn what it is, how it works inside, how it understands time, how its windows and joins behave, how to scale it, secure it, watch it and pay for it, and which mistakes to avoid.
1What Azure Stream Analytics Is and Why It Exists
Begin with the problem of data that never stops arriving, then see how a streaming service answers it.
The problem
A factory has thousands of sensors. Each one sends a temperature reading every second. A bank processes thousands of card payments a minute. A delivery company receives a location from every truck every few seconds. Each single reading is tiny and nearly useless. The value comes from patterns across many readings: a machine that is slowly overheating, a card used in two countries within ten minutes, a truck that has stopped for too long. Finding these patterns after a nightly batch job is often too late. The machine has already broken. The card has already been drained.
What the service is
Azure Stream Analytics is a fully managed real-time analytics service. “Fully managed” means Microsoft runs the machines, patches them and keeps them alive. You describe what you want in a query written in a language that looks like the database language many people already know, and you tell the service where events come from and where results should go. The service then runs your query continuously, day and night, over the flowing events.
A toll booth on a motorway counts cars as they pass. It does not wait until evening to count the whole day. A lifeguard watches swimmers all the time and reacts the moment someone struggles. Stream Analytics is the booth attendant and the lifeguard combined: always watching, always counting, always ready to react.
What you gain
Answers in seconds
Results appear moments after events happen, not hours later.
Familiar query style
You describe the result you want in a language close to standard database queries, not in low-level programs.
Built-in windows
Counting events per minute, or per hour, or per customer session, is a built-in idea rather than custom work.
Plugs into Azure
It reads from event hubs, IoT hubs and storage, and writes to databases, storage, dashboards and more.
Recovers by itself
The service saves its progress and resumes after failures without losing events.
Grows with the flow
You assign more compute units and split the work in parallel as traffic grows.
2Background: From Batch to Streaming
To see why streaming services exist, look at how data processing grew up.
The batch era
For decades, data was processed in batches. During the day, systems wrote records into files or databases. At night, a big job read everything collected, calculated totals and wrote reports. Managers read the reports the next morning. This worked well when business moved slowly and data volumes were small. A batch job is simple to understand: it has a start, an end and a clear input.
The limits of waiting
As systems grew, three things changed. Volumes became huge, so night jobs began to take longer than the night. Business expectations changed, so a fraud alert tomorrow was worth far less than one right now. And machines began to talk to each other, so a thermostat or a payment terminal needed an answer in a second, not a day.
Micro-batches and true streams
A first step was running batches more often, every hour, then every minute. This is called micro-batching. It reduces delay but adds complexity and cannot easily reach one-second answers. True stream processing treats data as an endless sequence of events and processes each one, or small groups, the moment it arrives, keeping running state in memory.
Streaming in the cloud
Early stream engines needed experts to build and run clusters. Cloud services took that burden away. Azure Stream Analytics grew from this idea: give people a way to write a few lines of query and have a managed engine run it at scale. It sits beside other Azure options for bigger or more custom needs, which a later chapter compares.
| Style | Typical delay | Good for | Weakness |
|---|---|---|---|
| Nightly batch | Hours to a day | Deep history, heavy reports | Too slow for alerts |
| Frequent micro-batch | Minutes | Near-live dashboards | Overhead per batch, still not instant |
| True streaming | Sub-second to seconds | Alerts, live metrics, control loops | Harder to reason about time and state |
Events versus records
An event is a small fact that something happened at a moment in time: “sensor 42 read 71 degrees at 10:00:03.” Unlike a row in a table that you update, an event is never changed. Events pile up in order, like entries in a diary. Streaming systems read the diary as it is written.
Most real systems use both. Streaming gives the quick answer; batch gives the deep, corrected answer later. The two work well when they share the same stored events.
3Core Concepts: The Vocabulary of Stream Analytics
Each term below says what it is, why it exists, a picture from daily life and an example.
Job
The unit you create and run. It holds inputs, a query and outputs. Analogy: a worker on a conveyor belt with one set of instructions.
Input
Where events come from, such as an event hub, an IoT hub or files in storage. Analogy: the start of the conveyor belt.
Output
Where results go, such as a database, a storage account, a message stream or a live dashboard. Analogy: the boxes at the end of the belt.
Query
The instructions that read inputs, calculate and write outputs. Analogy: the worker’s checklist.
Stream input
An endless flow of events. Analogy: a river.
Reference input
A slow-changing table used to add context, such as a list of device names. Analogy: a phone book beside the worker.
Event time
The moment something actually happened, recorded in the event. Analogy: the date written on a postcard.
Arrival time
The moment the service received the event. Analogy: the postmark when the postcard reaches the sorting office.
Window
A slice of time over which events are grouped for a calculation. Analogy: counting cars every ten minutes.
Partition
A separate lane of the stream so many workers can read at once. Analogy: several checkout lanes.
Streaming unit
The measure of compute and memory given to a job. Analogy: the number of workers on the belt.
Watermark
The engine’s marker saying “I believe I have seen all events up to this time.” Analogy: a teacher saying “no more homework before this date will be accepted.”
How the words fit together
Read it as a pipeline: a job reads one or more inputs, optionally enriches them with reference inputs, runs the query over windows measured in event time, and writes to one or more outputs. The job’s size is its streaming units. When the input is split into partitions, the job can work on many lanes in parallel.
Always keep in mind that there are two clocks: the time an event happened and the time it arrived. Much of the difficulty in streaming comes from the gap between them.
4Architecture and Components
Here is where the service sits in a typical real-time pipeline.
flowchart LR
subgraph SRC["Event sources"]
D1["Devices and sensors"]
D2["Applications"]
D3["Web and mobile clients"]
end
D1 --> IOT["IoT Hub"]
D2 --> EH["Event Hubs"]
D3 --> EH
IOT --> SA["Stream Analytics job"]
EH --> SA
REF["Reference data in storage"] --> SA
SA --> DB["Database"]
SA --> LAKE["Data lake storage"]
SA --> BUS["Service Bus or Event Hubs"]
SA --> DASH["Live dashboard"]
BUS --> FUNC["Alerting function"]
Event sources
Events begin on devices, applications and websites. They are sent into an ingestion service that holds them safely for a short time, in order, until a reader takes them. This holding area, such as an event hub or an IoT hub, is a buffer between the busy world and the job. If the job stops for a while, events wait in the buffer and are read when it returns.
The job
The job is the engine. It reads events from the buffer, runs the query, and keeps in memory the running state that windows and joins need, such as “the count so far in this minute.” It also writes progress markers so it can recover.
Outputs
Results are written to one or more destinations. A database may keep the latest numbers for an application. A data lake may hold everything for later analysis. A message service may carry alerts to other systems. A dashboard service may show live charts.
Supporting pieces
| Component | Role |
|---|---|
| Event Hubs | High-volume ingestion buffer for application and platform events |
| IoT Hub | Ingestion for device events with device identity and management |
| Blob or data lake storage | Holds reference data, archived outputs and sometimes file-based inputs |
| Azure Monitor | Metrics, logs and alerts for the job |
| Key Vault and managed identity | Safe handling of credentials and access |
| Virtual network integration | Lets the job reach private resources |
| Cluster (dedicated) | An optional dedicated pool of compute for many jobs, with private network features |
5Inputs: Stream and Reference
A job needs something to read. There are two kinds of input with very different behavior.
Stream inputs
A stream input is a flow of new events with no end. The most common sources are event hubs, IoT hubs and files appearing in storage. Each event carries data fields and a time. The job reads the stream continuously and never expects it to finish.
Event serialization
Events arrive in a format such as JSON, CSV or a compact binary format. You tell the job which format and character encoding to expect. If a producer sends a different shape than the job expects, you get input errors. Keep formats stable and version them carefully when they change.
Consumer groups
An event hub can be read by several independent readers, each using its own consumer group. Give each job its own group so jobs do not steal events from one another or from other applications. Sharing a group is a common cause of strange missing events.
Reference inputs
A reference input is a table that changes slowly or not at all. It is loaded into memory and used to add meaning to events. Example: an event has a device number, and the reference table maps device numbers to the building and floor where each device lives. The job joins the two so output shows the building and floor. Reference data usually comes from files in storage or from a database, and can be refreshed on a schedule, so the job sees new values over time.
A cashier scans items as they arrive on the belt; that is the stream. The price list pinned beside the register is the reference data. The cashier looks up each scanned code in the price list to know what to charge, and the manager updates the price list occasionally.
Early arrival and event ordering
Streams from different partitions are not guaranteed to arrive in perfect time order. A device in a poor network area may deliver its events late, in bursts. The job has settings that decide how much disorder and lateness it will tolerate, explained in the chapter on time.
Choosing the right source
| Source | Best for | Notes |
|---|---|---|
| Event Hubs | Large streams from applications, logs and telemetry | Partitioned; supports many readers through consumer groups |
| IoT Hub | Device telemetry with device identity | Built on the same engine as event hubs, with device management features |
| Blob or data lake files | Files dropped as batches or replayed history | Slower than a true stream, useful for testing and backfill |
| Reference blob | Slow-changing lookup lists | Refresh by date pattern |
| Reference database | Lookup data owned by an application | Keep size modest and refresh on a schedule |
6The Query Language Explained in Plain Words
The query is the heart of a job. You do not need to memorize code to understand how it thinks.
A language that looks familiar
The language is a dialect of the one used to ask questions of databases. You pick fields from an input, filter which events you care about, group them, and name an output. The difference is that, in a database, a question runs once over stored rows and finishes. Here, the question runs forever over events that keep arriving, and each answer is emitted as time passes.
The usual building blocks
Select
Choose which fields leave the query, and calculate new fields from old ones, such as converting units.
Where
Keep only events that meet a condition, such as temperature above a limit.
Group by with a window
Collect events by key and by time slice, then calculate counts, averages, minimums, maximums or sums.
Join
Combine two streams, or a stream with reference data, based on matching fields and, for streams, a time distance.
Analytic functions
Look back at a previous event for the same device, or find the first or last event in a period.
With steps
Break a long query into named steps that feed each other, like paragraphs in an essay.
Several outputs from one job
A single job can contain several queries. One may send raw filtered events to a data lake, another may send per-minute averages to a database, and a third may send alert events to a message service. All share the same input reading, which is cheaper than running separate jobs.
Built-in functions
The language has functions for text, dates, numbers, arrays and records, for geographic checks such as “is this point inside this area,” and for simple statistical and machine learning helpers, like spotting unusual values. You can also bring your own functions written in common languages for special logic, though keeping queries simple is wise.
Thinking in streams
When you write a query, ask three questions. What slice of time does each answer cover? What groups am I counting separately? When should an answer be released? Many beginners forget the first question and ask, for instance, for an average without saying over what time. The service will reject such a question for a stream, because an endless stream has no end to average over.
Any calculation that combines many events needs a window. A query that groups without a window cannot finish, because the stream never ends.
7Internal Working: How an Event Travels Through a Job
Follow a single event from its birth to a result in a database.
sequenceDiagram participant DEV as Device participant EH as Event hub participant JOB as Stream Analytics job participant ST as In-memory state participant OUT as Database output DEV->>EH: Send reading with event time EH->>JOB: Deliver from a partition JOB->>JOB: Parse and check format JOB->>JOB: Apply filter JOB->>ST: Add to window state JOB->>JOB: Watermark passes end of window JOB->>ST: Compute window result ST-->>JOB: Result JOB->>OUT: Write result in a batch JOB->>JOB: Save checkpoint
Step by step
The event is created and sent
A device or application builds an event with its fields and, ideally, its own time stamp, and sends it to the ingestion service.
The buffer stores it
The ingestion service writes it to a partition, in order, and keeps it for the retention period.
The job reads and parses
The job reads a batch of events from each partition it handles and decodes them. Bad events may be dropped or counted as input errors.
The query is applied
Filters remove unwanted events. Joins add context from reference data. Windowed groups update their running totals in memory.
Time moves forward
As event times advance, the engine decides that windows are complete and releases their results.
Results are written
The job writes results to outputs in small batches for efficiency, with retry if the output is busy.
Progress is saved
The job records a checkpoint of how far it has read and the state it holds, so it can resume after a failure.
Why batches inside a stream
Although the idea is event-by-event, the engine works on small groups of events for efficiency, much as a bus carries many passengers at once. These groups are small, so delay stays in the range of seconds.
Backpressure
If an output is slow, results pile up inside the job. If they pile up enough, the job slows its reading, and then events accumulate in the buffer instead. This slowing is called backpressure. It protects the job from crashing, but it shows up as growing delay. The monitoring chapter explains how to see it.
Memory is the real limit
Windows and joins keep state in memory. Counting events per device per minute for a million devices keeps a million small counters. State size grows with the number of groups and with the length of windows. This is why streaming units, which include memory, matter so much.
8Time: Event Time, Arrival Time, Late and Out-of-Order Events
Time is the hardest idea in streaming, and the part that most often corrupts results. Take this chapter slowly.
Two timestamps
Every event can be placed on two clocks. Event time is when the thing really happened, written by the device or application. Arrival time is when the ingestion service received it. If a phone is offline in a tunnel for ten minutes and then sends a burst of readings, their event times are spread across ten minutes, but their arrival times are all now. If you count by arrival time, you would wrongly say that traffic jumped just now. Counting by event time tells the true story.
Choosing the clock
The job can use either clock for windows. Using arrival time is simple and never has late data, but it reflects delivery delays. Using event time gives correct business answers, but the job must decide how long to wait for stragglers. A field in the query points to the time stamp inside the event, and the job uses it for all time decisions.
A teacher marks homework by the date written on the page, but also notes the day it was handed in. A student who handed in Monday’s work on Wednesday still did the work on Monday. Counting by hand-in day would make Wednesday look unusually busy.
Out-of-order and late events
Two settings handle disorder. The out-of-order tolerance says how far an event may be out of sequence within the stream and still be re-sorted into place. The late arrival tolerance says how late, compared with the newest time the job has seen, an event may arrive and still be counted in its proper window. Events beyond the limit are handled by a chosen policy: either they are dropped, or their event time is adjusted to the nearest acceptable time so they are not lost.
flowchart TD
E["Event arrives with event time T"] --> C1{"Within out-of-order tolerance?"}
C1 -->|"Yes"| P["Sorted into place and processed"]
C1 -->|"No"| C2{"Within late arrival tolerance?"}
C2 -->|"Yes"| P
C2 -->|"No"| POL{"Policy"}
POL -->|"Adjust"| ADJ["Event time moved to nearest allowed time"]
POL -->|"Drop"| DROP["Event discarded and counted"]
ADJ --> P
The cost of waiting
A bigger tolerance gives more accurate results but delays them. If the late arrival tolerance is five minutes, a one-minute window is released only after the job believes no more events with that window’s times will come, so results trail real time by about that tolerance. Short tolerances give fast results but risk missing stragglers. The right value depends on your devices and networks, so measure real delays before choosing.
Idle sources
If one partition goes quiet, the job cannot be sure no events are coming, and may hold back results. A setting for the maximum wait on idle partitions tells the job when to move on. This prevents one silent device group from stalling all output.
Clock quality
Device clocks drift and can be set wrongly. An event stamped far in the future can push the job’s sense of time ahead and cause genuine events to be treated as late. Validate time stamps at ingestion if possible, and set limits in the job for how far ahead a stamp may be.
One device with a date years in the future can make the whole job think time has jumped forward. Guard against this by checking stamps before or at ingestion.
9Windows: Slicing Endless Time
A window turns an endless stream into pieces you can calculate on. The service offers five types.
| Window | Shape | Output when | Example question |
|---|---|---|---|
| Tumbling | Fixed size, no overlap, no gaps | At the end of each slice | How many orders per minute? |
| Hopping | Fixed size, overlapping, moves by a hop | At each hop | Average temperature over the last ten minutes, updated every minute |
| Sliding | Fixed size, produces output only when an event enters or leaves | When content changes | Alert when more than three failed logins occur within ten seconds |
| Session | Grows while events keep arriving; closes after a quiet gap | When the gap passes | How long was each user visit, and how many clicks? |
| Snapshot | Groups events with exactly the same time stamp | For each distinct time | How many devices reported at this exact moment? |
Tumbling windows
Picture a calendar with one box per day. Every event falls in exactly one box. Tumbling windows are the simplest and cheapest, and suit regular reports such as totals per minute.
Hopping windows
These overlap, like a moving average on a chart. A ten-minute window that hops every minute means each event counts in ten different windows. They give smoother numbers but multiply state and output. A tumbling window is a hopping window whose hop equals its size.
Sliding windows
A sliding window looks back a fixed time from every event and reports only when the content changes. It is the right tool for threshold alerts that must react at once, such as too many failures in a short span. It can produce many outputs on busy streams.
Session windows
Sessions have no fixed size. Each starts at an event and extends while more events from the same key arrive within a timeout. When the gap exceeds the timeout, the session ends. They fit user behavior and equipment cycles, such as one machine run.
flowchart LR
subgraph TUM["Tumbling: fixed, no overlap"]
T1["0-5 min"] --> T2["5-10 min"] --> T3["10-15 min"]
end
subgraph HOP["Hopping: fixed, overlapping"]
H1["0-10 min"] -.-> H2["5-15 min"] -.-> H3["10-20 min"]
end
subgraph SES["Session: grows until quiet gap"]
S1["Burst of events"] --> S2["Gap longer than timeout ends session"]
end
Choosing a window
Regular reports
Use tumbling windows for totals per fixed period.
Smooth trend lines
Use hopping windows for rolling averages.
Immediate threshold alerts
Use sliding windows when you need to react as soon as a limit is crossed.
User or machine activity bursts
Use session windows when the length of activity is not fixed.
Windows and keys
Windows are almost always combined with a key, such as device or customer. Each key has its own window state. The number of distinct keys therefore drives memory use. A key with millions of unique values and a long window can use large amounts of memory.
10Joins and Reference Data
Real questions often need two sources of information. Joins let a job combine them.
Joining a stream with reference data
This is the easy and cheap kind of join. For each event, the job looks up matching fields in the reference table, such as turning a device number into a location. No time condition is needed, because the reference table is treated as a fixed list at that moment. Most enrichments use this approach.
Joining two streams
Here, the job matches events from two flows, such as a click and a later purchase from the same user. Because both flows are endless, the match needs a time rule: events match only if they happened within a stated time distance of each other, such as within ten minutes. The job must hold events from both streams in memory for that distance, waiting for partners. A longer distance means more memory.
A waiter takes an order slip and later receives a ready-signal from the kitchen. To pair them, the waiter keeps unmatched slips on a spike for a short time. If a signal does not appear in time, the slip is considered stale. The spike is the memory that the job needs to keep.
Kinds of stream join
| Join | Result | Use |
|---|---|---|
| Inner | Only matched pairs | Clicks that led to purchases |
| Left outer | All from the left, matched where possible | All orders, with delivery info where it arrived |
| Time-bounded | Pairs inside a time distance | Required for every stream-to-stream join |
Refreshing reference data
Reference files are loaded when the job starts and then refreshed on a pattern, usually based on the date and time in the file path. A new file appears for the next period, and the job picks it up at the right moment. Time-versioned reference data lets the job apply the correct values for each event time, which matters when prices or rules change at known moments.
Size limits
Reference data is held in memory for each part of the job, so very large tables cause pressure. Keep the table small, with only needed columns. For very large lookups, consider doing the lookup downstream or using a different tool.
Common join mistakes
No time bound
Joins of two streams must state a time distance; leaving it too wide uses large memory.
Mismatched partitions
If the two inputs are partitioned differently, the job cannot run in parallel lanes and may bottleneck.
Stale reference data
If the refresh does not occur, results use old values without any error.
11Outputs and Delivery Guarantees
Getting results to the right place safely is half of the job. Learn what the service promises and what it does not.
Common outputs
| Output type | Typical use | Thing to watch |
|---|---|---|
| SQL database | Latest figures for applications | Write speed and key conflicts |
| Data lake or blob storage | Long-term archive for analysis | File sizes and folder patterns |
| Event Hubs or Service Bus | Passing results to other systems and alerts | Message size and ordering |
| Cosmos database | Fast document store for apps | Partition key choice and throughput |
| Live dashboard service | Real-time charts | Rate and row limits |
| Functions | Custom actions per result | Retry behavior and idempotence |
What delivery guarantees mean
A guarantee describes what happens to each result when things fail. At-least-once means every result is delivered, but after a failure some may be delivered twice. At-most-once means none are duplicated, but some may be lost. Exactly-once means each result takes effect once. The service provides exactly-once processing inside the job for its internal state, and, for some outputs, exactly-once delivery. For others, such as message streams, delivery can be at-least-once, so duplicates are possible after recovery.
A courier who delivers a parcel and the recipient did not sign. After a network error the courier cannot be sure it arrived, so rather than risk a lost parcel the courier delivers again. The recipient may then have two. Making the recipient ignore a duplicate parcel with the same number is what idempotence means.
Designing for duplicates
The safe approach is to make downstream consumers idempotent: applying the same result twice has the same effect as applying it once. For instance, write results with a key made from the window and device, so a repeated result overwrites itself rather than adding another row. Do not assume duplicates never happen.
Batching and output rate
The job groups outputs into batches. Settings control the batch size and, for some outputs, how many writers run in parallel. A slow output, such as a small database, becomes the bottleneck for the whole job. Match the output capacity to expected results, and use partition-aware outputs to spread writes.
Error handling at the output
If an output rejects a row, for example because of a data type problem, the job can either retry forever, which stalls it, or drop the row and continue. The error policy setting decides which. For critical data, choose retry and alert on lag. For metrics that tolerate gaps, drop and log. Whatever you choose, make the choice deliberately.
When you restart a job from an earlier time to fix a bug, outputs will receive old results again. Idempotent writes make replays safe.
12Streaming Units, Partitioning and Scaling
How fast a job runs depends on how much compute you give it and how well the work can be split.
Streaming units
A streaming unit is a bundle of compute and memory. A job with more streaming units can hold more state and process more events. In many configurations units come in steps, and a job whose query can split into parallel lanes can use many units at once. The service shows a utilization figure that tells you how much memory the job uses relative to what it has.
Parallel jobs
The ideal case is called an embarrassingly parallel job. The input is split into partitions, the query keeps work for each partition separate, and the output is also split into matching partitions. Each lane runs alone with no need to talk to other lanes. Such a job scales almost in a straight line: twice the lanes and units handle roughly twice the events.
flowchart LR
subgraph IN["Input partitions"]
P1["Partition 1"]
P2["Partition 2"]
P3["Partition 3"]
P4["Partition 4"]
end
P1 --> W1["Worker lane 1"]
P2 --> W2["Worker lane 2"]
P3 --> W3["Worker lane 3"]
P4 --> W4["Worker lane 4"]
W1 --> O1["Output partition 1"]
W2 --> O2["Output partition 2"]
W3 --> O3["Output partition 3"]
W4 --> O4["Output partition 4"]
What breaks parallelism
Grouping by a key unrelated to the partition key
Events for one group sit in many lanes, so they must be brought together, which needs a shuffle step.
Mismatched partition counts
Input and output with different counts require re-splitting.
Global calculations
A single total across all devices needs everything in one place.
Hot keys
One very busy key makes one lane much slower than others.
You can often repartition explicitly in the query, to spread work and then combine small partial results in a second step. This two-stage approach, computing partial counts in lanes and then summing them, keeps most work parallel.
A worked sizing example
These numbers are illustrative, not official limits. Suppose 20,000 devices each send one event per second, so the job must handle 20,000 events per second. If one lane with a given number of units comfortably handles 2,500 events per second for your query, you need 20,000 divided by 2,500, which is 8 lanes. If the input has 8 partitions and each lane needs, for example, 6 units, you would plan for 8 times 6, or 48 units, then add a margin of about 30 percent for spikes. That gives roughly 62 units, so you might start at 64 and watch utilization. If utilization stays below 40 percent for a week, reduce units; if it often passes 80 percent, add more. Test with your real query, because a complex query changes the numbers greatly.
Autoscale and manual scale
You can change the number of units manually, and some configurations support rules that scale on a schedule or on load. Changing units may need a short restart, so make changes during quiet periods and test them.
The number of partitions on an event hub is hard to change later. Choose it with future growth in mind, since it sets the maximum parallelism of every job reading it.
13Job Lifecycle, Start Modes and Compatibility
A job moves through states, and the way you start it decides what data it processes first.
stateDiagram-v2 [*] --> Created Created --> Starting: start Starting --> Running: resources ready Running --> Degraded: errors or lag Degraded --> Running: recovered Running --> Stopping: stop Degraded --> Failed: unrecoverable error Failed --> Starting: restart Stopping --> Stopped Stopped --> Starting: start Stopped --> [*]: delete
Start modes
| Mode | Meaning | Use |
|---|---|---|
| Now | Begin with events arriving from this moment | New jobs where history does not matter |
| Custom time | Begin from a chosen earlier time and catch up | Replays after fixing a bug or for backfill |
| Last stopped | Continue from where the job stopped | Planned restarts with no gaps |
Catching up
If a job starts from the past, it will read stored events as fast as it can. During catch-up, windows close quickly and outputs surge. Make sure the outputs can take the burst, and consider extra units during catch-up.
State and restarts
Starting from the last stopped time normally restores saved state, so windows are not lost. But changes to the query may make saved state unusable. When you change a query, test whether the job can resume with state or must start fresh, and plan the consequences for windows that were in progress.
Compatibility levels
The service has numbered compatibility levels that fix certain behaviors, such as how some functions treat data types. New jobs get the recommended level. Existing jobs keep their level until you change it, to avoid breaking results. When you raise the level, test, since small differences can change numbers.
Stopping and deleting
You pay for the job while it exists in a running state, and often for allocated units even when not processing much. A job you do not need should be stopped and, if never to be used again, deleted. Stopped jobs normally do not bill for running time, but check the current billing rules.
Job configuration as code
Query text, inputs, outputs and settings can all be exported as files and kept in version control. Treat them like application code, with review and automated deployment. A job created by hand in the portal is hard to reproduce after an accident.
14Checkpoints, Fault Tolerance and High Availability
A job that runs for months will see failures. The design assumes this and recovers automatically.
Checkpoints
The service regularly saves a snapshot of its state and the position it has read in each input partition. If the machine running the job fails or is moved for maintenance, a new one loads the latest checkpoint and continues from there. Events after the checkpoint are read again from the buffer, which is why the buffer must keep events long enough. After recovery the job produces the same results it would have produced without the failure, thanks to the way it replays.
A reader keeps a bookmark and a note of the running score of a game they are tallying. If the lights go out, they relight the lamp, open the book at the bookmark and continue with the note in hand. Nothing is lost, only a few lines are read twice.
Retention matters
If a job is down longer than the buffer’s retention period, events that expired are gone. Choose retention longer than your worst realistic outage and repair time, and alert when a job stops.
Planned maintenance
The platform updates the underlying machines from time to time. The job restarts from its checkpoint with a short pause. Results may be delayed briefly. Applications that consume outputs should tolerate small gaps and duplicates.
Availability across zones and regions
Some configurations place a job so that it survives the loss of a zone. For loss of a whole region, a common design runs a second job in another region reading from a replicated or duplicated stream. Both write to separate outputs, and consumers switch if the primary fails. This costs double, so reserve it for critical flows.
flowchart LR
subgraph RA["Region A: primary"]
EHA["Event hub"] --> JA["Job A"] --> OA["Output A"]
end
subgraph RB["Region B: secondary"]
EHB["Event hub copy"] --> JB["Job B"] --> OB["Output B"]
end
EHA -. "geo-replication or dual send" .-> EHB
OA --> APP["Consumers"]
OB -. "used if A fails" .-> APP
Failure modes to expect
| Failure | Effect | Defense |
|---|---|---|
| Compute node failure | Short pause then resume from checkpoint | Built in; keep retention long |
| Output unavailable | Backpressure, growing delay | Retry settings, alerts, buffer capacity |
| Bad event format | Input errors, dropped events | Schema discipline, dead-letter sink |
| Query bug | Wrong results, not an error | Testing, review, replay capability |
| Region outage | Job and buffer unavailable | Second region with its own job |
| Expired credentials | Input or output auth failure | Managed identity, rotation alerts |
15Security
Streaming jobs often handle sensitive data, such as payments, locations and health readings. Protect each link in the chain.
Identity and access
Use a managed identity for the job rather than stored keys wherever the input or output supports it. The identity is given exactly the rights it needs: read on the input, write on the output, read on the reference data. Humans get roles that let them view or edit jobs; only a small team should be able to start, stop or change production jobs.
Secrets
If a connection string or password is unavoidable, keep it in Key Vault and refer to it from deployment code. Never put secrets in query text, in chat messages or in shared documents. Rotate secrets on a schedule and after any person with access leaves the team.
Network protection
Inputs and outputs have public addresses by default. For sensitive flows, place the services behind private endpoints and use the job’s dedicated cluster option or network integration so the job reaches them privately. Restrict public access on the buffer and outputs when private paths are in place.
Encryption
Data is encrypted in transit between the service and its inputs and outputs, and at rest where it is stored, such as in checkpoints and reference data. Some organizations bring their own keys for stronger control; consider this if rules require it.
Protecting the data inside events
Minimize fields
Pass only the fields needed downstream. Drop or mask personal data early in the query.
Mask or hash identifiers
Replace direct identifiers with hashed values where analysts do not need the originals.
Separate outputs by sensitivity
Send detailed data to a locked store, and only aggregates to broad dashboards.
Control retention
Keep events and outputs only as long as needed.
Auditing
The activity log records who changed a job, its query or its settings. Send it to a central workspace, protect it from edits and alert on changes to production jobs. Because a changed query can silently change business numbers, query edits deserve review like any code change.
| Risk | Control |
|---|---|
| Leaked connection strings | Managed identity, Key Vault, rotation |
| Public exposure of inputs and outputs | Private endpoints, disable public access |
| Over-broad permissions | Least privilege roles for job and people |
| Sensitive data spreading | Field minimization, masking, separate outputs |
| Unreviewed query changes | Version control, review, activity alerts |
| Injected bad events | Validate at ingestion, authenticate producers |
16Monitoring, Logging and Troubleshooting
A job that runs all day needs eyes on it. A short list of metrics tells you almost everything.
Key metrics
Streaming unit utilization
Memory use as a share of what the job has. Sustained values above about eighty percent warn of coming trouble.
Watermark delay
How far behind real time the job’s results are. Rising delay means the job is not keeping up.
Backlogged input events
Events waiting in the buffer unread. A growing backlog means the job is too slow.
Input events and output events
Rates in and out. A sudden drop in either is a signal.
Input deserialization errors
Events the job could not read.
Late and out-of-order events
Counts of events adjusted or dropped, to tune tolerances.
Runtime errors and data conversion errors
Failures inside the query or when writing outputs.
Job state
Whether the job is running, degraded or failed.
Logs
Activity logs record management actions. Diagnostic logs record details of runtime and data errors, such as which event failed to parse. Send them to a central workspace for search and alerts. For events that failed, an option to route them to a separate store lets you inspect and repair them later rather than losing them.
Alerts worth having
Alert when the job state is not running, when watermark delay passes your limit, when utilization passes eighty percent for a sustained period, when errors appear, when input events fall to zero for longer than usual, and when output events fall to zero. Zero events is a classic silent failure: the job looks healthy but nothing flows.
A troubleshooting walk
Is the job running?
Check state and recent restarts in the activity log.
Are events arriving?
Compare input events with what the producers say they sent. Check the buffer’s own metrics.
Are events readable?
Look at deserialization errors and format changes by producers.
Is time behaving?
Check late, early and out-of-order counts and watermark delay. Look for devices with wrong clocks.
Is the job keeping up?
Look at utilization and backlog. Add units or fix the parallelism if needed.
Is the output healthy?
Check output errors and the capacity of the destination.
Record normal event rates by hour and day. Many problems show up as a pattern that differs from normal, rather than as an error message.
17Understanding Cost
Costs for streaming come from always-on compute and from the services around the job. Prices change, so use the official calculator for real figures.
Streaming units
Billed per unit per hour while the job runs. This is the main cost and grows with the units you assign.
Ingestion service
Event hubs and IoT hubs are billed by capacity and by the volume of events.
Outputs
Databases, storage and message services each have their own charges and throughput limits.
Dedicated cluster
If used, billed for reserved capacity, shared by many jobs.
Data transfer
Moving data across regions or out of Azure may add fees.
Logs and monitoring
Detailed logging at high volume can be a hidden expense.
A worked monthly example
The numbers below are invented to show the method. Suppose a job uses 12 streaming units and each costs 0.11 dollars per hour. The hourly cost is 12 times 0.11, or 1.32 dollars. A month has about 730 hours, so the job costs 1.32 times 730, or 963.60 dollars. Add an event hub at 150 dollars, a database output at 300 dollars and logs at 40 dollars, and the pipeline costs about 1,453.60 dollars per month. If utilization is always below 30 percent, halving units to 6 saves about 481.80 dollars per month. If a test job runs all month at 6 units, it adds about 481.80 dollars; stopping test jobs outside working hours cuts this by two thirds.
Ways to reduce cost
Right-size units by watching utilization over weeks. Combine several small queries into one job so they share inputs. Stop development and test jobs when not in use. Filter early so less data moves through the system. Reduce hop count in windows and reduce the number of keys in state. Use batching to lower output costs. Archive raw events cheaply and keep only what you need in expensive databases.
Where money is wasted
Typical waste includes jobs sized for peak that never comes, abandoned test jobs, duplicate jobs reading the same stream for similar results, large reference tables and long retention of detailed outputs in costly stores. A monthly review of utilization and tags finds these.
Tags for owner, environment and application show who pays for each job and make it easy to find ones nobody uses.
18Choosing Between Stream Processing Options
Azure offers several ways to process streams. The right one depends on the complexity of the logic and the skills of your team.
| Option | Style | Best for | Trade-off |
|---|---|---|---|
| Stream Analytics | Managed, query-based | Filtering, windows, joins, alerts with minimal code | Less flexible for complex custom logic |
| Functions on event triggers | Code per event or batch | Simple reactions to events and custom actions | You manage state and windows yourself |
| Spark-based streaming platforms | Cluster, code or notebooks | Complex transformations, machine learning, huge scale | More skills and operation effort |
| Real-time analytics database | Ingest and query fast | Interactive exploration of recent data | Not a processing engine for alerts by itself |
| Open stream engines on clusters | Code, full control | Advanced stateful logic | Heavy operation |
| Real-time features of unified analytics platforms | Integrated with lakehouse tools | Teams already on that platform | Depends on platform choices and licensing |
flowchart TD
S["Need to process a stream"] --> A{"Logic mostly filter, window, join, aggregate?"}
A -->|"Yes"| SA["Stream Analytics"]
A -->|"No, custom or complex"| B{"Simple per-event reaction?"}
B -->|"Yes"| FN["Functions"]
B -->|"No"| C{"Heavy transformations or machine learning?"}
C -->|"Yes"| SP["Spark-based or open stream engine"]
C -->|"No"| D["Revisit requirements"]
When Stream Analytics shines
It shines when the question can be expressed as “filter these events, group by key and time, enrich with a list and send the result there.” Teams that know the database query style can ship a working pipeline in hours. Operation effort is low.
When to look elsewhere
Complex custom state machines, extremely large state, multi-step machine learning, advanced libraries and special protocols often fit better elsewhere. Also, if your whole data platform already runs on another engine and your team is expert in it, a single standard may beat a mix of tools.
Combining tools
Many designs use several: Stream Analytics for fast alerts and windowed metrics, a data lake for full history, and a heavier platform for model training. They share the same event hub, each reading in its own consumer group.
For a quick sandwich you use a toaster and a knife. For a banquet you need a full kitchen and chefs. Stream Analytics is the efficient kitchen counter for everyday meals; the larger platforms are the banquet kitchen.
19Advantages, Disadvantages and Trade-offs
An honest look at what the service does well and where it falls short.
Advantages
- Fully managed: no clusters to build, patch or repair
- Query-based approach is quick to learn for people who know database queries
- Built-in windows, joins, time handling and anomaly helpers
- Automatic checkpoints and recovery
- Many ready-made inputs and outputs inside Azure
- Scales by adding units, with parallel lanes for large streams
- Good tools for testing queries on sample data
Disadvantages
- Less flexible than code-based engines for complex custom logic
- Always-on billing while the job runs
- State lives in memory, so large windows and many keys need many units
- Delivery to some outputs can be at-least-once, so duplicates must be handled
- Query changes can make saved state unusable
- Time handling is subtle and easy to configure wrongly
- Tied to the Azure ecosystem
Key trade-offs
| Choice | Benefit | Cost |
|---|---|---|
| Large late arrival tolerance | More complete, accurate windows | Delayed results |
| Event time instead of arrival time | Correct business timing | More waiting and memory |
| Hopping instead of tumbling | Smoother metrics | More state and output |
| More streaming units | Headroom and speed | Higher bill |
| One job, many queries | Shared input, lower cost | One failure affects all queries |
| Separate jobs per use | Isolation and independent changes | More cost and more to manage |
The central balance
Almost every streaming design balances three forces: how fast you want answers, how correct you want them, and how much you want to pay. Faster and more correct together cost more. Decide which of the three matters most for each use. A fraud alert may accept some false alarms for speed; a financial report must be correct even if delayed.
20Design Patterns and Anti-Patterns
Teams that run streaming pipelines well repeat a handful of habits. Teams that struggle repeat a handful of mistakes.
Patterns that work
Hot path and cold path
Send events to a fast path for quick alerts and live numbers, and in parallel to cheap storage for detailed analysis later.
Filter early, aggregate next
Remove unneeded events and fields first, so later steps handle less data.
Enrich with reference data
Add names, locations and thresholds from small lookup lists instead of changing producers.
Two-stage aggregation
Compute partial results in parallel lanes, then combine small partial results.
Idempotent outputs
Write results with keys so repeated delivery overwrites instead of duplicating.
Dead-letter path
Route unreadable or failed events to a store for inspection and repair.
Anti-patterns to avoid
Arrival time by accident
Using arrival time when the business wants event time, then wondering why bursts look like spikes.
Unbounded keys
Grouping by a field with endless unique values, like a request id, with long windows, so memory grows without end.
One giant query
Hundreds of lines in a single job that nobody understands or dares to change.
Ignoring duplicates
Assuming outputs arrive exactly once and double-counting after recoveries.
No monitoring of zero
Alerting on errors but not on silence, so a dead source goes unnoticed for days.
Hand-built production
Jobs created by clicking in the portal and never stored as code.
21Best Practices and Common Mistakes
A checklist to apply before any job carries live traffic.
Best practices
Start from the question
Write down what decision the result supports, how fast it is needed, and how accurate it must be.
Choose the time model deliberately
Pick event time where correctness matters and set tolerances from measured delays.
Design for parallelism early
Align partition keys, input and output partition counts so lanes stay independent.
Use one consumer group per reader
Avoid sharing groups between jobs and applications.
Test with sample and recorded data
Run the query on saved events, including late and malformed ones, before going live.
Make outputs idempotent
Expect duplicates and design consumers to ignore them safely.
Monitor delay, backlog, utilization and silence
Create alerts for each, with clear owners.
Keep everything as code
Queries, settings and deployment in version control with review.
Common mistakes
| Mistake | Result | Prevention |
|---|---|---|
| Two readers share a consumer group | Events seem to go missing | One group per reader |
| Tolerance set too small | Late events dropped, totals too low | Measure delays, then set |
| Tolerance set too large | Results arrive much later than needed | Balance against the business need |
| Partition count too low on the hub | Cannot scale past a point | Plan for growth when creating the hub |
| Skewed key | One lane overloaded, others idle | Choose a more even key or add a salting step |
| Oversized reference table | Memory pressure | Trim columns, move heavy lookups elsewhere |
| Output too small for result rate | Backpressure and delay | Size the destination, batch writes |
| Changing the query without testing state | Lost windows or restart from scratch | Test upgrades on a copy |
22Failure Scenarios and Recovery
Walk through failures in advance, and recovery becomes routine.
Scenario one: results are suddenly delayed
Dashboards show numbers ten minutes behind. Likely causes: an output is slow, utilization is high, or a hot key overloads one lane. Recovery: check backlog and utilization, scale units, fix the slow output, and repartition the hot key. Prevention: alert on delay before users notice.
Scenario two: the totals are too low after a network outage
Field devices were offline for twenty minutes, then sent everything at once. The job’s late arrival tolerance was five minutes, so older events were adjusted or dropped. Recovery: replay from the buffer or archived raw events with a larger tolerance into a corrected table. Prevention: measure the longest realistic outage and either widen tolerance or run a corrective batch.
Scenario three: a producer changed its format
A team renamed a field and the job’s input errors soared. Events were dropped. Recovery: revert the producer or update the job, then replay the missed period from the buffer. Prevention: schema versioning, producer testing and a dead-letter path.
Scenario four: duplicates in the database
After a platform restart, some rows appear twice. The output was at-least-once and the table had no unique key. Recovery: remove duplicates by key and rebuild affected totals. Prevention: define a natural key per result and upsert, and test with failure injection.
Scenario five: memory runs out
Utilization hits one hundred percent and the job degrades. A new feature added a request id to a group key and kept long windows. Recovery: remove the unbounded key, shorten windows, add units. Prevention: review state size when changing queries.
Scenario six: the job stopped and nobody noticed
A credential expired on a Friday and the job failed. The buffer retention was one day, so events from the weekend were lost. Recovery: restore access and accept the gap or fill from other sources. Prevention: alerts on job state and on zero events, managed identities, and retention longer than a long weekend.
flowchart TD
A["Results wrong or late"] --> B{"Job running?"}
B -->|"No"| C["Check credentials, errors and restart"]
B -->|"Yes"| D{"Backlog or delay growing?"}
D -->|"Yes"| E["Check utilization, output speed and hot keys; scale or fix"]
D -->|"No"| F{"Counts lower than expected?"}
F -->|"Yes"| G["Check late events, input errors and consumer groups"]
F -->|"No"| H["Check query logic, windows and reference data"]
C --> I["Verify outputs and replay if needed"]
E --> I
G --> I
H --> I
Store raw events in cheap storage so you can rebuild any result after a bug. Without raw events, a wrong number can only be explained, not fixed.
23Development, Testing and Deployment
Good streaming systems are built, tested and released with the same care as any other software.
Develop locally and in the cloud
You can write and test queries in the portal against sample data, or in a developer tool on your own computer that runs the query on local files. Local testing is faster and lets you use version control naturally. Start with small sample files that include normal, late, malformed and edge-case events.
Test layers
| Layer | What it proves |
|---|---|
| Query tests on sample files | Logic, windows and joins produce expected outputs |
| Time tests | Late and out-of-order events behave as designed |
| Integration tests in a test environment | Inputs and outputs connect and permissions work |
| Load tests | The job keeps up at expected and peak rates |
| Failure tests | Restarts, output outages and bad events are handled |
Release pipeline
Change in version control
Query and configuration changes are reviewed like application code.
Automated tests
Run query tests against stored sample data in a pipeline.
Deploy to test
Create or update a test job and run it on a copy of the stream.
Compare to production
Run old and new versions side by side to separate outputs and compare results.
Cut over
Switch consumers or stop the old job and start the new one from the right time.
Watch and keep rollback ready
Monitor delay and results, and keep the previous version available.
Upgrades with state
A changed query may or may not resume with saved state. Prefer designs where a restart from a recent time, with a short warm-up, gives correct results. For example, an hourly window can be rebuilt by starting one hour earlier. Plan these warm-ups in the release steps.
Environments
Keep separate development, test and production jobs with their own inputs and outputs. Use parameters for names, connection settings and sizes. Never point a test job at a production output.
Save a few hours of real events, with sensitive fields masked, to use in tests. Real data contains surprises that invented samples never do.
24Real-World Usage Examples
These are typical, invented scenarios that show the ideas at work. They are not reports about any named company.
Spotting an overheating machine
Sensors on machines send temperature and vibration readings every second. A job computes a rolling average per machine and compares it with a threshold from a reference table of machine types. A sliding window raises an alert event the moment too many readings exceed the limit. Alerts go to a message service that notifies maintenance staff. Full raw readings are archived in a data lake for later study.
Catching suspicious card activity
Payment events flow into an event hub. A job looks for the same card used in two distant places within a short time, using a time-bounded join of the stream with itself, and counts attempts per card using a sliding window. Matches go to a fraud team queue within seconds, while all events continue to a lake for the analysts.
Live sales and stock view
Tills send sale events. A tumbling window totals sales per store per minute and a reference table adds store names and regions. A live dashboard shows sales by region, and when stock counts fall below a level, a message goes to the replenishment system.
Trucks that stop too long
Each truck sends its position and speed. A session window per truck closes when movement resumes, and the job calculates stop durations. Stops beyond the limit trigger a notification, and daily summaries feed a planning database.
Understanding viewer behavior
Players send start, pause and quit events. Session windows group events per viewer to measure watch time and drop-off points. Results guide which programs to promote, and unusual spikes in errors trigger engineering alerts.
What they share
Each example starts from a clear question, uses the right window for the question, enriches events with small reference lists, writes results somewhere that people or systems act on, and keeps raw events for replay. The tool was simple; the thinking about time and groups was the real work.
25Built-in Analytics: Anomalies, Locations and Custom Functions
Beyond counting and averaging, the service includes helpers that answer richer questions without leaving the query.
Spotting unusual values
Fixed thresholds are easy to write but often wrong. A temperature that is normal for a furnace is alarming for a freezer. Built-in anomaly detection functions learn what is normal in a recent stretch of the stream and flag values that depart from it, either as sudden spikes and dips or as slow changes in trend. The job looks back over a history window you define, scores each new reading, and outputs a flag and a score. You then decide what score deserves an alert.
An experienced nurse knows each patient’s normal pulse. A heart rate of ninety is alarming for one patient and ordinary for another. Anomaly detection gives the stream a nurse’s memory of what normal looks like for each source.
Tuning anomaly checks
History length
Too short and the job treats every change as normal. Too long and it reacts slowly to genuine new patterns.
Sensitivity
A higher sensitivity catches more but also raises more false alarms.
Per-key models
Partition by device so each device is judged against its own past, not the average of all devices.
Warm-up
The first readings after a start have no history, so ignore alerts during the warm-up period.
Geographic functions
Events often carry a latitude and longitude. The language can build points and areas and ask whether a point lies inside an area, or how far two points are apart. This allows rules like “alert when a vehicle leaves its permitted zone” or “count visitors currently inside a building’s boundary.” The areas can come from reference data, so planners update zones without editing the query.
Windowed pattern matching
Some questions are about the order of events: a login failure followed by a password reset followed by a successful login from a new place. Analytic functions let a query look back at the previous event, or the last event of a certain type for the same key, within a time limit. This turns a stream of separate facts into a story with a beginning and an end.
Custom functions
When built-in functions are not enough, you can add your own logic written in common programming languages or as a trained model. This is helpful for a special calculation or a scoring model, but it comes with costs. Custom code adds delay, needs testing of its own and can become the slowest part of the job. Keep such functions small, stateless and well tested, and prefer built-in features when they can do the job.
Machine learning scoring
A trained model, hosted as a service, can be called from the query to score each event, for instance to predict the chance of a fault. Calls over the network add delay, so batch events per call when possible, and plan for the model service being slow or unavailable. A fallback value for failed calls keeps the pipeline alive.
| Feature | Good for | Watch out for |
|---|---|---|
| Anomaly detection | Unknown or changing normal ranges | False alarms, warm-up, history length |
| Geographic functions | Zone entry and exit, distance | Quality of coordinates and zone data |
| Look-back functions | Sequences and changes between events | Memory for long look-back times |
| Custom code functions | Special calculations | Added delay, testing, maintenance |
| Model scoring | Predictions per event | Network delay, model downtime |
A plain threshold with a good window beats an advanced model nobody understands. Add smarter analytics only when a simple rule proves too noisy or too blunt.
26Frequently Asked Questions
Short answers to common questions. Where a detail may have changed, confirm in the current Microsoft documentation.
27Summary and Key Takeaways
Azure Stream Analytics is a managed service that reads endless streams of events, computes over time windows and sends results to where people and systems can act at once.
Key takeaways
- A job connects inputs, a query and outputs, and runs continuously; reference data adds meaning to events.
- Time is the hardest part: choose event time when correctness matters, and set late and out-of-order tolerances from measured delays.
- Pick the window to fit the question: tumbling, hopping, sliding, session or snapshot, and watch how keys drive memory.
- Scale with streaming units and by keeping lanes parallel through aligned partitions; avoid hot keys and unbounded groups.
- Assume duplicates and restarts: use idempotent outputs, long enough buffer retention and a path to replay from raw events.
- Secure with managed identities, private networking and minimal fields, and monitor delay, backlog, utilization and silence.
- Treat queries as code with tests and reviews, choose the tool that fits the logic, and verify current limits, features and prices in the official documentation.