News and blog
NXLog main page
  • Products
    NXLog Platform
    Log collection
    Log management and analytics
    Log storage
    NXLog Agent
    NXLog Community Edition
    Integrations
    Professional Services
  • Solutions
    Use cases
    Specific OS support
    SCADA/ICS
    Windows event log
    DNS logging
    MacOS logging
    Open Telemetry
    Cost reduction
    Industries
    Financial Services
    Government & Education
    Entertainment & Gambling
    Telecommunications
    Medical & Healthcare
    Military & Defense
    Law Firms & Legal Counsel
    Industrial & Manufacturing
  • Pricing
    Licensing
    Plans
  • Partners
    Find a Reseller
    Partner Program
    Partner Portal
  • Resources
    Documentation
    Blog
    White papers
    Videos
    Webinars
    Case Studies
    Community Program
    Community Forum
  • About
    Company
    Careers
  • Support
    Support portals
    Contact us

NXLog Platform
Log collection
Log management and analytics
Log storage
NXLog Agent
NXLog Community Edition
Integrations
Professional Services

Use Cases
Specific OS support
SCADA/ICS
Windows event log
DNS logging
MacOS logging
Open Telemetry
Cost reduction
Solutions by industry
Financial Services
Government & Education
Entertainment & Gambling
Telecommunications
Medical & Healthcare
Military & Defense
Law Firms & Legal Counsel
Industrial & Manufacturing

Licensing
Plans

Find a Reseller
Partner Program
Partner Portal

Documentation
Blog
White papers
Videos
Webinars
Case Studies
Community Program
Community Forum

Company
Careers

Support portals
Contact us
Let's Talk
  • Start free
  • Interactive demo
Let's Talk
  • Start free
  • Interactive demo
NXLog search
  • Loading...
Let's Talk
  • Start free
  • Interactive demo
October 12, 2026 siem

How to reduce Microsoft Sentinel ingest cost: filter, trim, and tier before the data leaves the host

By João Correia

Share
ALL ANNOUNCEMENT COMPARISON COMPLIANCE DEPLOYMENT SECURITY SIEM STRATEGY RSS

Microsoft Sentinel charges by the gigabyte for most data you ingest into the analytics tier. To reduce Microsoft Sentinel ingest cost, drop events you never query, remove fields you don’t use, and route high-volume, low-value logs to the cheaper data lake tier. This article walks through how to do each of these with NXLog Agent configurations and KQL you can adapt for your environment.

Lever Where it runs What it saves Trade-off

Drop noisy events

NXLog Agent on the host

Analytics-tier GB, bandwidth, collector load

Check every event ID against active detections

Trim unused fields

NXLog Agent on the host

Billed record size

Some keyword rules need the text fields

Second-line filter

DCR transformation in Azure

Anything that slips past the agent

Runs after Azure receives the data

Tier by value

Agent routes to two DCR streams

About 96% lower ingest rate on lake-tier data

No real-time analytics on lake-tier tables

Why Microsoft Sentinel ingest cost is a data-engineering problem

Microsoft Sentinel pricing depends on the tier your data lands in. Pay-as-you-go bills the amount of data stored, measured in GB, plus retention beyond 90 days. You pay for whatever your estate sends.

Microsoft publishes list prices through its Azure Retail Prices API. For the East US region, checked on September 11, 2026:

  • Analytics tier, pay-as-you-go: $4.30 per GB

  • 100 GB/day commitment tier: $296/day, an effective $2.96/GB

  • 500 GB/day commitment tier: $1,265/day, an effective $2.53/GB

  • Data lake tier, direct ingestion: $0.05 per GB ingested plus $0.10 per GB data processing, then $0.026 per compressed GB per month for storage and $0.005 per GB scanned by queries

Commitment tiers reward volume you ingest every day. They don’t remove waste. Microsoft’s billing guidance states that usage above your commitment is billed at the tier’s discounted rate, so a bloated feed costs you at every tier.

In 2025, Microsoft added a second storage tier. The data lake overview describes an analytics tier for detections, hunting, and incidents, and a data lake tier for long-term storage and Python-based analytics. If you use Auxiliary Logs today, Microsoft’s billing documentation states that once you onboard to the lake, usage is billed through the data lake meters rather than the existing long-term retention, search, or auxiliary logs ingestion meters.

Every gigabyte you stop on the host is a gigabyte Microsoft never bills.

Step 1: Measure what you pay for

Measure before you filter. Microsoft’s usage analysis guide documents the Usage table and the _BilledSize and _IsBillable columns you need.

Billable volume by table over the last 31 days:

Usage
| where TimeGenerated > ago(32d)
| where StartTime >= startofday(ago(31d)) and EndTime < startofday(now())
| where IsBillable == true
| summarize BillableDataGB = sum(Quantity) / 1000. by DataType
| sort by BillableDataGB desc

Which Windows event IDs dominate SecurityEvent:

SecurityEvent
| where TimeGenerated > ago(7d) and _IsBillable == true
| summarize Events = count(), GB = sum(_BilledSize) / 1e9 by EventID
| sort by GB desc
| take 25

Which hosts send the most data. Run this one sparingly, because find scans every table:

find where TimeGenerated between(startofday(ago(1d))..startofday(now()))
  project _BilledSize, _IsBillable, Computer, Type
| where _IsBillable == true and Type != "Usage"
| extend host = tolower(tostring(split(Computer, '.')[0]))
| summarize GB = sum(_BilledSize) / 1e9 by host
| sort by GB desc

Run these before and after every change. The output is a savings figure your finance team will accept instead of an estimate.

In the environments we see, a handful of Windows Security events account for a large share of volume: Windows Filtering Platform connections (5156, 5158), object access (4663), handle events (4658, 4690), and verbose DNS or firewall "allow" logs. Your SecurityEvent breakdown shows whether that holds for you.

Step 2: Filter events at the source with NXLog Agent

Microsoft gives you two places to filter in Azure. DCR transformations run after Azure receives the data. A client-side transformation for Azure Monitor Agent exists, but the DCR overview still marks it as Preview. Neither stops the data from crossing your network.

Filtering on the collecting agent does. Every event you drop on the host is one you don’t pay to transmit, buffer, or ingest.

Suppress at the Windows API level

The Event Log for Windows input module accepts an XPath query in its QueryXML block directive, allowing you to paste a query directly from Event Viewer. Microsoft’s event query schema includes a <Suppress> element that tells the Event Log API to withhold matching events. NXLog Agent never reads them, making this the cheapest filter available.

<Input security_events>
    Module    im_msvistalog
    <QueryXML>
        <QueryList>
            <Query Id="0">
                <Select Path="Security">*</Select>
                <!-- Filtering Platform permit chatter and handle noise -->
                <Suppress Path="Security">
                    *[System[(EventID=5156 or EventID=5158 or EventID=4658 or EventID=4690)]]
                </Suppress>
            </Query>
        </QueryList>
    </QueryXML>
</Input>

The module documentation notes that, because of a limitation in the Windows Event Log API, queries with more than 22 clauses fail. Group event IDs in parentheses or split them across <Query> blocks if you hit that limit.

Drop on conditions QueryXML can’t express

For rules that depend on field values, use an Exec block and the drop() procedure from the NXLog language:

<Input security_events>
    Module    im_msvistalog
    <QueryXML>
        <QueryList>
            <Query Id="0">
                <Select Path="Security">*</Select>
            </Query>
        </QueryList>
    </QueryXML>
    <Exec>
        # Object access on scratch paths nobody investigates
        if ($EventID == 4663 and $ObjectName =~ /^C:\\Windows\\Temp\\/i) {
            drop();
        }

        # Process creation for known-benign system binaries
        if ($EventID == 4688 and $NewProcessName =~ /\\(conhost|dllhost|backgroundTaskHost)\.exe$/i) {
            drop();
        }

        # Service logons by machine accounts
        if ($EventID == 4624 and $LogonType == 5 and $TargetUserName =~ /\$$/) {
            drop();
        }
    </Exec>
</Input>

The same pattern works for any input. For Windows DNS Server analytical events collected with the Event Tracing for Windows input module, you can drop successful lookups for your own internal zones and keep failures and anything pointing outside. Event ID 257 is RESPONSE_SUCCESS in Microsoft’s DNS analytic events table. The Event Tracing for Windows module exposes the query name inside the $dns.query field, which holds a JSON object containing dns.query.name, rather than as a standalone field:

<Input dns_etw>
    Module      im_etw
    Provider    Microsoft-Windows-DNSServer
    <Exec>
        # 257 = RESPONSE_SUCCESS. Keep failures (258) and external names.
        if ($EventID == 257 and $dns.query =~ /\.corp\.example\.com/i) {
            drop();
        }
    </Exec>
</Input>

Check before you drop. Microsoft’s table settings guidance warns that moving a table from the analytics tier to the data lake tier stops features that rely on analytics data, including alerting, analytics rules, and advanced hunting. A drop rule has the same effect on the events it removes. Review every candidate event ID against your active analytics rules, hunting queries, and any Microsoft content you’ve enabled. If a detection references it, keep it or route it to the data lake tier (Step 5).

Step 3: Trim fields, not just events

Microsoft Sentinel bills the stored record, so a 4 KB event costs about eight times as much as a 500-byte one. Microsoft’s transformation guidance says it directly: omit columns you don’t need to save cost, and note that columns outside the target schema are billed for ingestion even though they aren’t stored.

Windows events carry metadata you rarely query. You have two ways to shed it on the host.

If you forward the record in JSON format, remove fields first using the delete() procedure. If no rule reads the message field, set CaptureMessage to FALSE to skip rendering it. The module documentation also lists this as a processing-time saving.

<Extension json>
    Module            xm_json
</Extension>

<Input security_events>
    Module            im_msvistalog
    CaptureMessage    FALSE   (1)
    <QueryXML>
        <QueryList>
            <Query Id="0">
                <Select Path="Security">*</Select>
            </Query>
        </QueryList>
    </QueryXML>
    <Exec> (2)
        delete($Keywords);
        delete($Opcode);
        delete($OpcodeValue);
        delete($TaskValue);
        delete($Version);
        delete($ExecutionThreadID);
        delete($EventReceivedTime);
        delete($SourceModuleName);
        delete($SourceModuleType);
        to_json();
    </Exec>
</Input>
1 Set this only if no rule reads the $Message field.
2 Delete metadata fields you rarely query before converting to JSON.

For a custom table, an allow-list is the better option. Build a payload that contains only the fields you want, with names that match your table schema one-for-one, and serialize it with the JSON extension. Nothing outside the list leaves the host:

<Extension json>
    Module    xm_json
</Extension>

<Output sentinel>
    Module    om_azuremonitor
    ... (1)
    <Exec>
        $payload = (
            'TimeGenerated' => $EventTime,
            'Computer'      => $Hostname,
            'Channel'       => $Channel,
            'EventID'       => $EventID,
            'EventLevel'    => $SeverityValue,
            'EventRecordId' => $RecordNumber,
            'Provider'      => $SourceName,
            'SubjectUser'   => $SubjectUserName,
            'TargetUser'    => $TargetUserName,
            'LogonType'     => $LogonType,
            'Process'       => $NewProcessName,
            'Message'       => $Message
        );

        $raw_event = to_json($payload);
    </Exec>
</Output>
1 Include the connection directives (Step 4).

Keep the Message field unless you’ve confirmed no keyword-based rule depends on it. Keep the EventRecordId, Channel, and Computer fields for correlation and chain of custody.

Step 4: Send through the Logs Ingestion API with a lean DCR

NXLog Agent’s Microsoft Azure Logs Ingestion output module sends to Microsoft Sentinel through the Logs Ingestion API. It authenticates with a Microsoft Entra ID application and targets a data collection rule by its immutable ID. Our Microsoft Sentinel integration guide walks through the Azure side: app registration, data collection endpoint, and a DCR template you can import.

<Output sentinel>
    Module            om_azuremonitor
    API               LogsIngestion
    TenantId          <directory-tenant-id>
    ClientId          <application-client-id>
    ClientSecret      <client-secret>
    URL               https://<dce-name>.<region>-1.ingest.monitor.azure.com
    DcrImmutableId    dcr-<immutable-id>
    StreamName        Custom-WindowsSecurity-Stream
    <Exec>
        ... (1)
    </Exec>
</Output>

<Route security_events_to_sentinel>
    Path              security_events => sentinel
</Route>
1 Include the payload mapping (Step 3).

The module also supports certificate authentication. Replace ClientSecret with CertKeyFile and CertThumbprint as shown in the integration guide.

Then add a second line of defense inside the DCR. The Microsoft Sentinel data ingestion and transformation docs state that when it is activated on the workspace, transformations to Analytics tables carry no filtering charge, however much they drop. Basic tables are different. They incur the charge once a transformation removes more than 50% of incoming data.

source
| where EventID !in (5156, 5158, 4658, 4690)
| project TimeGenerated, Computer, Channel, EventID, EventLevel,
          EventRecordId, Provider, SubjectUser, TargetUser,
          LogonType, Process, Message

We recommend using both. The agent filter saves bandwidth and ingest. The DCR transformation catches whatever a misconfigured host sends anyway.

Step 5: Route low-value data to the Microsoft Sentinel data lake tier

Microsoft describes the data lake tier as a low-cost "cold" tier. Data there isn’t available for real-time analytics or hunting, but you can reach it through KQL jobs, scheduled KQL or Spark jobs, and summary rules. You can also ingest directly into the lake without routing through the analytics tier.

At East US list prices, direct lake ingestion costs $0.15/GB ($0.05 ingestion plus $0.10 data processing) against $4.30/GB in the analytics tier, about 96% lower. Those two charges apply to tables set to the data lake tier only. Microsoft does not apply them to tables whose retention covers both the analytics and data lake tiers, because that data is mirrored rather than ingested separately, so the saving below assumes a lake-tier-only table. Storage adds $0.026 per GB per month, billed at a 6:1 compression ratio, and queries add $0.005 per GB scanned. Heavy querying erodes the savings. For firewall allows, proxy logs, NetFlow, and DNS lookups you keep for forensics rather than alerting, the lake is the right home.

Make the split once, on the host. Point two outputs at two DCR streams, one feeding an analytics tier table and one feeding a table you’ve set to the data lake tier. Each output keeps only what belongs to it. NXLog Agent supports route branching, so the same input instance can feed both routes at once:

<Output sentinel_hot>
    Module            om_azuremonitor
    API               LogsIngestion
    ... (1)
    DcrImmutableId    dcr-<hot-rule-id>
    StreamName        Custom-SecurityHot-Stream
    <Exec>
        # Keep only detection-grade events in the analytics tier
        if ($EventID NOT IN (4624, 4625, 4648, 4672, 4688, 4720, 4726, 4728, 4732, 4756, 4768, 4769, 4776, 1102)) {
            drop();
        }

        ... (2)
    </Exec>
</Output>

<Output sentinel_lake>
    Module            om_azuremonitor
    API               LogsIngestion
    ... (1)
    DcrImmutableId    dcr-<lake-rule-id>
    StreamName        Custom-SecurityCold-Stream
    <Exec>
        # Everything else goes to the data lake tier table
        if ($EventID IN (4624, 4625, 4648, 4672, 4688, 4720, 4726, 4728, 4732, 4756, 4768, 4769, 4776, 1102)) {
            drop();
        }

        ... (2)
    </Exec>
</Output>

<Route hot>
    Path              security_events => sentinel_hot
</Route>

<Route cold>
    Path              security_events => sentinel_lake
</Route>
1 Include the connection directives (Step 4).
2 Include the payload mapping and JSON conversion (Step 3).

The event ID list is illustrative. Yours should come from your detection inventory.

Step 6: Roll it out across the fleet with NXLog Platform

A drop rule on one server won’t change your bill. NXLog Platform lets you build a configuration once and assign it to many NXLog Agent instances in one go. You can author configurations in the visual configuration builder or through the API, so your drop rules can live in version control and go through the same review as your detections.

The rollout loop:

  1. Measure with the KQL queries in Step 1.

  2. Change the configuration and assign it to a pilot group of agent instances.

  3. Re-measure. Confirm your analytics rules still fire on test events.

  4. Assign to the rest of the fleet, or roll the configuration back.

Start with NXLog Agent to prove the approach on a few hosts. Move to NXLog Platform when you need to manage the change across hundreds or thousands of hosts.

What this looks like in practice: an illustrative model

This is a model, not a measurement. Replace the percentages with the output of your own queries from Step 1. Prices are East US pay-as-you-go list prices from Microsoft’s Retail Prices API on September 11, 2026, before any commitment discount or free data allowance.

Stage Daily volume Analytics tier cost/day Lake tier cost/day

Baseline: 500 GB/day, all analytics

500 GB

$2,150

n/a

Drop 25% of events at the agent

375 GB

$1,613

n/a

Trim 10% of bytes from what remains

337.5 GB

$1,451

n/a

Route 200 GB/day of that to the lake tier

137.5 GB hot, 200 GB cold

$591

$30 ingestion and processing, plus storage

Under these assumptions, the daily analytics bill falls from $2,150 to about $590. Lake storage adds roughly $26 per month for each month of lake data you retain (200 GB/day at 6:1 compression, $0.026 per GB-month), plus query charges. Halve every assumption and the analytics bill still falls by more than a third. The three levers multiply: each one shrinks the volume the next one works on, and all three cost less when applied before ingestion.

The model leaves out commitment-tier pricing (which lowers the baseline), retention beyond 90 days, lake query volume, and the free data sources Microsoft lists, such as Office 365 audit logs and Microsoft Defender alerts. Plug in your own numbers.

Five mistakes that undo the savings

Filtering at query time

A WHERE clause in a workbook filters data you already paid to ingest.

Dropping events your detections need

Check rule references first. Route to the data lake tier when in doubt.

Forgetting the Basic table rule

Transformations that drop more than 50% of a Basic table’s data incur the filtering charge. Analytics tables don’t.

Moving a table to the lake and then hammering it with queries

Lake queries bill per GB scanned.

Committing before you’ve filtered

Microsoft allows lowering a commitment tier only every 31 days. Measure the post-filter volume, then commit.

Conclusion

Drop what you never query, trim what you don’t need, and put the rest in the tier that matches how you use it. Do it on the host, before Microsoft Azure sees the data. If you’d like help mapping your own event inventory to this model, we’re happy to talk it through. You can try NXLog Platform free or get in touch with any questions.

FAQ

What is the cheapest way to reduce Microsoft Sentinel ingest cost?

Stop unneeded data before it reaches Microsoft Azure. Filtering on the collecting agent avoids ingest charges, bandwidth, and DCR processing. DCR transformations are a good second layer, but they run after Microsoft Azure has received the data.

Does filtering with a DCR transformation cost money?

According to Microsoft, not for Analytics tables when Microsoft Sentinel is activated on the workspace. For Basic tables, a filtering charge applies once the transformation drops more than 50% of incoming data.

What’s the difference between Basic, Auxiliary, and the Microsoft Sentinel data lake tier?

Microsoft Sentinel now has two tiers: analytics and data lake. When you onboard to the data lake, Auxiliary Logs meters are replaced by data lake meters. Basic Logs remain a Log Analytics plan with its own rate, currently $1.00/GB in East US.

Can I filter Windows Security events before they reach Microsoft Sentinel?

Yes. NXLog Agent’s Event Log for Windows input module accepts Windows QueryXML with <Suppress> elements, and an Exec block lets you drop or rewrite events on any field before sending.

Does NXLog Agent support the Logs Ingestion API and data collection rules?

Yes. The Microsoft Azure Logs Ingestion output module targets a DCR by its immutable ID and a named stream, and authenticates with an Entra ID application using a client secret or a certificate.

Will filtering break Microsoft’s built-in analytics rules?

It can, if you drop an event field a rule depends on. Review your rules and hunting queries before each change, pilot on a subset of agents, and re-test detections after deployment.

NXLog Platform is an on-premises solution for centralized log management with
versatile processing forming the backbone of security monitoring.

With our industry-leading expertise in log collection and agent management, we comprehensively
address your security log-related tasks, including collection, parsing, processing, enrichment, storage, management, and analytics.

Start free Contact us
  • Microsoft Sentinel
  • Telemetry pipeline management
  • Log noise
Share

Facebook Twitter LinkedIn Reddit Mail
Related Posts

Making the most of Windows Event Forwarding for centralized log collection in 2026
7 minutes | July 8, 2026
DNS Log Collection on Windows
9 minutes | May 28, 2020
Enterprise IIS log analysis software: top tools, use cases, and NXLog Agent integration
17 minutes | May 7, 2026

Stay connected:

Featured posts

Announcing NXLog Platform 1.15
October 8, 2026
Announcing NXLog Platform 1.14
August 19, 2026
Announcing NXLog Platform 1.13
June 9, 2026
Enterprise IIS log analysis software: top tools, use cases, and NXLog Agent integration
May 7, 2026
Announcing NXLog Platform 1.12
April 21, 2026
How to visualize telemetry data flow and volume with NXLog Platform
March 23, 2026
Security dashboards go dark: why visibility isn't optional, even when your defenses keep running
February 26, 2026
Building a practical OpenTelemetry pipeline with NXLog Platform
February 25, 2026
Announcing NXLog Platform 1.11
February 23, 2026
Adopting OpenTelemetry without changing your applications
February 10, 2026
Linux security monitoring with NXLog Platform: Extracting key events for better monitoring
January 9, 2026
2025 and NXLog - a recap
December 18, 2025
Announcing NXLog Platform 1.10
December 11, 2025
Announcing NXLog Platform 1.9
October 22, 2025
Gaining valuable host performance metrics with NXLog Platform
September 30, 2025
Security Event Logs: Importance, best practices, and management
July 22, 2025
Enhancing security with Microsoft's Expanded Cloud Logs
June 10, 2025

Categories

  • ANNOUNCEMENT
  • COMPARISON
  • COMPLIANCE
  • DEPLOYMENT
  • SECURITY
  • SIEM
  • STRATEGY
  • Products
  • NXLog Platform
  • NXLog Agent
  • NXLog Community Edition
  • Integration
  • Professional Services
  • Licensing
  • Plans
  • Resources
  • Documentation
  • Blog
  • White Papers
  • Videos
  • Webinars
  • Case Studies
  • Community Program
  • Community Forum
  • Compare NXLog Platform
  • Partners
  • Find a Reseller
  • Partner Program
  • Partner Portal
  • About NXLog
  • Company
  • Careers
  • Support Portals
  • Contact Us

Follow us

LinkedIn Facebook YouTube Reddit
logo

© Copyright NXLog Ltd.

Privacy Policy • General Terms of Business