Query VictoriaLogs
Environment Setup
Read the project CLAUDE.md for VL_DEV_URL and VL_PROD_URL values. Default to DEV unless user specifies production.
CRITICAL: Time Range Limits
NEVER query more than 3 hours without explicit _time filter. The server will crash on wide time ranges.
- Default: use
_time:5mto_time:1hfor recent logs - Max safe range: 3 hours. NEVER exceed 3 days under any circumstances.
- Always include
_timefilter in every query — no exceptions.
When User Knows Only a Date (Not Exact Time)
If the user says "check logs from March 20" but doesn't know the exact time, use a two-step approach:
Step 1: Find the time range using /select/logsql/hits — lightweight, returns only counts:
curl -s "$VL_URL/select/logsql/hits" \
-H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' \
--data-urlencode "query=SEARCH_TERM" \
-d 'step=3600000ms' \
-d 'start=2026-03-20T00:00:00Z' \
-d 'end=2026-03-20T23:59:59Z' \
--insecure
This returns hit counts per hour — find which hours have data.
Step 2: Query only the narrow time range identified from Step 1:
curl -s "$VL_URL/select/logsql/query" \
-H 'Accept: application/stream+json' \
-H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' \
--data-urlencode "query=SEARCH_TERM" \
-d 'limit=500' \
-d 'start=2026-03-20T14:00:00Z' \
-d 'end=2026-03-20T15:00:00Z' \
--insecure
Always follow this pattern: hits first to locate, then query to fetch.
How to Query
Use curl directly via Bash tool. Always use --insecure flag and POST with application/x-www-form-urlencoded;charset=UTF-8.
Query Logs
curl -s "$VL_URL/select/logsql/query" \
-H 'Accept: application/stream+json' \
-H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' \
--data-urlencode "query=_time:5m error" \
-d 'limit=500' \
--insecure
Hit Counts (histogram) — use to locate time ranges
curl -s "$VL_URL/select/logsql/hits" \
-H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' \
--data-urlencode "query=_time:1h error" \
-d 'step=60000ms' \
--insecure
Stats Query
curl -s "$VL_URL/select/logsql/stats_query" \
-H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' \
--data-urlencode "query=_time:5m error | stats count() as errors" \
--insecure
Discover Fields/Streams
# Field names
curl -s "$VL_URL/select/logsql/field_names" --data-urlencode "query=_time:5m *" --insecure
# Field values
curl -s "$VL_URL/select/logsql/field_values" --data-urlencode "query=_time:5m *" -d 'field=level' --insecure
# Streams
curl -s "$VL_URL/select/logsql/streams" --data-urlencode "query=_time:5m *" --insecure
LogsQL Quick Reference
Filters
error # word in _msg
"connection refused" # phrase
{app="nginx"} # stream filter
_time:5m # last 5 minutes
field:value # field filter
field:re("pattern") # regexp
q1 AND q2 / q1 OR q2 / NOT q # logical
Pipes
| fields f1, f2 # keep fields
| unpack_json # parse JSON
| stats by (field) count() as c # aggregate
| sort by (field desc) # sort
| limit 10 # limit
| filter field > 100 # post-filter
| top 10 by (path) # top N
| extract_regexp "(?P<ip>...)" # extract via regex
Stats Functions
count(), sum(f), avg(f), min(f), max(f), median(f), quantile(0.95, f), rate(), count_uniq(f), uniq_values(f)
For full LogsQL syntax: read references/logsql-reference.md
For full HTTP API details: read references/http-api.md
Best Practices
- ALWAYS include
_timefilter — server crashes without it. Default to_time:5mor_time:1h. - Max 3 hours per query. If broader search needed, use hits endpoint first to locate the right window.
- Unknown time? Hits first, query second. Use
/select/logsql/hitswith 1h step to scan a day, then query only the relevant hours. - Place fastest filters (word, phrase) first, slowest (regexp) last
- Use
limitto avoid overwhelming output — start with 100-500 - Use
| unpack_jsonwhen logs are JSON-structured - Use
| collapse_numsto group similar error messages - Use
| stats by (_stream) count()to find noisiest services - Pipe output through
jqfor readability when needed