Skip to content

Splunk → SonQL

A translation guide for Splunk users. Every SonQL command name below was checked against the shipped ANTLR grammars — Splv1Lexer.g4 / Splv1Parser.g4 (the search1 engine) and SplLexer.g4 / SplParser.g4 (the search2 engine) — not carried over from a document. Where a command’s behavior is noted, it was measured against a live instance in Searching logs with SonQL.

The short version. Most of the language is the same words. The traps worth knowing on day one: headlimit, tablefields, sort takes a by clause and sorts descending by default (Splunk ascends), and SonQL has two engines that disagree on a handful of commands.

Splunk SonQL note
stats count() by service stats count() as n by service count(), avg(), sum(), min(), max() work; an unknown function errors (no match function) rather than returning an empty column
eval duration = end - start eval duration = end - start
where status = 500 where status = 500
rex field=_raw "…" rex field=_raw "…"
fields host source fields host source also does what Splunk’s table does (below)
rename src as dst rename src as dst
dedup host, source dedup host, source
bin _time span=1d bin _time span=1d spelled bin, same as Splunk
timechart count() span=1d timechart count() span=1d
chart avg(x) by host chart avg(x) by host same on both since 14 Aug 2026
eventstats avg(x) by host eventstats avg(x) by host
transaction host maxspan=1m transaction host maxspan=1m works on both engines (15 Aug 2026); search2 carries the joined member fields as multivalue columns — the added fields are _event_count/_duration on search2, eventcount/duration_second on search1
lookup t a OUTPUT b lookup t a OUTPUT b needs a lookup table to exercise
inputlookup t / outputlookup t same
makeresults makeresults
makemv delim="," field makemv delim="," field
replace "a" with "b" in f replace "a" with "b" in f
convert ctime(x) convert ctime(x)
iplocation ip iplocation ip
accum x accum x
addtotals addtotals
streamstats count() by host streamstats count() by host by is required — the engine answers “expected one of ‘by’”
Splunk SonQL note
head 20 limit 20 head is not a command — it errors (unknown command [head] … did you mean 'limit'?)
table a b fields a b there is no table
sort -errors sort by errors desc sort takes a by; defaults to descending, Splunk ascends. A size goes first: sort 10 by errors desc
tail 20 sort by _time desc | limit 20 no tail; this returns newest-first
spath input=x path=y jsonpath input=x path=y
xpath … xmlpath …
join type=inner host [subsearch] join type=inner on=host [search …] the subsearch is a bracketed query
append [subsearch] append [search …]
search index=… search index=… or search2 index=… two engines (below); index= is aliased to repo= in a search predicate

Checked against both grammars; none of these Splunk commands exist in SonQL.

Splunk SonQL equivalent
appendcols not supported
union not supported
map not supported
gentimes makeresults (generates a row, not a time series)
xyseries not supported
untable not supported
fillnull patch with eval
delta streamstats + eval on the previous value
trendline not supported
predict forecast (search2), or fit / apply

search2-only commands (no search1 equivalent)

Section titled “search2-only commands (no search1 equivalent)”

mstats, msearch, logcluster, rate, fit / apply, forecast, anomalies, outliers, unnest, topseries, show tag/metric names, explain.


The full detail, with the measurements, is in Searching logs with SonQL. The three worth internalizing before you migrate anything:

  1. A . does not break a token by default. NullPointerException does not match an event containing java.lang.NullPointerException. Add . to the index’s word-breaker list (affects new data), or search *NullPointerException.
  2. sort is descending by default, the reverse of Splunk, and it is silent — a migrated query returns the reverse order, not an error.
  3. top / rare need a count on search2. top 5 service, not top service. mvexpand and mvcombine work on both engines. mvexpand limit=<n> works on both, and both spellings are accepted — Splunk’s mvexpand <field> limit=<n> and the options-first mvexpand limit=<n> <field>. mvcombine groups by the searched repo’s real columns (not the per-event identity fields), so events that differ only in _time/_raw merge. Pin the engine in anything you save, because the global Default Search Engine setting decides it otherwise.