1.2 The timechart Command & Time-Series Visualizations
Key Takeaways
- The timechart command is a specialized transforming command that automatically bins events along the internal _time field as the implicit primary X-axis dimension.
- Unlike chart (which supports up to two split-by fields), timechart allows at most ONE split-by field via the by clause because _time is already locked as the row dimension.
- Chronological time buckets can be explicitly configured using `span=<interval>` (e.g., `span=5m`, `span=1h`, `span=1d`) or `bins=<N>`; if omitted, Splunk dynamically selects an optimal span based on the search time window.
- By default, timechart enforces continuous time (`cont=true`), ensuring that time buckets with zero events are included as empty intervals to preserve chronological scale integrity.
- Built-in rate normalization functions (`per_second()`, `per_minute()`, `per_hour()`, `per_day()`) convert metric totals into standardized rates regardless of the underlying bucket span length.
1.2 The timechart Command & Time-Series Visualizations
Time-series analysis is the cornerstone of operational intelligence and security monitoring in Splunk. While the general-purpose chart command allows any categorical field to serve as the row dimension, the timechart command is purpose-built to aggregate metrics across time. It automatically groups events into chronological buckets using the internal _time timestamp field. Understanding how timechart manages bucket spans, enforces split-by limits, normalizes rates, and handles continuous timelines is essential for building robust dashboards and excelling on the Splunk Core Certified Power User exam.
1. The Architecture of timechart
Under the hood, timechart is an optimized, native C++ composite transforming command. It combines three distinct operations into a single high-performance pipeline stage:
- Temporal Binning: Discretizing timestamps into uniform intervals using the
bin(orbucket) command on_time. - Statistical Aggregation: Calculating summary metrics across buckets and dimensions using
stats. - 2D Tabular Formatting: Pivoting secondary dimensions into wide series columns using
chart.
+-------------------------------------------------------------------------------------+
| The `timechart` Execution Equivalence Model |
+-------------------------------------------------------------------------------------+
| Native Query: |
| `... | timechart span=1h avg(cpu_usage) by host` |
| |
| Is functionally equivalent to the manual pipeline: |
| `... | bin _time span=1h` |
| ` | stats avg(cpu_usage) as avg_cpu by _time, host` |
| ` | chart avg_cpu over _time by host` |
+-------------------------------------------------------------------------------------+
Why Use Native timechart?
- Engine Optimization: Native
timechartexecutes significantly faster and consumes far less memory on the Search Head and Indexers than manually chainingbin,stats, andchart. - Automatic Continuity (
cont=true): It automatically fills gaps in time where zero events occurred, preventing false slope drops in line charts. - Rate Function Support: It provides specialized rate functions like
per_hour()andper_minute()that dynamically normalize metrics to fixed time units.
2. The Single Split-By Field Rule
A fundamental architectural rule that appears on nearly every Splunk Power User exam is the split-by limit in timechart:
chartsupports up to two split-by fields (over <field1> by <field2>orby <field1>, <field2>).timechartsupports at most ONE split-by field via thebyclause because the primary row dimension is always implicitly locked to_time.
# VALID TIMECHART EXAMPLES:
index=web | timechart count
index=web | timechart span=1h avg(bytes) as avg_bytes
index=web | timechart span=15m count by status
index=web | timechart span=1d sum(bytes) as total_bytes by host
# INVALID TIMECHART EXAMPLES (SYNTAX ERRORS):
index=web | timechart count by host, status <-- ERROR: More than 1 split-by field!
index=web | timechart count over _time by host <-- ERROR: 'over' clause not allowed!
What If You MUST Split by Two Fields Over Time?
If you need to analyze metrics broken down by time AND two additional categorical fields (e.g., _time, host, AND status), you cannot use timechart. You must use bin followed by stats:
index=web sourcetype=access_combined
| bin _time span=1h
| stats count by _time, host, status
This produces a flat, multi-column table containing all three dimensions.
3. Controlling Time Buckets: span vs. bins
When grouping events into time intervals, you can explicitly configure bucket sizes using the span argument, constrain the total bucket count with bins, or allow Splunk to determine the span automatically.
Explicit Time Intervals (span)
The span argument sets a fixed duration for each time bucket. Splunk SPL supports the following time unit abbreviations:
| Unit Abbreviation | Temporal Unit | Example Usage | Description |
|---|---|---|---|
us / ms | Microseconds / Milliseconds | span=500ms | High-frequency telemetry and sub-second metrics |
s / sec | Seconds | span=30s | Real-time streaming monitoring and short spikes |
m / min | Minutes | span=5m, span=15m | Standard operational application and web monitoring |
h / hr | Hours | span=1h, span=4h | Daily trends, server load, and traffic patterns |
d / day | Days | span=1d, span=7d | Weekly reporting, capacity planning, and SLA tracking |
w / week | Weeks | span=1w | Long-term macro trends and cyclical analysis |
mon / month | Calendar Months | span=1mon | Monthly billing, compliance, and growth summaries |
y / yr | Calendar Years | span=1y | Multi-year archival analysis |
[!WARNING] Syntax Trap: Notice that
1mrepresents 1 minute, while1monrepresents 1 month. Usingspan=1mon a 1-year search will attempt to create over 525,600 buckets, causing massive memory overhead or search truncation!
Constraining Bucket Counts with bins
Instead of specifying a fixed span length, you can request an approximate number of time buckets using bins=<integer>:
index=web
| timechart bins=50 count by status
Splunk calculates the total duration of the search time window, divides it by 50, and rounds to the nearest sensible time unit (e.g., 5 minutes, 1 hour, 1 day).
Automatic Span Calculation
When neither span nor bins is defined, Splunk automatically selects an optimal span based on the search time window selected in the Time Range Picker and the screen resolution of the browser:
- Search Range: Last 15 minutes -> Auto Span:
10 secondsor30 seconds - Search Range: Last 24 hours -> Auto Span:
30 minutesor1 hour - Search Range: Last 7 days -> Auto Span:
1 houror4 hours - Search Range: Last 30 days -> Auto Span:
1 day
4. Single-Series vs. Split-By Timecharts
The structure of the output table depends directly on whether a by clause is specified.
Scenario A: Single-Series Timechart (No by Clause)
index=web
| timechart span=1h count as request_count, avg(response_time) as avg_latency
Output Data Structure:
+---------------------+---------------+-------------+
| _time | request_count | avg_latency |
+---------------------+---------------+-------------+
| 2026-08-24 00:00:00 | 12450 | 142.5 |
| 2026-08-24 01:00:00 | 8320 | 118.2 |
| 2026-08-24 02:00:00 | 4100 | 95.8 |
+---------------------+---------------+-------------+
In a single-series timechart, each aggregation function forms its own column. This is ideal for dual Y-axis charts (plotting count on Left Y-Axis and latency on Right Y-Axis).
Scenario B: Multi-Series Split-By Timechart (With by Clause)
index=web
| timechart span=1h count by status
Output Data Structure:
+---------------------+-------+-------+-------+-------+-------+
| _time | 200 | 301 | 404 | 500 | OTHER |
+---------------------+-------+-------+-------+-------+-------+
| 2026-08-24 00:00:00 | 11800 | 450 | 180 | 20 | 0 |
| 2026-08-24 01:00:00 | 7900 | 310 | 95 | 15 | 0 |
| 2026-08-24 02:00:00 | 3950 | 110 | 35 | 5 | 0 |
+---------------------+-------+-------+-------+-------+-------+
When a by clause is added, distinct values of that field form individual series columns, enabling stacked area, stacked column, or multi-line graphs.
5. Timeline Continuity: The cont Argument
In standard statistical operations, if no events match a search for a specific time interval, that interval produces no output. In a time-series graph, omitting missing time intervals causes the X-axis to compress, distorting the perception of time.
To prevent this, timechart defaults to cont=true (continuous):
cont=true(Default): Splunk generates a continuous timeline spanning the entire search window. Missing time buckets are included withnullor0values.cont=false: Splunk suppresses empty time buckets, returning rows only for intervals containing actual matching event data.
Continuous Timeline (cont=true, Default):
+---------------------+-------+
| _time | count |
+---------------------+-------+
| 2026-08-24 08:00:00 | 450 |
| 2026-08-24 09:00:00 | 0 | <-- Preserves 09:00 gap on X-axis
| 2026-08-24 10:00:00 | 520 |
+---------------------+-------+
Non-Continuous Timeline (cont=false):
+---------------------+-------+
| _time | count |
+---------------------+-------+
| 2026-08-24 08:00:00 | 450 |
| 2026-08-24 10:00:00 | 520 | <-- 09:00 bucket is completely omitted
+---------------------+-------+
When to Use cont=false:
When analyzing sparse, sporadic datasets (such as critical security alerts or infrequent cron errors) where 99% of time buckets are empty and you only want to inspect active event windows in a tabular report.
6. Rate Normalization Functions: per_minute(), per_hour(), per_second()
A critical challenge in dashboard engineering occurs when users change the dashboard time range. If a dashboard panel aggregates requests using timechart count with auto-span:
- Over a 1-hour search, the span might be
1 minute(e.g., 50 requests per bucket). - Over a 24-hour search, the span might be
1 hour(e.g., 3,000 requests per bucket).
To the end user, the metric appears to skyrocket from 50 to 3,000 simply because the bucket size increased!
To display consistent, normalized rates regardless of the underlying bucket span, Splunk provides built-in rate functions:
| Rate Function | Normalization Base | Mathematical Formula |
|---|---|---|
per_second(field) or per_second(count) | Standard 1-second rate | Value = (Metric / Span Seconds) * 1 |
per_minute(field) or per_minute(count) | Standard 60-second rate | Value = (Metric / Span Seconds) * 60 |
per_hour(field) or per_hour(count) | Standard 3,600-second rate | Value = (Metric / Span Seconds) * 3600 |
per_day(field) or per_day(count) | Standard 86,400-second rate | Value = (Metric / Span Seconds) * 86400 |
Step-by-Step Calculation Example:
Suppose you run the following search over a 15-minute span (span=15m):
index=web
| timechart span=15m per_hour(count) as requests_per_hr by host
If web01 generates 600 requests during a specific 15-minute bucket:
- Bucket duration = 15 minutes = 900 seconds.
- Normalization factor for
per_hour= 3,600 seconds (or 60 minutes). - Calculation:
Rate = (600 requests / 15 minutes) * 60 minutes = 40 * 60 = 2,400 requests/hour
Even if the dashboard span changes to
span=5morspan=1h, the normalized metric remains directly comparable.
7. Advanced Inline eval in timechart
You can perform complex conditional aggregation and arithmetic transformations directly inside timechart:
index=web sourcetype=access_combined
| timechart span=1h
count(eval(status>=200 AND status<300)) as http_2xx,
count(eval(status>=400 AND status<500)) as http_4xx,
count(eval(status>=500)) as http_5xx,
eval(round(avg(bytes)/1024, 2)) as avg_kb_per_req,
eval(round(count(eval(status>=500)) / count * 100, 2)) as error_percentage
This single query generates five synchronized time-series metrics per hour, perfect for comprehensive service health monitoring panels.
8. Summary of Common Exam Pitfalls for timechart
- Two Split-By Fields: Never write
timechart count by host, status. It is an invalid syntax. Usebin _time | stats count by _time, host, statusinstead. - The
overClause: Never useoverin atimechartcommand (e.g.,timechart count over _time by host). Theoverkeyword is strictly forchart. - Minute vs. Month Spans: Remember that
span=1mis 1 minute, whilespan=1monis 1 month. - Continuous Timeline Defaults: Remember that
cont=trueis the default behavior, which preserves empty time buckets.
A Splunk search developer writes the following query to build a dashboard panel:
index=firewall action=blocked | timechart span=30m count over _time by src_ip, dest_ip
What will happen when this query is dispatched?
A monitoring query aggregates server errors using the following SPL command:
index=app | timechart span=10m per_hour(count) as err_per_hr
If a single 10-minute bucket contains 150 error events, what value will Splunk display for err_per_hr in that bucket?
An administrator wants to audit infrequent administrative logins that occur sporadically over a 90-day window. The search is:
index=auth user=admin action=login | timechart span=1d cont=false count
What is the exact effect of specifying cont=false?