Every so often you meet a tool that doesn't just do a job better, but makes you realise the job was harder than it needed to be the whole time you'd been doing it the other way. For me, this year, that tool was Kusto — specifically the Kusto Query Language, KQL, the language behind Azure Data Explorer. I'd spent months wrestling sensor and telemetry data with SQL and a struggling warehouse, and I want to describe what it was like to finally use a language built for exactly the data I had, because the difference was genuinely a small revelation.
Let me set the scene, because the "before" matters. I'd been writing earlier about why a traditional data warehouse hates time-series data — the relentless append, the temporal questions it does clumsily, the way it grinds under the shape of sensor readings. KQL and Azure Data Explorer are, in a sense, the constructive answer to that whole complaint: a store and a language designed from the ground up for exactly the log, telemetry, and time-series data I'd been forcing through the wrong tools.
It reads like a sentence
The first thing that hits you about KQL is the shape of it, and it's a genuinely different mental model from SQL. SQL is declarative and, honestly, a bit inside-out — you write SELECT first and FROM and WHERE later, describing the result before the source, and complex queries nest in ways you have to unpick from the middle. KQL flows the other way: you start with your data and pipe it through a series of transformations, each step feeding the next, left to right, top to bottom, the way you actually think about it.
Here's a query against sensor readings, and I'd wager you can read it without me explaining the syntax:
SensorReadings
| where Timestamp > ago(1h)
| where SensorType == "temperature"
| summarize avg(Value) by bin(Timestamp, 5m), RoomId
| order by Timestamp desc
Start with the SensorReadings table. Keep only the last hour. Keep only temperature. Summarise into five-minute buckets per room, averaging the value. Sort newest first. Each line is one clear step, and the whole thing reads like a set of instructions you'd give aloud. After the mental gymnastics of expressing the same thing in SQL against a warehouse, this felt like being handed a language that spoke my actual intent.
It thinks in time
The pipe syntax is the charm; the time-awareness is the substance. Look at that query again — ago(1h), bin(Timestamp, 5m). Time isn't something I bolted on with awkward date arithmetic. It's a first-class citizen of the language.
ago()lets me say "the last hour," "the last seven days," in the natural way I'd say it, instead of constructing timestamp boundaries by hand.bin()buckets data into time windows — the five-minute-average operation that was a genuine fight in the warehouse is one word here, because windowing over time is precisely what this language is built to do.- The whole engine assumes it's dealing with enormous volumes of timestamped events, and so the operations I most wanted — trends over ranges, aggregations per interval, finding what happened around a point in time — are the easy, fast, natural things rather than the hard ones.
This is the payoff of a purpose-built tool that I keep relearning: the questions that were awkward in the general-purpose tool aren't just easier here, they're the default. The language was designed by people who assumed you'd want to ask exactly these things.
The specific delights
A few things that turned "this is better" into "I actually enjoy this":
- Exploration feels fast and cheap. Because queries pipe together step by step, building one up interactively — add a filter, see what happens, add a summarise, refine — is fluid in a way that encourages actually exploring the data rather than carefully composing one big query and hoping. I found things in my sensor data I wouldn't have gone looking for, purely because looking was so low-friction.
- It's genuinely good at the log-and-telemetry questions. Finding anomalies, tracing what happened in a window around an event, spotting patterns across huge volumes — the operations that matter for operational data are rich and built-in, not things you assemble from primitives.
- The learning curve is kind. Coming from SQL, enough is familiar that you're productive quickly, and the pipe model is intuitive enough that the new parts click fast. It's not a hard language to start being useful in, which lowered the barrier to just... using it for real work.
TIP
If you're coming from SQL, don't try to translate your SQL habits line for line. Lean into the pipe model — start from the table and transform forward. The queries that feel awkward when you're mentally writing SQL-in-KQL become obvious the moment you let the data flow left to right instead.
The feature that sold me: make-series and render
One capability deserves a special mention, because it's the moment KQL went from "nicer SQL" to "oh, this is a different kind of thing." make-series builds a proper time-series — a regular, gap-filled sequence of values over time — in a single operation, which is exactly the shape you need for trend analysis and anomaly detection, and is a genuine ordeal to produce by hand in most other tools. Pair it with render timechart and you get an instant visualisation right there in the query results — no export, no separate tool, just see the shape of the data as you explore it.
That combination — build a clean time-series, see it immediately — turned querying into something closer to a conversation with the data. I'd ask, see the shape, refine, ask again, all in seconds. For someone whose whole job is finding what's happening in a flood of readings, being able to look that fast didn't just change my speed; it changed what I bothered to investigate at all, because a hunch was suddenly cheap to check instead of expensive to chase.
The honest caveats
It's not a universal hammer, and pretending otherwise would be exactly the over-enthusiasm I try to catch in myself. KQL and Azure Data Explorer are specialists — brilliant for log, telemetry, and time-series analytics, and not the tool for your transactional systems or your dimensional business warehouse. This isn't the thing that replaces your relational database; it's the thing that finally does the job your relational database was miserable at. Reach for it when your data is high-volume, timestamped, and append-heavy — and keep reaching for the relational tools when it's structured business records that need joins and transactions.
The other honest note: it's another store and another skill in the estate. Adding it means you're now running and querying two kinds of system, which is a real cost. It earned its place for me because the time-series volume was large enough and the pain of the wrong tool sharp enough that the specialist clearly paid for itself. For a modest amount of occasional telemetry, that calculus might tip the other way.
A general-purpose tool makes every problem possible. A purpose-built one makes the right problems easy — and reveals, a little embarrassingly, how much unnecessary effort you'd been spending doing it the general way.
Why I'm glad I found it
What stays with me isn't just that KQL is a nice language — it's the reminder, again, that matching the tool to the shape of the data changes the character of the work, not only its speed. Fighting sensor data with SQL, I'd started to think that kind of analysis was just inherently laborious. KQL showed me it wasn't; I'd simply been using a tool that made it laborious. The query language I didn't know I needed turned a grind back into something I actually look forward to — which is the highest praise I can give a tool, and a lesson I keep having to relearn: when the work feels needlessly hard, it's worth asking whether the problem is the problem, or just the tool you brought to it.