eventhouse
83 TopicsDeduplicating streaming events in Eventhouse: materialized view or update policy?
Hi everyone, I'm looking at how to handle duplicate events in an Eventhouse table that is fed from an Eventstream. The source can resend the same event (same EventId) after retries, so the raw table will contain duplicates. The two options I keep coming back to are: 1. A materialized view that keeps the latest record per key .create materialized-view with (backfill=true) EventsDedup on table RawEvents { RawEvents | summarize arg_max(IngestionTime, *) by EventId } 2. An update policy into a clean table, filtering out EventIds that already exist, combined with a short retention on the raw table. What I'm unsure about: At high ingestion rates, does the materialized view keep up reliably, and how do you monitor how far behind it is? Update policies only see the newly ingested batch, so duplicates arriving in different batches can still get through. Is there a common pattern to handle that, or is option 1 generally the safer choice? For downstream Power BI reports in DirectQuery, is it better to query the materialized view directly, or wrap it in a stored function? I'd be interested in how others approach this in practice, especially at higher volumes. Thanks!Solved53Views0likes4CommentsEdge device detections into Fabric: Eventstream + Eventhouse, or Lakehouse?
Hi all, While working on a computer vision project at DataToBiz, we built the edge side of a real-time system, and I’d like to compare notes with people here on how the data side would work in Fabric. On the edge, the detection runs on a Raspberry Pi. We used YOLOv8n with ByteTrack to track vehicles across frames, plus Depth-Anything-v2 for depth estimation from a single camera so we could apply spacing rules. The model was converted to ONNX, TFLite and NCNN, and we used quantization and threading to get the speed we needed without heavy hardware. A camera, GPS and compass were synced by timestamp, so every detection comes out tagged with its time, location and direction. Post-processing smooths the detections to reduce flickering. That leaves a stream of time-stamped, geo-tagged detection events from many devices, and that’s the part I’d like your input on in Fabric. Would you ingest it through Eventstreams into an Eventhouse and query it with KQL, or land it in a Lakehouse and process it in batches? Where does that line sit for you when the end goal is near real-time dashboards? How do you handle devices that go offline and send their events late or out of order? Do you rely on event time in the Eventhouse, or clean it up downstream? For the geo side, with coordinates and direction on every event, how have you handled spatial queries and map visuals in Real-Time Intelligence or Power BI? Is it good enough, or do you still end up pre-processing the coordinates? And with raw detections arriving continuously, how do you decide what to keep as raw events, and what to aggregate into something like per-location availability for reporting? Would love to hear how you’d approach it.Solved81Views0likes4CommentsLessons learned: A Real-Time Intelligence pipeline for Germany’s power grid
I built a real-time pipeline in Microsoft Fabric for live data from Germany’s power grid: generation by source, renewable share, cross-border flows, day-ahead prices and grid frequency per second. The data comes from the public Energy-Charts API of Fraunhofer ISE. On top of the Eventhouse sit a Real-Time Dashboard, seven Activator alerts and a Data Agent. The pipeline in short Source: The Energy-Charts API v2 of Fraunhofer ISE with five endpoints: public net generation, traffic light signal with renewable share, cross-border physical flows, day-ahead prices and grid frequency. No API key is required. Ingestion: Four Python Azure Functions (Python 3.13, Flex Consumption) call the API: grid frequency every minute, generation every 5 minutes, prices every 15 minutes, and a backfill every 3 hours for late corrections. They send JSON events via the Event Hubs protocol. Eventstream: One custom endpoint. Two filters with Manage fields route frequency data into frequency_raw and everything else into energy_raw. he Eventstream splits the data into two tables Eventhouse: Append-only raw tables with permanent retention. The materialized view energy_latest uses arg_max(generated_at) to always return the latest version of each value, so late corrections are simply sent again. For the grid frequency, frequency_1s removes duplicate seconds, frequency_1min aggregates per minute, and the function GridFrequency() adds the deviation from 50 Hz. Real-Time Dashboard: Three pages: Grid Live, Electricity Prices and Grid Frequency. KQL Queryset and Activator: A queryset holds the seven alert queries. Activator turns them into email rules, for example for negative prices, high export, grid congestion, frequency deviations or a data outage. Data Agent: Answers questions in plain English via eight read-only KQL functions and shows the generated query for every answer. It can optionally be published to Microsoft 365 Copilot. Git integration: The function code, all KQL scripts and every Fabric item (Eventstream, Eventhouse, Queryset, Dashboard, Activator and Data Agent) live in one GitHub repository. Design decisions that paid off One event per value (long format). New series need no schema change. A backfill function instead of a longer look-back. The source corrects values for many hours after the first publication. The 5-minute runs stay small, and the backfill catches the rest. Timer schedules offset by seconds. The API allows 2 requests per minute per endpoint, so the functions never call it at the same moment. Lessons learned from the Data Agent Give it functions, not tables. With access to a materialized view, the agent bypassed my functions, returned a forecast value as “now” and showed UTC as local time. Now only eight KQL functions are selected as the data source. Encapsulate analyses. For “How does the price depend on the renewable share?” the agent computed something different on every run. A dedicated function, PriceVsRenewableShare(), fixed that. Return every figure once. When totals were repeated in every row, the model summed them up. The function now returns totals as a separate row. Questions in English. Other languages are not officially supported yet. Full walkthrough and code Blog: From API to Data Agent GitHub: ms-fabric / real-time-intelligence-project-energy Data: Energy-Charts.info (Fraunhofer ISE), Bundesnetzagentur | SMARD.de, CC BY 4.0 About the author I’m Rene Fürstenberg. I’ve worked with Microsoft technologies since 2004, with Azure analytics since 2016, and I’ve been a Microsoft Trainer since 2019. Today my focus is Microsoft Fabric: data engineering, Real-Time Intelligence and Power BI. I offer consulting and training in English and German. If you want to dig deeper or have questions about this project, you can find me here: Blog: renefuerstenberg.de, with more hands-on guides on Fabric and Azure LinkedIn: Rene Fürstenberg. Feel free to connect or send me a message. YouTube: Cloud Junkies, videos on Microsoft Fabric (in German) GitHub: ms-fabric, the code for this and other Fabric projects Medium: @renefuerstenbergHandling late and out-of-order events in Eventstream windows and Eventhouse aggregations?
I'm coming from Apache Flink, where late and out-of-order events are handled with event-time watermarks and allowed lateness. I'm trying to understand the equivalent approach in Fabric Real-Time Intelligence. Scenario: IoT devices send telemetry with an event timestamp. Because of network delays, some events arrive several minutes late, and occasionally out of order. I need accurate 5-minute aggregates (average and max per device) for dashboards and Activator rules. Questions: Eventstream: when using windowed aggregations (tumbling or hopping), are windows based on event time or arrival time? Is there a setting for out-of-order tolerance or late-arrival handling, and what happens to events that arrive after a window has closed: are they dropped, or do they produce a corrected result? Eventhouse: if I aggregate in Eventhouse instead, for example with a materialized view using bin(EventTime, 5m), are late events included automatically when they arrive? Any caveats with materialized views and late data? Which layer is better for aggregations when correctness under late data matters more than lowest latency? Activator: if a rule has already fired on an aggregate that later gets corrected by late data, is there a pattern for handling that, or should rules only run on finalized windows?Solved83Views1like6CommentsBest practice for handling schema evolution in Fabric Eventstream before data reaches Eventhouse?
I have an Eventstream receiving operational events where the schema may evolve over time. For example, the producer initially sends: DeviceId, Timestamp, Temperature, Status but later adds fields such as: Location, FirmwareVersion, ErrorCode I want the pipeline to continue ingesting events without breaking downstream KQL tables, update policies, materialized views, or Real-Time Dashboards. I am trying to understand where schema evolution should ideally be handled in a production Fabric RTI architecture. Would you: enforce the contract upstream using Schema Registry normalize changing fields inside Eventstream before Eventhouse ingestion land the raw payload first and handle schema evolution inside Eventhouse/KQL maintain separate versioned event schemas/tables How are people handling this in production when producers can add fields without notice? I am particularly interested in avoiding a design where every small upstream schema change forces updates across Eventstream, KQL tables, update policies, and downstream dashboards.Solved168Views0likes3CommentsBest pattern for keeping a current-state table in Eventhouse from Eventstream CDC?
Hi all, I'm streaming change data from Azure SQL Database into Eventhouse using an Eventstream CDC source. Ingesting the raw change events works fine. The question is how best to turn them into a queryable current-state table, the way you would with a Flink CDC or Debezium pipeline. Setup: Source: Azure SQL Database (CDC enabled), about 20 tables, mostly updates with occasional deletes Eventstream → Eventhouse, raw change events land in one table per source table Consumers: Real-Time Dashboards and some Activator rules that need the latest row per key What I'm considering: A materialized view using arg_max(timestamp, *) by key over the raw table An update policy that flattens the change envelope into a typed table, with the materialized view on top of that Handling deletes by keeping a delete flag, then filtering it out in the view or a stored function Questions: Is option 2 (update policy, then materialized view) the recommended pattern, or is there a simpler built-in approach? How are people handling deletes? Filtering the latest row by a delete flag works, but deleted keys keep taking up space. Is there a good retention or cleanup pattern? What should I use as the ordering column so out-of-order events don't produce a stale "latest" row: the source LSN/commit timestamp, or ingestion time? Any gotchas when the source schema changes (for example, a new column)? Thanks!Solved85Views1like4CommentsChanging Ingestions from JSON
I have an EventStream receiving IoT Data out of JSONs. In my KQL table the columns timestamp, deviceId and for example x and y exist. The data from one sensor gets ingested in the columns timestamp, deviceId and y. No x since there is no data in the JSON for that. I dont work with a Mapping because it only makes it more complicated and the names in the JSON and in the KQL table are identical. No I changed the named for data from y to x when creating the JSON. Since there is no mapping and the column already exists in the KQL table the data should be saved now in column x. My problem is, it doesn't the data is not in x nor in y. It seems to be gone. Is that a bug in fabric? Can I solve this?164Views0likes11CommentsDate slicer
Hi, I need some help with Power BI. I want to use a Between Date Slicer and display the dates in this format: DD-MMM-YYYY Example: 01-Jan-2020 I don’t want to use the default dropdown/date format. I specifically want the Between slicer with two date inputs (From Date and To Date), but I need the displayed dates to appear as 01-Jan-2020 instead of the default format. Could you please guide me on how to achieve this? If the standard Power BI slicer does not support this format, is there any custom visual or alternative solution that can provide the same Between Date functionality with the DD-MMM-YYYY format? Thanks!Solved81Views1like5CommentsGlobal Aircraft✈️ Live Tracking with Microsoft Fabric Real-Time Intelligence
In this blog, I’ll walk you through, build a real-time global flight tracking system. We will ingest live flight data from the public OpenSky Network API using a Python polling script, stream it through Microsoft Fabric Eventstream into an Eventhouse (KQL Database), transform the dense raw arrays using KQL update policies and visualize the results on a Real-Time Dashboard complete with maps, KPIs and analytical charts. Prerequisites: Valid Fabric Capacity / Trail License Knowledge on Python Knowledge on KQL Step1: Setup Workspace & Eventhouse (KQL Database) Created a workspace “FlightTracking-[WS]” Created an eventhouse “FLightTracking-EH” Create a raw ingestion table “RawFlightbatc” in KQL Databse Step 2: Setup a Fabric Eventstream Created a Eventstream “GlobalFlightStream” and select ‘Use custom endpoint’ Click ‘Add’ Click on ‘Publish’ Copy the ‘Event hub name’ and ‘connection string-primary key’ into notepad Step 3: Notebook Creation and Setup Python script Created a notebook. Make sure select Python Install azure eventhub package Let’s go back to eventstream and add destination by selecting ‘Eventhouse’ Configure all details and click on save Comeback to Notebook and insert the Python script which is having all the connection strings / passwords etc. Run the notebook Now notebook started running and sending the data to eventstream Data is loaded into eventstream and Click on Publish Now eventstream is ‘Live’ Data is loading into KQL Database Step 4: Regularizing Data with KQL & Update Policies Create a cleaned table “FlightStates” Create the parsing function and update policy Alter table with updated policy Step 5: Building Real-Time Dashboard Click on Realtime dashboard and give a name “FlightOperationsDashboard” Now click on edit Run the below code to get total active flights count Change the chart to Stat and rename, click on Apply KPI added and click on Add visual and take new Stat visual Insert the code and run to get India Origin Flights and Format it and click Apply In the same way, I built other KPIs Select Map Chart Run the below code and Fill all details and Click on Apply. Here we’re calculating Flights trend We can see chart added to Dashboard Select a Bar chart Run the below code, fill all details and click on apply to add Bar chart to Dashboard. Here we’re getting the top 10 countries by aircrafts Run the below code, fill all details and click on apply to add Column chart to Dashboard. Here we’re categorizing the baro-altitude which is critical for airport delay predection Run the below code, fill all details and click on apply to add Pie chart to Dashboard. It splits the aircraft parked versus those actively flying Together, these visuals transform raw flight telemetry into an operational monitoring experience. Key takeaways: Fabric Eventstream provides a streamlined way to ingest external real-time feeds. Eventhouse/KQL Database provides a real-time analytical environment for flight telemetry. KQL mv-expand simplifies the processing of nested flight-state arrays. Update Policies automate transformation from raw streaming data into structured analytical data. KQL geospatial functions enable location-based flight analysis. Real-Time Dashboards transform streaming telemetry into actionable operational insights. Conclusion: This project demonstrates how Microsoft Fabric Real-Time Intelligence can be used to build an end-to-end real-time aircraft tracking solution. we can transform continuously arriving aircraft telemetry into meaningful real-time insights. Do you want to replicate? Get Code file from my GitHub link You can find all the KQL queries, update policy functions, and the complete Python polling script in the official GitHub repository below: [Download from here] Acknowledgements I would like to express my sincere gratitude to @SuryaTejaJosyul , @minniwalia and @rajendraongole1 for their continuous guidance and support throughout this Real-Time Intelligence (RTI) implementation. Their insights and encouragement played a key role in helping me complete this solution successfull Happy learning! — Inturi Suparna Babu [LinkedIn]Fabric Eventstream MySQL CDC scans all databases and does not emit row-level events
Hello Fabric Team, We are testing the Microsoft Fabric Eventstream MySQL CDC connector with an AWS RDS MySQL database. The MySQL instance is accessible through a private IP, and Fabric connects through a VNet data gateway/private network connection. Connectivity is successful, and the connector remains Active without reporting processing errors. Our MySQL environment contains the same table structure across multiple databases, following a pattern similar to: application_<tenant>.sample_table We configured the source to capture only one fully qualified table: application_tenant1.sample_table The MySQL configuration is: log_bin = ON binlog_format = ROW binlog_row_image = FULL The connection user has SELECT, SHOW DATABASES, REPLICATION CLIENT, REPLICATION SLAVE/REPLICA, and the required snapshot permissions. Each Fabric source uses a unique Server ID. CDC from the same RDS instance has previously worked successfully through another CDC platform. However, we are seeing the following behavior: Although only one fully qualified table is selected, Fabric/Debezium scans schema metadata for every accessible database and table on the MySQL server. More than 45,000 schema events were generated across the tenant and history databases. The schema events contain DDL such as DROP TABLE IF EXISTS and CREATE TABLE. Snapshot mode is configured as Initial. The selected table contains approximately 16,000 records, but Fabric emitted zero snapshot r events. We committed a new insert into the selected table after schema discovery finished, but no c event was emitted. Eventhouse receives the schema events successfully, confirming that the source-to-Eventhouse path is operational. The Eventhouse destination stores the Debezium payload in a dynamic column using a mapper from payload to RawEvent. Could you please confirm the following? Is it expected for the Fabric-managed MySQL CDC connector to scan and publish schema events for every database when only one fully qualified table is selected? Does Fabric expose or support settings equivalent to: database.include.list table.include.list schema.history.internal.store.only.captured.databases.ddl schema.history.internal.store.only.captured.tables.ddl Why would the connector finish schema discovery but not emit existing rows from the selected table when Snapshot mode is Initial? Why are committed inserts not emitted after the schema phase appears to finish? Is there a known limitation involving AWS RDS MySQL accessed through a private IP and VNet data gateway? What is the recommended supported destination pattern for this CDC stream? Our main objective is reliable ongoing CDC capture. We are flexible about the landing destination and can use: Eventhouse ADLS Gen2 in JSON or Parquet Fabric Lakehouse/OneLake Snowflake as the final destination Please let us know which logs, connector identifiers, timestamps, or additional configuration details would help investigate this behavior. Thank you.Solved86Views0likes4Comments