Friday, July 25, 2025

Writing KQL Queries to Analyse Azure Costs in Log Analytics

Azure Cost Management provides excellent visual tools for cost analysis, but there are scenarios where custom querying gives more flexibility, particularly when you need to correlate cost data with operational logs or produce custom aggregations that the portal does not surface directly.

Log Analytics supports several tables relevant to cost analysis. This post covers the key tables and practical KQL queries for understanding Azure spend from within a Log Analytics workspace.

1. The Usage Table

The Usage table in Log Analytics records data ingestion volumes per data type. This is the primary table for understanding Log Analytics workspace costs, as ingestion pricing is based on the volume of data written.

Following is a query to identify the top data types by ingestion volume over the past 30 days:

Usage
| where TimeGenerated > ago(30d)
| summarize TotalGB = sum(Quantity) / 1024 by DataType
| order by TotalGB desc
| take 20

This query is particularly useful when a workspace bill has increased unexpectedly. It quickly identifies which log source is responsible.

2. Estimating Ingestion Cost by Data Type

The Usage table volume can be converted to an approximate cost estimate using the current Log Analytics pricing for your region. As of 2025, Pay-As-You-Go ingestion in Australia East is approximately $3.63 per GB.

Usage
| where TimeGenerated > ago(30d)
| summarize TotalGB = sum(Quantity) / 1024 by DataType
| extend EstimatedCostAUD = round(TotalGB * 3.63, 2)
| order by EstimatedCostAUD desc

Note that this is an approximation. Commitment tiers and reserved capacity will produce different effective rates. Use this query for relative comparisons between data types rather than absolute billing reconciliation.

Understanding whether ingestion is growing, stable, or declining helps with capacity planning and budget forecasting.

Usage
| where TimeGenerated > ago(90d)
| summarize DailyGB = sum(Quantity) / 1024 by bin(TimeGenerated, 1d)
| render timechart

Rendering as a timechart in the Log Analytics query editor provides an immediate visual of ingestion trends. A sustained upward trend warrants a review of diagnostic settings and data collection rules.

4. Identifying Resources Generating the Most Logs

When a specific data type has high ingestion volume, the next step is identifying which resources are generating it. The following query works for AzureDiagnostics, which is commonly the largest data type in environments with many Azure services:

AzureDiagnostics
| where TimeGenerated > ago(7d)
| summarize EventCount = count(), EstimatedGB = count() * 0.0005 by ResourceType, Resource
| order by EstimatedGB desc
| take 20

The 0.0005 multiplier is a rough approximation of average event size in GB. The primary value of this query is identifying the top contributing resource types, not a precise cost figure.

5. Running Queries from the Portal

All queries above can be run directly from Log Analytics workspace > Logs. Results can be:

  • Exported to CSV using the Export button
  • Pinned to an Azure Dashboard using Pin to dashboard
  • Saved as a named query using Save > Save as query for reuse by the team
  • Converted to an alert rule using + New alert rule directly from the query toolbar

Summary

KQL queries against the Usage table provide a level of cost analysis granularity that the Cost Management portal does not offer natively, particularly for diagnosing workspace ingestion costs and correlating data volumes with specific resources.