How do we optimise WEF event query XML structures to reduce client CPU usage

Fath Swift 0 Reputation points
2026-08-20T14:50:06.54+00:00

We are facing a critical challenge on one of our absolutely vital WEF collector servers, which handles massive volumes of forwarded events. The server is simply being brought to its knees with severe processing delays due to client subscriptions running overly complex, un-indexed XPath queries.

I have been troubleshooting and monitoring the subscriptions in real time, which clearly revealed that client endpoints are suffering from significant CPU spikes when evaluating these un-indexed event queries. As we have a large estate of enterprise machines forwarding events under these subscriptions, I would like to ask what the most effective and direct method is to properly optimise the WEF query XML structures, so we can reduce client CPU overhead and eliminate these forwarding delays?

Windows for business | Windows 365 Business
0 comments No comments

1 answer

Sort by: Most helpful
  1. Marcin Policht 111.2K Reputation points MVP Volunteer Moderator
    2026-08-20T15:04:56.22+00:00

    Start by replacing complex contains(), starts-with(), and body-level text parsing in WEF XPath filters with simple, structural, channel-based, and Event ID-based filtering. WEF evaluates subscription queries on the local endpoint before events are forwarded. If a query searches broadly through EventData or performs string operations against event contents, the endpoint has to perform substantially more work for every matching log stream. The goal is to eliminate unnecessary processing at the client rather than attempting to solve the problem solely on the collector.

    Explicitly restrict each Select statement to the appropriate channel and Event ID. For example, instead of searching every Security event for a particular string within EventData, anchor the query on the specific Event ID first. Avoid functions such as contains() and starts-with() wherever possible, and replace them with exact Event ID matches or specific structural attributes. If an Event ID is required but particular instances generate excessive noise, use <Suppress> clauses to exclude those events at the endpoint before they are forwarded. This can substantially reduce both endpoint processing and the volume sent to the collector.

    For example, an inefficient query would be:

    <QueryList>
      <Query Path="Security">
        <Select Path="Security">*[System[EventID=4688] and EventData[Data[name='NewProcessName'] and contains(., 'cmd.exe')]]</Select>
      </Query>
    </QueryList>
    

    This requires additional string evaluation against the event data. A more efficient query, when all 4688 events are required, is:

    <QueryList>
      <Query Path="Security">
        <Select Path="Security">*[System[(EventID=4688)]]</Select>
      </Query>
    </QueryList>
    

    If you need to filter on a specific process name or command-line argument, consider collecting the relevant Event ID and performing the more expensive content filtering downstream in the SIEM or other analysis system. Also review the subscriptions for overlapping queries and unnecessary high-volume events.

    The key optimization is to make the endpoint do the minimum possible work: restrict the channel and Event ID first, avoid expensive string searches, suppress unnecessary events locally, and defer complex content analysis until after collection.


    If the above response helps answer your question, remember to "Accept Answer" so that others in the community facing similar issues can easily find the solution. Your contribution is highly appreciated.

    hth

    Marcin

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.