Sunday, August 17, 2025

Optimising Azure Monitor Ingestion Costs: What to Log and What Not To

Azure Monitor Log Analytics is billed primarily on data ingestion volume. As environments grow and diagnostic settings are enabled across more resources, ingestion costs can increase significantly, often without a corresponding increase in the value derived from the data being collected.

Cost optimisation is a key pillar of the Azure Well-Architected Framework. This post outlines a structured approach to reducing Log Analytics ingestion costs without compromising on operational visibility.

1. Understanding Ingestion Pricing

Log Analytics uses a tiered pricing model. The Pay-As-You-Go rate applies to all ingestion above any commitment tier purchased. Commitment tiers (100 GB/day, 200 GB/day, and higher) offer significant per-GB discounts for workspaces with consistent, predictable ingestion volumes.

Before optimising individual log sources, it is worth reviewing the workspace's current daily ingestion volume to determine whether a commitment tier would reduce overall cost.

Navigate to Log Analytics workspace > Usage and estimated costs to see the current daily ingestion volume and a comparison of what each commitment tier would cost at that volume.

2. Identifying High-Volume Log Sources

The first step in any ingestion optimisation exercise is understanding where the data is coming from.

Following is a KQL query to rank data types by ingestion volume:

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

In most environments, a small number of data types, typically AzureDiagnosticsSecurityEvent, or Syslog, account for the majority of ingestion. Focus optimisation effort on these sources first.

3. Reviewing Diagnostic Settings

Diagnostic settings control which log categories and metrics are sent from Azure resources to Log Analytics. Many resources have categories enabled by default that are rarely queried in practice.

Navigate to any Azure resource > Diagnostic settings and review the enabled categories. Common categories that can often be disabled without impacting operations include:

  • AuditEvent logs for services with low change frequency
  • AllMetrics when the same data is already available through Azure Monitor Metrics at no additional cost
  • Verbose activity categories on services such as Azure API Management (GatewayLogs at DEBUG level)

Disabling a single verbose category on a high-throughput service can reduce ingestion by several gigabytes per day.

4. Using Data Collection Rule Transformations to Filter

Data Collection Rules (DCRs) support ingestion-time transformations using KQL. This allows specific rows or columns to be filtered out before they are written to the workspace, reducing billable ingestion volume.

Following is an example transformation that filters SecurityEvent rows to retain only events with EventID in a defined allow-list:

source
| where EventID in (4624, 4625, 4648, 4720, 4726)

Navigate to Azure Monitor > Data Collection Rules, select the relevant DCR, and open the Data sources tab to configure the transformation on the applicable data source.

5. Setting Table-Level Retention

Not all data needs to be retained in the hot (interactive) tier for the same duration. Log Analytics supports per-table retention settings, with data beyond the interactive period moving to low-cost archival storage.

Navigate to Log Analytics workspace > Tables, select a table, and choose Manage table to configure the interactive retention period. For high-volume, low-query-frequency tables such as AzureDiagnostics, reducing interactive retention from 90 days to 30 days can meaningfully reduce workspace cost.

Summary

Reducing Log Analytics ingestion costs requires understanding the workspace's data profile before making any changes. Identifying the top ingestion sources, reviewing diagnostic settings for unnecessary categories, applying DCR transformations to filter noisy data, and right-sizing table retention periods are the four most impactful levers available, none of which require compromising on the logs that matter.

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.

Friday, June 20, 2025

AgentCon Perth - 20-06-2025

I had the privilege of helping organize the AgentCon Perth event, which drew an impressive turnout of over 300 AI enthusiasts.

We had an outstanding lineup of speakers who shared insights on Agentic AI and how the Microsoft ecosystem can be leveraged to harness AI capabilities



Thursday, June 19, 2025

Azure Savings Plans vs Reservations: When to Use Which

Commitment-based discounts are among the most impactful cost optimisation levers available in Azure. Both Azure Savings Plans and Azure Reservations offer significant discounts over pay-as-you-go pricing, but they serve different scenarios and the distinction is not always obvious.

This post outlines what each commitment type offers, their key differences, and a practical framework for deciding which to use.

1. What Is an Azure Reservation

An Azure Reservation is a commitment to a specific resource type, size, and region for one or three years. In exchange, Azure offers discounts of up to 72% compared to pay-as-you-go.

Reservations are available for a wide range of services including:

  • Virtual Machines (e.g., Standard_D4s_v5 in Australia East)
  • Azure SQL Database and Managed Instance
  • Azure Cosmos DB
  • Azure Blob Storage (reserved capacity)
  • Azure Machine Learning compute clusters

The key characteristic of a reservation is its specificity. A reservation for a Standard_D4s_v5 in Australia East applies only to that VM size in that region. It does not apply to a Standard_D8s_v5 or a VM in Southeast Asia.

2. What Is an Azure Savings Plan

Azure Savings Plans, introduced in 2022, offer a more flexible commitment model. Rather than committing to a specific resource, you commit to a fixed hourly spend (for example, $5/hour) across eligible compute services for one or three years.

The savings plan discount applies automatically to any eligible compute usage across VM sizes, regions, and even across Azure services such as AKS, Azure Functions, and App Service.

Savings Plan discounts are slightly lower than equivalent reservation discounts (typically 15–65% depending on the term and service), in exchange for the flexibility.

3. Key Differences

DimensionReservationSavings Plan
CommitmentSpecific resource, size, regionHourly spend amount
FlexibilityFixed to a specific resource and regionApplies across VM sizes, regions, and services
DiscountUp to 72%Up to 65%
Best forStable, predictable workloadsDynamic or diverse compute workloads
Exchange/RefundAllowed with limitsNot exchangeable

Use a Reservation when:

  • The workload has run at consistent size and scale for at least 60 days
  • The resource is tied to a specific region due to latency or data residency requirements
  • The service is reservation-eligible and you can accurately forecast utilisation above 80%

Use a Savings Plan when:

  • The workload spans multiple VM sizes or regions (common with autoscaling environments)
  • The team is early in cloud maturity and forecasting specific resource consumption is not yet reliable
  • You need a simpler commitment model that covers future architectural changes

5. Reviewing Recommendations Before Purchasing

Azure Advisor provides reservation and savings plan recommendations based on your actual usage history. I recommend reviewing these before making any commitment.

Navigate to Azure Advisor > Cost to see recommendations including estimated annual savings, recommended term, and utilisation confidence based on the past 30 days of usage.

Summary

Reservations deliver the highest discount for stable, well-understood workloads. Savings Plans offer flexibility for environments that change frequently. In practice, a combination of both often yields the best outcome: reservations for core infrastructure and savings plans for dynamic compute. Azure Advisor removes much of the guesswork by surfacing recommendations backed by actual usage data.