Splunk Cheatsheet
Splunk Cheatsheet
Search Processing Language reference: a base search filters, then each | pipes results into the next command. The Optimize section collects the SPL habits that keep searches fast — filter early, narrow fields, and lean on tstats.
Search fundamentals
Anatomy of a search: everything before the first pipe filters raw events (indexed, fast); each pipe transforms the result set.
# <base search / filters> | <command> | <command>
index=web sourcetype=access_combined status=500 earliest=-24h@h latest=now
| stats count AS errors BY host
| sort -errorsAlways pin index=, sourcetype=, and a time range in the base search. That is the single biggest factor in search speed.
Filtering & fields
| Command | Use |
|---|---|
| search … | Filter events; before the first pipe it is the indexed base search. |
| where expr | Filter with functions and field-to-field comparison. |
| fields f1 f2 | Keep only these fields; fields – f drops them. Do this early. |
| table f1 f2 | Render as a table in field order. |
| rename f AS g | Rename a field (quote names with spaces). |
| dedup f | Keep the first event per unique value of f. |
| sort -f / sort +f | Descending / ascending; sort num(f) forces numeric. |
| head N / tail N | First / last N results. |
| reverse | Reverse the current result order. |
Aggregation
# Aggregate ... | stats count, avg(bytes) AS avg_bytes, dc(user) AS users BY host # Time series ... | timechart span=1h count BY status # Pivot: values OVER one dim, split BY another ... | chart count OVER host BY status # Ranked values ... | top limit=10 uri ... | rare user # Add aggregate back onto each event / running calc ... | eventstats avg(bytes) AS avg BY host ... | streamstats count AS running BY session
| Function | Returns |
|---|---|
| count / count(f) | Event count / non-null count of f. |
| dc(f) | Distinct (unique) count. |
| sum / avg / min / max / median | Standard numeric aggregates. |
| perc95(f) | 95th percentile (any perc<n>). |
| values(f) / list(f) | Unique / all values as multivalue. |
| earliest(f) / latest(f) | Value at the earliest / latest _time. |
eval & calculated fields
| eval sev = case(status>=500,"error", status>=400,"warn", true(),"ok") | eval is_err = if(status>=500, 1, 0) | eval host = coalesce(host, "unknown") | eval kb = round(bytes/1024, 2) | eval target = src . ":" . port | eval tier = if(match(uri,"^/api/"), "api", "web")
| Function | Does |
|---|---|
| if(cond, a, b) | Ternary. |
| case(c1,v1, c2,v2, …) | First matching condition wins. |
| coalesce(a, b, …) | First non-null value. |
| round / floor / ceil(x, n) | Rounding. |
| lower / upper / trim / len | String helpers. |
| substr / replace(x, re, y) | Slice / regex replace. |
| split / mvindex / mvcount | Multivalue handling. |
| strftime / strptime(_time, fmt) | Epoch to string / string to epoch. |
| match(f, regex) / like(f, pat) | Regex / SQL-style match. |
Field extraction
# Inline regex with named captures | rex field=_raw "user=(?<user>\w+)\s+ip=(?<ip>\d+\.\d+\.\d+\.\d+)" # Redact in place with sed mode | rex field=email mode=sed "s/@.*/@***/g" # Parse structured JSON / XML | spath input=payload path=user.id output=uid # Auto key=value extraction | extract pairdelim="," kvdelim="="
rex vs extract rex is one-off regex at search time; field extractions defined in props/transforms apply automatically to every matching event.
Lookups
# Enrich events from a lookup table | lookup geo_ip ip AS src_ip OUTPUT country, city # Read a lookup as the event source | inputlookup assets.csv # Persist search results into a lookup (build / refresh) ... | outputlookup assets.csv
Setup Register the file under Settings → Lookups (or transforms.conf); automatic lookups attach the fields at search time without the explicit command.
Time
| Token | Meaning |
|---|---|
| earliest=-24h latest=now | Relative window. |
| -7d@d | 7 days ago, snapped to midnight. |
| @h @d @w @mon | Snap to start of hour / day / week / month. |
| _time | The event timestamp field. |
| bin _time span=5m | Bucket time (alias: bucket). |
| relative_time(now(), “-1d@d”) | Compute a time in eval. |
# Snapped relative range in the base search = cache-friendly + fast
index=web earliest=-7d@d latest=@d
| bin _time span=1h
| stats count BY _time, status
| eval day = strftime(_time, "%Y-%m-%d")Combine searches
# join (subsearch-bound, capped ~50k rows) - use sparingly ... | join type=inner user [ search index=identity | fields user, dept ] # append rows / add columns side-by-side ... | append [ search index=other | stats count AS other_count ] ... | appendcols [ search index=other | stats avg(x) AS avg_x ] # transaction: stitch related events into one ... | transaction session maxspan=30m maxpause=5m # union two datasets | union [ search index=a ] [ search index=b ]
Scale tip For correlation, prefer stats … BY key over join / transaction — it is distributable and avoids the subsearch row cap.
Accelerated & metadata
# tstats over indexed / accelerated fields - skips raw events, very fast | tstats count WHERE index=web BY host, sourcetype # metadata: hosts / sources / sourcetypes for an index | metadata type=sourcetypes index=web # query an accelerated data model | tstats count FROM datamodel=Web BY Web.status
Why fast tstats reads the time-series index (.tsidx) and accelerated summaries instead of decompressing raw events, often 10–100x quicker on large volumes.
Format & output
| Command | Does |
|---|---|
| fields f1 f2 | Select fields (also prunes data down the pipe). |
| table f1 f2 | Ordered table layout. |
| rename f AS “Nice Name” | Human-friendly column labels. |
| fillnull value=0 | Replace nulls (all fields, or named ones). |
| foreach x* [ eval <<FIELD>>=… ] | Apply an expression across matching fields. |
| addtotals / addcoltotals | Row / column totals. |
| mvexpand / makemv / nomv | Multivalue reshaping. |
| convert ctime(_time) | Type / time conversions. |
Splunk CLI
| Command | Does |
|---|---|
| splunk start | stop | restart | Control the splunkd service. |
| splunk status | Is it running. |
| splunk add index NAME | Create an index. |
| splunk list index | List indexes. |
| splunk add oneshot FILE -index NAME | One-off file ingest. |
| splunk search ‘index=web | stats count’ -earliest_time -1h | Run SPL from the shell. |
| splunk btool inputs list –debug | Show effective config + which file set it. |
| splunk apply cluster-bundle | Push config to indexer cluster peers. |
Path Commands live in $SPLUNK_HOME/bin/splunk and prompt for admin credentials.
Optimize
SPL performance, highest payoff first. Most wins come from moving work left (earlier) and up (onto indexers).
| Area | Lever |
|---|---|
| Filter | Pin index=, sourcetype=, and a snapped time range in the base search. |
| Fields | Add | fields f1 f2 right after the base search to shrink what flows down the pipe. |
| Accelerate | Use tstats and accelerated data models instead of raw search where possible. |
| Correlate | Prefer stats BY key over join / transaction (distributable, no row cap). |
| Matching | Avoid leading wildcards (*term); they cannot use the index. Use TERM() for exact segments. |
| Order | Put streaming commands (eval, rex, fields) before transforming ones (stats) so they run on indexers. |
| Subsearch | Return only needed fields; mind the ~50k row / 60s subsearch limits. |
| Mode | Use Fast or Smart mode; Verbose computes every field and is slow. |
| Late & costly | Apply dedup / sort after stats has already reduced the volume. |