August 25, 2026
Why Performance Matters
Well-optimized YARA-L rules evaluate efficiently at scale and keep detections current with your data.
Optimization Principles
- Filter early. Place
log_typeandevent_typefilters first to eliminate most events before aggregation. - Size your match window correctly. If
1hcaptures the behavior, do not use24h. - Avoid unbounded aggregations. Filter to a specific log type and event type before running
count_distinct. - Use data tables over inline lists. Table lookups are faster and easier to maintain.
Before: SLOW
rule slow_example {
meta:
severity = "HIGH"
events:
$e.principal.user.email_addresses = $user
$e.target.resource.name = $resource
match:
$user over 24h
outcome:
$resource_count = count_distinct($resource)
condition:
$e and $resource_count >= 100
}
After: FAST
rule fast_example {
meta:
severity = "HIGH"
events:
$e.metadata.log_type = "GCP_CLOUDAUDIT"
$e.metadata.event_type = "USER_RESOURCE_ACCESS"
$e.principal.user.email_addresses = $user
$e.target.resource.name = $resource
not $user in %system_accounts.email
match:
$user over 1h
outcome:
$resource_count = count_distinct($resource)
condition:
$e and $resource_count >= 50
}
(this rule will not compile without the data table system_accounts and column called email)
The fast version filters by log type and event type, excludes noise via data table, and cuts the window from 24h to 1h.
Checklist: Does every rule start with event_type filters? log_type is helpful and will speed up the process but we may want to aggregate across event_type across log_type, so this may not be an option. Is the match window the shortest that captures the behavior? Are inline lists replaced with data tables?
Here’s a table of some other areas to think about optimization:

