KQL · cost
Telemetry volume by table, in GB per day
Billed gigabytes per Application Insights table over the last 7 full days, with stored rows, items and the daily average, to see what drives the bill.
requestsdependenciesexceptionstracescustomEventspageViewsavailabilityResultsperformanceCounterscustomMetricsbrowserTimings cost
let lookback = 7d;
union withsource = source_table
requests, dependencies, exceptions, traces, customEvents,
pageViews, availabilityResults, performanceCounters, customMetrics, browserTimings
| where timestamp >= startofday(ago(lookback)) and timestamp < startofday(now())
| summarize
billed_gb = sum(_BilledSize) / 1e9,
stored_rows = count(),
items = sum(coalesce(itemCount, int(1)))
by source_table
| extend gb_per_day = round(billed_gb / (lookback / 1d), 3)
| extend billed_gb = round(billed_gb, 3)
| order by billed_gb desc Returns: One row per table with the billed gigabytes over the last 7 complete days, the stored rows, the items they stand for after sampling, and the average gigabytes per day, largest first.
Pitfalls
- _BilledSize is a hidden standard column: it doesn't appear in the schema list or in results unless you name it, which is why the classic schema tables don't show it. Microsoft documents it on every ingested Application Insights event, for workspace-based and classic resources.
- Billed size is per stored row. Sampling cuts the bill because it cuts rows; items shows how many events those rows stand for.
- performanceCounters and customMetrics have no itemCount column, because they are never sampled; coalesce() counts each of their rows once.
- Queries over raw data for long windows are slow on busy resources. Microsoft suggests restricting such queries to a day and tracking trends elsewhere.
How it works
Application Insights is billed by the gigabyte ingested, and the first step to a smaller bill is knowing which table the gigabytes land in. This query reads every Application Insights table for the last seven complete days and adds up the billed size of each.
Line by line
let lookback = 7d;covers a week of complete UTC days: from midnight seven days ago to midnight today.union withsource = source_table ...reads all ten tables and adds asource_tablecolumn naming the table each row came from.billed_gb = sum(_BilledSize) / 1e9adds up the billed bytes. Azure Monitor bills in GB of 10^9 bytes, so dividing by1e9gives gigabytes in the unit you are billed by.stored_rows = count()is the number of rows kept, anditems = sum(coalesce(itemCount, int(1)))is the number of events they stand for.coalesce()fills in 1 for the two tables that have noitemCountcolumn.gb_per_daydivides by the number of days in the window (lookback / 1d), the figure to multiply by your price per GB.
About _BilledSize and the two schemas
The table schemas on Microsoft’s migration page don’t list _BilledSize, which can make it look like a workspace-only column. It isn’t: Microsoft’s usage analysis page says the property is available on each ingested event for both workspace-based and classic resources, and gives a classic-name example (dependencies | summarize sum(_BilledSize) by operation_Name). It is a hidden standard column that only appears when you name it. In the workspace, the same query reads the App* tables, and you can also filter on _IsBillable:
let lookback = 7d;
union withsource = source_table
AppRequests, AppDependencies, AppExceptions, AppTraces, AppEvents,
AppPageViews, AppAvailabilityResults, AppPerformanceCounters, AppMetrics, AppBrowserTimings
| where TimeGenerated >= startofday(ago(lookback)) and TimeGenerated < startofday(now())
| where _IsBillable == true
| summarize billed_gb = round(sum(_BilledSize) / 1e9, 3) by source_table
| order by billed_gb desc
Reading the result
Start with the first row. A large traces row is usually verbose logging: see the noisiest trace messages. A large table with items far above stored_rows is already sampled; one with the two equal isn’t, and sampling rate in effect shows which. The pricing guide turns these gigabytes into money and lists the levers, and the sampling guide covers the biggest one.
Sources, checked
- Analyze usage in a Log Analytics workspace (Application Insights data volume)
- Standard columns in Azure Monitor log records (_BilledSize)
- Azure Monitor Logs cost calculations and options (GB is 10^9 bytes)
- union operator (Kusto)
- Telemetry sampling in Application Insights
- Migrate an Application Insights classic resource to a workspace-based resource (table schemas)