stats
stats
Aggregate data using statistical functions. Group results by one or more fields to analyze patterns and calculate metrics.
Description
The stats command produces aggregate statistics from your search results. It calculates values across events and optionally groups them by specified fields. This is one of the most powerful commands for data analysis, enabling you to count events, sum values, calculate averages, and more.
When you use stats, the output replaces individual events with aggregated rows. Each row represents either the entire dataset (if no grouping) or a unique combination of grouped field values.
Syntax
... | stats <function>([field]) [as <alias>] [, <function>([field]) [as <alias>] ...] [by <field> [, <field> ...]]Required Arguments
function
One or more aggregation functions to calculate. See Aggregation Functions below.
Optional Arguments
as
Syntax: as <alias>
Description: Rename the output field for an aggregation.
Example: count() as total_events
by
Syntax: by <field> [, <field> ...]
Description: Group results by one or more fields. Creates a separate row for each unique combination of field values.
Example: by src_ip, dest_port
Aggregation Functions
count()
Count the number of events.
* | stats count()
* | stats count() as total
* | stats count() by userdc(field)
Count distinct (unique) values of a field.
* | stats dc(src_ip) as unique_ips
* | stats dc(user) by dest_hostsum(field)
Sum numeric values of a field.
* | stats sum(bytes) as total_bytes
* | stats sum(bytes) by src_ipavg(field)
Calculate average (mean) of numeric values.
* | stats avg(response_time) as avg_response
* | stats avg(bytes) by protocolmin(field)
Find minimum value.
* | stats min(response_time) as fastest
* | stats min(timestamp) as first_seen by src_ipmax(field)
Find maximum value.
* | stats max(bytes) as largest_transfer
* | stats max(timestamp) as last_seen by usermedian(field)
Calculate median value.
* | stats median(response_time) by endpointpercentile(field, N)
Calculate Nth percentile (0-100).
* | stats percentile(response_time, 95) as p95
* | stats percentile(bytes, 50) as median_bytesstdev(field)
Calculate standard deviation.
* | stats stdev(response_time) as response_variancevar(field)
Calculate variance.
* | stats var(bytes) by protocolrange(field)
Calculate range (max - min).
* | stats range(response_time) as time_spreadfirst(field)
Return first value encountered.
* | stats first(message) by userlast(field)
Return last value encountered.
* | stats last(status) by session_idearliest(field)
Return earliest timestamp value.
* | stats earliest(timestamp) as first_occurrencelatest(field)
Return latest timestamp value.
* | stats latest(timestamp) as last_occurrencevalues(field)
Return array of unique values.
* | stats values(dest_port) by src_iplist(field)
Return array of all values (including duplicates).
* | stats list(action) by usermode(field)
Return most frequently occurring value.
* | stats mode(status) by endpointperc95(field)
Shorthand for percentile(field, 95). Returns the 95th percentile value.
* | stats perc95(response_time) as p95 by endpoint
* | stats perc95(bytes) by src_ipsparkline(field)
Collect values into an array, producing inline mini time-series data. Useful for visualizing trends within grouped results. Can also be used without parentheses or a field argument alongside other aggregations.
* | stats sparkline(bytes) as trend, count() by src_ip
* | stats sparkline count by src_ip
* | chart sparkline(response_time) by endpointExamples
Count all events
* | stats count()Returns total number of events in the time range.
Count events by field
action=login | stats count() by userShows login attempts per user.
Multiple aggregations
* | stats count() as requests,
sum(bytes) as total_bytes,
avg(response_time) as avg_time
by src_ipCalculates multiple metrics grouped by source IP.
Distinct count analysis
* | stats dc(src_ip) as unique_sources,
dc(dest_port) as unique_ports,
count() as total_eventsAnalyzes diversity of sources and ports.
Find outliers with percentiles
* | stats percentile(response_time, 50) as median,
percentile(response_time, 95) as p95,
percentile(response_time, 99) as p99
by endpointIdentifies slow endpoints using percentile analysis.
Multi-level grouping
* | stats count() as events,
sum(bytes) as bytes
by src_ip, dest_port, protocolGroups by multiple dimensions for detailed analysis.
Time-based aggregation
* | stats min(timestamp) as first_seen,
max(timestamp) as last_seen,
count() as occurrences
by file_hashTracks when files were first and last observed.
Detect brute force attempts
action=login status=failure
| stats count() as failures,
dc(user) as unique_users,
values(user) as attempted_users
by src_ip
| where failures > 10Identifies IPs with excessive failed login attempts.
Analyze data transfer patterns
* | stats sum(bytes_in) as inbound,
sum(bytes_out) as outbound,
sum(bytes_in + bytes_out) as total
by src_ip
| eval ratio = outbound / inbound
| where ratio > 10Finds hosts with unusual upload/download ratios.
Session analysis
* | stats count() as requests,
earliest(timestamp) as session_start,
latest(timestamp) as session_end,
dc(endpoint) as unique_endpoints
by session_idSummarizes user session activity.
Usage Notes
Performance: stats is highly efficient as it reduces data volume. Always prefer aggregation over returning raw events when possible.
Grouping: You can group by up to 10 fields, but performance decreases with high cardinality combinations.
Null values: Fields with null values are grouped together. Use fillnull before stats if you need different behavior.
Memory: Aggregations with very high cardinality (millions of unique groups) may consume significant memory.
Order: Results are not ordered by default. Use sort after stats to order output.
Related Commands
- streamstats - Calculate running statistics without aggregating
- chart - Alias for stats, used for visualization
- timechart - Time-based aggregation with automatic bucketing
- where - Filter aggregated results
- sort - Order aggregated results