~/Live-KQL-Pipeline-Visualizer KQL examples ☕ Support me apps ← about me
// kusto query language · step by step · runs on sample data · sentinel · defender · azure data explorer

KQL Pipeline Visualizer — see what every step of a Kusto query does

Paste a KQL query and it is split into its pipeline: the source table, then one card per | step with a plain-English explanation, performance tips and the number of rows that survive it. A small built-in engine runs the query on five sample tables (SigninLogs, SecurityEvent, DeviceProcessEvents, Perf and StormEvents), so you can click any step and see its rows, even charts from render. Your query never leaves the browser.

KQL query Enter adds a new | line · Ctrl+Enter runs

Examples:
Sample tables and columns

Result

Guide — understand a KQL query in five steps

The query is parsed and run in your browser on built-in sample data. Nothing is sent to Azure or anywhere else.
1Paste or pick a query

Paste KQL from Microsoft Sentinel, Defender XDR, Log Analytics or Azure Data Explorer, or start from one of the nine examples.

2Read the pipeline

Every | step becomes a card with a coloured operator badge and a plain-English explanation. It updates while you type.

3Watch the row counts

On the sample tables each step shows how many rows are left and how much it filtered, so you see where the data shrinks or grows.

4Click a step

The panel on the right shows the rows at that point. With render at the end you get a simple chart. Copy any result as CSV.

5Apply the tips

Yellow ⚡ faster tips point out slow patterns, orange ones possible mistakes. Then share the query with share link.

What the engine can run

RUNSCommon operators

Simulated on the sample tables.

Filter
where, take, top, distinct, sample
Shape
project, extend, project-away/rename, mv-expand
Combine
summarize, join, lookup, union, let, render
FUNCTIONSMost used functions

Scalar and aggregation.

Time
ago, now, bin, datetime, startofday
Text
has, contains, in~, extract, strcat
Aggregate
count, dcount, countif, make_set, arg_max
EXPLAINSEverything else

Recognised and explained, not run.

Operators
parse, make-series, evaluate, search
Your tables
Any table name: explained step by step

KQL pipelines, explained

KQL, the Kusto Query Language, is the query language of Microsoft Sentinel, Defender XDR advanced hunting, Azure Monitor Log Analytics, Application Insights and Azure Data Explorer. A KQL query is a pipeline: it starts with a table and passes the rows through a chain of operators separated by the pipe character |. Each step receives the output of the step before it, like an assembly line. Reading a query from top to bottom therefore tells you exactly what happens to the data, and that is what this visualizer shows.

The operators you will see most

OperatorWhat it doesExample
whereKeeps rows that match a conditionwhere ResultType != "0"
projectChooses and renames columnsproject TimeGenerated, User = UserPrincipalName
extendAdds a calculated columnextend Hour = hourofday(TimeGenerated)
summarizeGroups rows and aggregatessummarize count() by Computer
sort / topOrders rows, top also limitstop 10 by count_ desc
joinCombines two tables on a keyjoin kind=inner (…) on Account
renderDraws a chartrender timechart

Writing fast KQL

Filter early and on time first: put where TimeGenerated > ago(1d) right after the table name, so the engine only scans the data partitions you need. Prefer has over contains: has looks up whole terms in the index, contains has to scan every string. Use == for exact matches and =~ only when case really varies. Project away columns you don't need before a join, and put the smaller table on the left. And use top N by instead of sort plus take.

Common mistakes

A single = in a where clause is an error: comparisons use ==. sort by is descending by default, which surprises people coming from SQL. A join without kind= is innerunique, which silently removes duplicate keys from the left side. Grouping by a raw TimeGenerated creates one group per timestamp; wrap it in bin(TimeGenerated, 1h). And take returns arbitrary rows, so two runs can give different results.

let statements

Statements before the main query start with let and end with a semicolon. let threshold = 5; defines a value; let BadIPs = SigninLogs | where … | distinct IPAddress; defines a table you can use as a source, in a join or in where IPAddress in (BadIPs). The visualizer runs both kinds and shows them above the pipeline.

About the sample data and the engine

The five sample tables are generated in your browser with realistic columns from Microsoft Sentinel and Defender (SigninLogs, SecurityEvent, DeviceProcessEvents, Perf) and the classic StormEvents tutorial table. They contain a few planted incidents (a password spray, MFA fatigue, a brute force that succeeds and encoded PowerShell) so the security examples return something. The engine is a small JavaScript reimplementation written for learning: it covers the common operators and functions, not every edge case of Kusto, and some details such as integer division and default column names may differ. Always test production queries in your own workspace.