Microsoft Fabric Real-Time Architecture: Testing RTI, Mirroring & Shortcuts

Microsoft Fabric demo architecture comparing real-time ingestion through Eventstream and KQL Database with Fabric Mirroring and ADLS Gen2 Shortcuts, including Azure Functions, Azure SQL Database, Real-Time Dashboard, and Power BI reporting.

TL;DR: At a Glance

  • The Project: The live audience-voting demo I built for my session “Is this Real-Time? Or is this just Fantasy?” at New Stars of Data 2026. It covers the full architecture of how a click in the browser becomes a visible data point in Fabric.
  • The Comparison: Three Microsoft Fabric ingestion paths evaluated under live audience load: Real-Time Intelligence (RTI) via Eventstream, Mirroring from Azure SQL, and Shortcuts from ADLS Gen2 parquet files.
  • The Latency Reality Check: RTI via Eventstream landed votes in the KQL database within milliseconds to a couple of seconds. Mirroring averaged around 18 seconds end-to-end on a warm system, but slowed down noticeably after the source tables had been idle. Shortcuts ranged from a few seconds to several minutes, similarly showing a significant latency spike after prolonged inactivity at the source.
  • Ingestion Latency vs. Report Latency: Your data can reach the Eventhouse in under a second and still take over 5 minutes to show up in the report if you did not change the capacity default setting for Auto Page Refresh (APR).
  • The Tech Stack: Azure Function + Azure SQL + ADLS Gen2 → Microsoft Fabric Eventstream + Eventhouse, Mirroring, Shortcuts → Power BI Embedded and RTI Dashboards.

It’s an indescribable feeling when you push a button in front of an audience, just hoping that your entire demo environment doesn’t decide to take a nap right then and there.

I got to experience that firsthand on May 8, 2026, during my session at New Stars of Data. At one point during the live demo, a message appeared in the Teams chat from an audience member:

This is sorcery not fantasy 😄 What a great demo

— Audience feedback during the session

That comment captured exactly what I had hoped the demo would achieve.

While preparing the session, I found myself wondering: What actually qualifies as “real-time” in Microsoft Fabric, and how does that differ from Mirroring and Shortcuts in practice?

All three promise near-instant access to fresh data, but the real-world experience isn’t quite the same. Rather than relying on documentation and assumptions, I wanted to measure the differences myself.

Building a Live Ingestion and Performance Demo for Microsoft Fabric

Rather than testing these ingestion paths with synthetic data, I turned the audience into the data source of the demo.

Everyone in the session could vote live from their own browser without installing an app or creating an account. Their clicks hit a backend I built on Azure and got written to an Azure SQL database. Each question was configured with a specific Fabric ingestion path, allowing us to experience each path’s latency directly.

Roughly half of the 23 attendees actively voted across the different questions during the session. For a remote event at 10 am where people are inevitably half-watching and half-focused on their inbox, I considered that a good turnout for an interactive demo.

I am curious whether that number shifts when I present in person at Data Saturday Croatia this Saturday.

Screenshot of the live audience voting application used during the session, showing the custom voting interface and an embedded Power BI report used to compare end-to-end latency between direct database updates and data arriving through Fabric Eventstream.

The demo featured two distinct voting modes:

  • Standard Voting: One vote per question and person, with deduplication enforced by a unique constraint in the database. Everyone sees the aggregated results in a donut chart.
  • Latency Mode: Attendees could click the +1 button as many times as they wanted. They only saw their own votes in tabular form, filtered by their personal voter ID. This allowed them to watch their own clicks appear instantly in a JavaScript visual reading directly from Azure SQL, and then see the same data arrive in the embedded Power BI report in DirectQuery-Mode via Fabric. The gap between the two visuals made the end-to-end latency visible. Alongside this, I showed the implementation in Eventstream, the data in the KQL DB, and an RTI Dashboard to illustrate what was happening inside Fabric itself.

Every voter got assigned a randomly generated fictional pop-culture name, for example “Iron Man #A3F2”. This made it easier for audience members to spot their own votes while looking at the data in Fabric. The name was derived from a UUID that the browser generated on the first visit and stored in localStorage, so it persisted across questions without any login. If you cleared your browser storage, you would get a new identity.

This design ensured that no actual personal data was stored at any point. The voter name itself was computed deterministically from that UUID via a simple hash. This means the same UUID always produced the exact same fictional name.

The End-To-End Architecture: Azure SQL to Microsoft Fabric

Every vote, regardless of question type, followed the same first step:

Browser → Azure Function → Azure SQL

The SQL database was the main source of truth. What differed per question was what happened next.

The common path worked like this: A voter opens the voting page – a single-page HTML/JavaScript app with no frameworks. They click to vote, the request hits a Python Azure Function, and the function writes the vote to Azure SQL. The Azure SQL table is also continuously mirrored into Fabric in the background, so all data eventually ends up in Fabric’s mirrored copy. From there, the Power BI report exposes the results of all three ingestion methods through DirectQuery.

Each Fabric ingestion path behaves differently:

1. RTI via Eventstream

The Azure Function additionally sends the vote to an Eventstream custom endpoint, which routes it into an Eventhouse KQL database. This path makes the data queryable within milliseconds to a couple of seconds of the click.

2. Mirroring from Azure SQL

No extra backend code needed here. Fabric replicates the Azure SQL tables continuously. Because Fabric Mirroring does not offer DirectQuery mode when connecting from Power BI to the mirrored database, I used its SQL Endpoint via the SQL Server Connector instead.

3. Shortcuts via ADLS Gen2

The Azure Function writes each vote directly to a Delta table stored in an Azure Data Lake Storage Gen2 container. A Fabric Shortcut then exposes that external data as a Lakehouse table.

Technical Stack and Fabric Components

Let’s break down how the data navigates this pipeline from the initial click to the final dashboard visual:

  • Azure Function, Python 3.13: Handles incoming browser requests and multi-casts the payload. I originally built this in Node.js, but switched to Python because the native deltalake library made writing Delta tables significantly easier.
  • Azure SQL Database: Serves as the transactional database for the voting app and gives us our immediate baseline to compare Fabric’s latency against.
  • ADLS Gen2 Container: Stores the Delta parquet files for the external Shortcut test.
  • Eventstream, Custom Endpoint: Handles data continuously as a stream. For this demo, it exposed an inbound, push-based REST API that accepted individual vote payloads from the Azure Function as they happened.
  • Eventhouse + KQL Database: Stores and queries the live voting clickstream. The Eventhouse serves as the top-level container for one or more KQL Databases. The KQL Database hosts the data and handles ingestion and query execution.
  • Mirroring, Source Azure SQL: Continuously replicates the Azure SQL database into Fabric for analytical workloads.
  • Shortcuts: Virtual links that let you query data stored elsewhere without moving or copying the physical files. In this demo, they connected both mirrored data and ADLS-hosted Delta tables to the reporting layer.
  • Power BI Embedded & RTI Dashboard: The frontends used during the demo. The RTI Dashboard showed the streaming path, while the embedded Power BI report compared all ingestion methods and their end-to-end latency.

I plan to publish a simplified version of this demo, along with a step-by-step setup guide, so you can recreate it yourself.

Microsoft Fabric Architecture Pitfalls and Real-World Gotchas

Real-Time Intelligence vs Mirroring Latency Benchmarks

RTI via Eventstream was the fastest path, as expected. Votes appeared in the KQL database within milliseconds to a couple of seconds. The RTI Dashboard showed the results almost immediately after each click once I activated Auto Page Refresh with the “Minimal time interval” – “Continuous” setting. I would have expected this to be the default setting for RTI Dashboards.

Note: The June 2026 Fabric update replaced traditional Auto Page Refresh with the new Live Refresh mode. Instead of refreshing visuals at fixed intervals, visuals are now refreshed only when new data is detected. This helps reduce unnecessary refresh activity and capacity consumption. At the same time, however, the minimum refresh interval was increased to 10 seconds.

Mirroring, on a warm system, averaged around 18 seconds end-to-end. It was consistent, and honestly faster than I initially expected once replication was already active. The caveat is that the term “warm system” does a lot of heavy lifting in that sentence.

Fabric Mirroring After Idle Periods

In my demo, Mirroring was highly predictable once replication was already active. New votes typically appeared after roughly 18 seconds.

Things became more interesting after longer periods of inactivity. The first change following an idle period often took noticeably longer to appear than subsequent updates. That is not something you want when an audience is staring at the screen waiting for a vote to show up.

The practical workaround was simple: a quick warm-up before the presentation. About an hour before the session, and again a few minutes before going live, I opened and closed each question type and submitted a handful of test votes. It is not particularly elegant, but it proved to be effective.

ADLS Gen2 Delta Shortcuts and the Small File Anti-Pattern

The Shortcut path was based on a Delta table stored in ADLS Gen2. To avoid introducing additional latency through batch processing, the Azure Function wrote each vote directly as an individual Delta record. As a result, the solution inevitably produced a large number of very small files.

For a demo environment, this was perfectly acceptable. In a production scenario, you would typically batch writes or periodically consolidate files using OPTIMIZE to avoid the classic small file anti-pattern.

More interesting than the storage pattern itself was the latency behavior I observed. On a warm system, new data usually became available within a few seconds. After longer periods of inactivity, however, the exact same change could take several minutes before it became visible through the Shortcut.

MetricRTI via EventstreamMirroringADLS Gen2 Shortcuts
Observed LatencyMilliseconds to ~2 seconds~18 secondsSeconds to several minutes
ConsistencyVery highHigh on a warm systemHighly variable
Behavior After Idle PeriodsLittle to no changeFirst update takes longerOften significantly higher latency
Demo TakeawayFastest pathGood balance of simplicity and speedEasy to set up, but with the widest latency variation

While Shortcuts within Fabric itself behaved fairly consistently in my tests, the external Shortcuts from ADLS Gen2 into Fabric were much less predictable. I was never able to isolate the exact root cause with confidence. Once again, a quick warm-up before the presentation turned out to be the most practical workaround.

Troubleshooting Power BI DirectQuery and Auto Page Refresh Bottlenecks

Fast ingestion is only part of the equation. What ultimately matters is when the data becomes visible to users. That is why I measured not only ingestion latency, but decided to show the entire end-to-end path from a vote being submitted to its appearance in the embedded Power BI report.

DirectQuery vs Direct Lake

I chose DirectQuery mode for the report. The KQL database connector in Power BI supports DirectQuery and Import, but does not provide a native Direct Lake option.

One possible alternative would be to expose the Eventhouse tables through OneLake availability and build a Direct Lake model on top of them. However, that approach would no longer query the KQL database directly. It would also introduce an additional materialization step between Eventhouse and OneLake.

For the live demo, I wanted to keep the data path as short as possible and avoid additional layers that could influence the measured end-to-end latency.

I ran into a similar challenge with the mirrored data. While the KQL database connector supports DirectQuery and Import, the Mirroring connector only offers Import or Direct Lake.

Because I wanted to compare both the RTI and Mirroring paths within the same report, I connected the mirrored database through its SQL Endpoint using the SQL Server connector instead. This allowed me to use DirectQuery for the mirrored data as well and compare both paths under the same conditions.

Auto Page Refresh: When the Report Is Slower Than the Data

Fast data updates are only half the story. The report still needs to make those changes visible to users. I chose Auto Page Refresh (APR) to handle this automatically using a 1-second fixed interval.

Auto Page Refresh automatically refreshes report visuals without requiring users to reload the report manually. There are two trigger modes:

  • Fixed interval: Refresh every N seconds or minutes, regardless of whether data changed.
  • Change detection: Poll a dedicated measure at a set interval and only refresh visuals when a change is detected.

Both require dedicated capacity for this kind of scenario. On shared capacity, the minimum polling interval is locked at 30 minutes, making APR practically unusable for real-time reporting. On Premium or Fabric F SKUs, the minimum interval can be set as low as 1 second at the capacity level.

I chose a fixed interval over change detection because change detection introduced longer and less predictable delays in my scenario.

The biggest pitfall: APR has a minimum refresh interval configured at the capacity level. If the interval configured in the report falls below that threshold, the capacity setting is enforced instead.

The default is 5 minutes. A report configured for 1 second will quietly refresh every 5 minutes instead, without any error or warning. The enforced capacity interval is visible in the report’s Page refresh panel inside the web interface, although it is a bit hidden:

Automatic Page Refresh details in Power BI showing a configured refresh interval of 1 second. The panel displays the capacity administrator setting with an admin interval of 1 second and an actual refresh rate of 1.5 seconds.

I ran into this issue twice during preparation. The first time cost me over a day of troubleshooting because I didn’t know about that setting. The second time happened because I switched to a new capacity mid-prep and forgot it was a per-capacity setting rather than a tenant-wide one. A new capacity meant default settings all over again. It was a good reminder that defaults bite you when you least expect it.

To change the setting, you need Capacity Admin permissions. You can change it in the Fabric interface via:

Settings → Admin Portal → Capacity settings → Power BI workloads → Minimum refresh interval

Microsoft Fabric Admin Portal capacity settings showing Automatic Page Refresh configured with a 1-second minimum refresh interval.

Eventstream Live Preview is Not a Live Stream

The data preview pane at the bottom of the Eventstream editor is not a live stream. Even in Live mode, you will not see events flowing through in real time. Instead, it provides a manually refreshable preview of the data.

The preview is useful for confirming that data is arriving, understanding its structure, and troubleshooting schema or connection issues.

Microsoft Fabric RTI Dashboards: Limitations of Publish to Web and Embedding

RTI Dashboards are great for internal monitoring. However, once external users enter the picture, you quickly run into limitations. Neither Publish to Web nor embedding into public websites is currently supported.

For my demo, this meant that attendees could not view the RTI Dashboards directly. The public display of the results therefore had to be handled through an embedded Power BI report, while the RTI Dashboards remained in the background as a reference point for latency measurements.

What’s Next

The architecture covered in this article was only one piece of the puzzle.

A simplified version of the demo setup, along with additional articles on RTI, Mirroring, and Shortcuts in Microsoft Fabric, will follow in separate posts.