Skip to content

Environment Variables

Joel Natividad edited this page Oct 27, 2026 · 32 revisions

Environment Variables

Tier: Advanced

Note

Canonical reference: docs/ENVIRONMENT_VARIABLES.md. 85+ variables total — this page groups them by purpose and links the canonical reference for definitions.

Run qsv --envlist to see all active qsv-relevant env vars in your environment.

qsv also supports .env files. See docs/ENVIRONMENT_VARIABLES.md#env-file-support for the lookup order.

Quick reference — the most-used vars

Variable What it does
QSV_AUTOINDEX_SIZE Auto-create .idx for files > N bytes (and auto-refresh stale ones)
QSV_STATSCACHE_MODE auto (default), force (auto-create cache), or none
QSV_MAX_JOBS Cap the number of parallel jobs
QSV_LLM_BASE_URL, QSV_LLM_APIKEY, QSV_LLM_MODEL describegpt LLM config
QSV_DEFAULT_DELIMITER Fallback delimiter for stdin, unrecognized extensions, and output
QSV_SNIFF_DELIMITER Auto-detect the input delimiter
QSV_LOG_LEVEL, QSV_LOG_DIR Logging

I/O & format

  • QSV_DEFAULT_DELIMITER — the delimiter used when neither --delimiter nor a .csv/.tsv/.tab/.ssv extension sets one: stdin, other extensions, and output written to stdout. Default ,. It does not override --delimiter or a recognized extension. Since 26.0.0 (#4819), excel, jsonl and readstat follow it on output too: if you set it only to read semicolon files, they now write semicolons to stdout as well. Pass --delimiter , to keep commas.
  • QSV_SNIFF_DELIMITER — auto-detect the input delimiter; takes precedence over extensions and QSV_DEFAULT_DELIMITER, but not over --delimiter.
  • Precedence, highest first: --delimiter → QSV_SNIFF_DELIMITER → file extension → QSV_DEFAULT_DELIMITER → ,.
  • Piped stdin is copied to a temp stdin.csv by commands that take several inputs. That copy is read with QSV_DEFAULT_DELIMITER, as stdin is, not with the comma its name implies (27.0.1). Commands that run qsv subprocesses on it, such as describegpt, moarstats and profile, pass its path down in QSV_STDIN_SPOOL, which qsv sets itself; don't set it by hand.
    • Exception: joinp, sqlp, scoresql and readstat always use tab for a .tsv/.tab path and semicolon for an .ssv path, whether reading it or writing it with --output, even when --delimiter is given.
  • QSV_SNIFF_PREAMBLE — detect the preamble rows above the header (a title or a "generated on" line) and skip them, so every command reads from the header; it also sniffs the delimiter. (27.0.1: it used to detect the rows and ignore them.)
    • Covers the Polars-based commands (sqlp, joinp, pivotp, to parquet, …) and the DuckDB queries of scoresql and describegpt too. Not covered: stdin and Polars SQL's read_csv() table function.
    • A file with a preamble is never read through its index, and qsv index still indexes the file as stored.
    • Stats caches and Polars schemas are kept apart for the two modes, so turning the env var on or off never reuses one built the other way. A schema of the rows past an N-line preamble is <file>.skip<N>.pschema.json.
  • QSV_NO_HEADERS — treat the first row as data, not headers
  • QSV_TOGGLE_HEADERS — invert header behavior
  • QSV_COMMENT_CHAR — skip lines starting with this character
  • QSV_OUTPUT_BOM — add a UTF-8 BOM to outputs (Excel-friendly on Windows)
  • QSV_RDR_BUFFER_CAPACITY — reader buffer size (default 128 KB)
  • QSV_WTR_BUFFER_CAPACITY — writer buffer size (default 512 KB)
  • QSV_SKIP_FORMAT_CHECK — skip MIME-type inference for inputs

Performance & memory

  • QSV_AUTOINDEX_SIZE — auto-create / refresh index for files > N bytes
  • QSV_MAX_JOBS — max parallel jobs (default: all logical CPUs)
  • QSV_MEMORY_CHECK — enable pre-check that the file fits before running memory-mode commands
  • QSV_FREEMEMORY_HEADROOM_PCT — reserve N% of free RAM (default 20)
  • QSV_STATS_CHUNK_MEMORY_MB — per-chunk memory limit in stats
  • QSV_FREQ_CHUNK_MEMORY_MB — per-chunk memory limit in frequency
  • QSV_FREQ_HIGH_CARD_THRESHOLD — absolute cardinality threshold for HIGH_CARDINALITY classification
  • QSV_FREQ_HIGH_CARD_PCT — percentage-of-rowcount cardinality threshold
  • QSV_NO_ALLOC_TUNING — disable qsv's automatic jemalloc tuning (jemalloc builds only). By default qsv enables jemalloc background_thread purging where supported (Linux) at no extra memory cost, and on platforms without it (e.g. macOS) retains freed pages more aggressively

See Performance Tuning for how these interact.

Cache config

  • QSV_STATSCACHE_MODE — auto / force / none

  • QSV_CACHE_DIR — directory for qsv's persistent caches (default ~/.qsv-cache). It holds:

    • lookup tables downloaded by luau (qsv_register_lookup), template and validate
    • geocode's Geonames index, and its OpenCage and Geoclient result caches
    • get's download cache
    • describegpt's tag vocabularies (its LLM completion cache is set separately by --disk-cache-dir, default ~/.qsv-cache/describegpt)
    • viz's Census boundary and population caches

    It takes precedence over the --cache-dir option of describegpt, geocode, get, luau, template and validate.

  • QSV_GET_PART_SIZE — get byte-range part size for parallel downloads (default 8 MiB)

  • QSV_GET_CONCURRENCY — get parallel range-download workers (default 4, clamped 1–64)

  • QSV_DISKCACHE_TTL_SECS — fetch / fetchpost / describegpt disk-cache TTL (default 28 days)

  • QSV_DISKCACHE_TTL_REFRESH — extend TTL on cache hit

  • QSV_REDIS_CONNSTR — Redis connection string for fetch cache (default redis://127.0.0.1:6379/1)

  • QSV_FP_REDIS_CONNSTR — Redis connection for fetchpost cache (default db 2)

  • QSV_DG_REDIS_CONNSTR — Redis connection for describegpt cache (default db 3)

  • QSV_REDIS_MAX_POOL_SIZE — Redis connection pool size

  • QSV_REDIS_TTL_SECS — Redis cache TTL

  • QSV_REDIS_TTL_REFRESH — extend Redis TTL on cache hit

See Stats Cache & Caching and HTTP & Web.

AI & LLM

  • QSV_LLM_BASE_URL — OpenAI-compatible LLM endpoint for describegpt
  • QSV_LLM_APIKEY — API key for the LLM
  • QSV_LLM_MODEL — model name (e.g. openai/gpt-oss-20b, google/gemma-4-31b)
  • QSV_DUCKDB_PATH — DuckDB binary path (enables DuckDB SQL in describegpt & scoresql)
  • QSV_TEST_DESCRIBEGPT — enable describegpt tests (requires LM Studio with openai/gpt-oss-20b)

See AI & Documentation.

Web & HTTP

  • QSV_TIMEOUT — timeout in seconds for fetch, fetchpost, geocode, sniff, validate, describegpt, template, sample, snappy, luau (default 30). viz has no --timeout option but honors this variable for its Census requests. apply and get have their own --timeout but do not read this variable.
  • QSV_USER_AGENT — custom User-Agent header (supports $QSV_VERSION, $QSV_TARGET, $QSV_BIN_NAME, $QSV_COMMAND placeholders)
  • QSV_CKAN_API — CKAN action API endpoint for ckan:// URL scheme
  • QSV_CKAN_TOKEN — CKAN access token (only required for private resources)
  • Plus standard HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, NO_PROXY. OS-level proxy configuration (macOS SystemConfiguration, Windows registry) is honored as well — in 23.0.1 and earlier by the full qsv binary only; New in 24.0.0: also by qsvlite, qsvdp and qsvmcp, which additionally decode responses by their Content-Type charset instead of lossy UTF-8

Geocoding

  • QSV_GEOIP2_FILENAME — MaxMind GeoLite2 binary database filename (default GeoLite2-City.mmdb)
  • QSV_GEOCODE_INDEX_FILENAME — custom Geonames index file
  • QSV_OPENCAGE_API_KEY — API key for the geocode opencage / opencagenow online geocoding subcommands (the --api-key flag, if given, takes precedence)
  • QSV_GEOCLIENT_API_KEY — NYC Geoclient subscription key for the geocode geoclient / geoclientnow subcommands (25.0.0, #4789). Get one free at https://api-portal.nyc.gov by subscribing to "Geoclient V2 User". --api-key takes precedence. qsv sends it as a request header, never in the URL. Not needed for a self-hosted Geoclient.
  • QSV_GEOCLIENT_API_URL — base URL of a self-hosted Geoclient, e.g. http://localhost:8080/geoclient/v2; no key is needed then (default https://api.nyc.gov/geoclient/v2; 25.0.0)

See Geospatial.

Visualization

All require the viz feature (bundled in the prebuilt qsv/qsvpy binaries and any all_features build).

  • QSV_VIZ_MAX_POINTS — max data points viz smart embeds per panel before uniform downsampling (default 150000)
  • QSV_VIZ_CDN — load the plotly.js runtime from its CDN (pinned to the embedded version) instead of inlining it; shrinks a smart dashboard by ~1.9 MB but requires network access when the page is viewed — intended for web-published charts. Governs only the plotly.js bundle; figure payloads still follow QSV_VIZ_NO_COMPRESS
  • QSV_VIZ_NO_DAEMON: when set, viz smart leaves the qsv-clientd bridge script out of the Data Schematic (same as --no-daemon-bridge; 27.0.1, #4848). The qsv-schematic-source provenance block is still embedded, but without the input fingerprint, which saves a full extra read of the input. See live mode
  • QSV_CLIENTD_PORT: the loopback port a schematic's bridge probes for qsv-clientd (default 14470; 27.0.1, #4848). It is read at render time, so set it when the daemon listens on a non-default port
  • QSV_VIZ_NO_COMPRESS — emit fully plain-text HTML (inline plotly.js and figures, decimal map arrays) instead of the default gzip+base64 payloads; larger output, but works on pre-2023 browsers and strict-CSP embeds and is greppable
  • QSV_VIZ_DICT_FRESH — set to 1 to force viz smart --dictionary infer to re-run the LLM: ignores an existing <stem>.schema.json sidecar and bypasses describegpt's completion cache, overwriting the sidecar on success. Without it, an existing sidecar is reused as-is (no LLM call) — which is what makes hand-tuning a dictionary stick
  • QSV_CENSUS_API_KEY — US Census Data API key, required by viz choropleth --denominator census (and the viz smart rate panel it drives) to fetch ACS population denominators. The Bureau redirects unkeyed requests to a "Missing Key" page rather than refusing them, so qsv asks for the key up front. Request a free one
  • QSV_VIZ_BOUNDARY_CACHE_TTL_DAYS — days a boundary set fetched by viz --geojson auto (Census TIGERweb polygons) stays fresh in the cache before re-fetching; within the TTL a repeated command makes no network request at all (default 30)
  • QSV_VIZ_DENOMINATOR_CACHE_TTL_DAYS — days a population denominator fetched by viz --denominator census stays fresh in the cache (default 30)
  • QSV_GEOJSON_SHORTCUTS — a JSON map of shortcut name → {path, id} so viz --geojson <name> resolves by name instead of a full path/URL; the shortcut's id sets --feature-id-key when you don't pass one. Used for region maps and point-in-polygon binning

Static image export (third-party)

These two are not QSV_* variables and do not appear in qsv --envlist — they are read directly by plotly_static, which backs viz static image export. They only matter when writing a chart to PNG/SVG/PDF/JPEG/WebP.

  • WEBDRIVER_PATH — full path to the chromedriver to render with. On 23.0.1 and earlier, you had to set it yourself whenever static export couldn't find a driver. New in 24.0.0: when unset, or not pointing at an executable file, qsv probes $WEBDRIVER_INSTALL_PATH, ~/.local/bin, your PATH, then (Unix only) /opt/homebrew/bin, /usr/local/bin and /usr/bin, and sets the variable to the first chromedriver it finds — which is what repairs prebuilt binaries, whose baked-in path points into the build machine's home directory (#4620). Firefox/geckodriver is not supported. The driver's MAJOR version must match your Chrome
  • BROWSER_PATH — full path to a Chrome/Chromium binary, when it isn't the system default

See Visualization.

Stats output config

  • QSV_STATS_STRING_MAX_LENGTH — truncate long min/max string values
  • QSV_STATS_SEPARATOR — separator for multi-value MODE/ANTIMODE/PERCENTILE cells (default |)
  • QSV_ANTIMODES_LEN — max characters when listing antimodes (default 100)

Date parsing

  • QSV_PREFER_DMY — parse dates as DMY instead of MDY (affects datefmt, frequency, joinp, moarstats, pivotp, sample, schema, sniff, stats, tojsonl)

Regex

  • QSV_REGEX_UNICODE — make search / searchset / replace unicode-aware (slower; default off)

Color / display

  • QSV_FORCE_COLOR — force color output even in CI / pipes
  • QSV_THEME — DARK or LIGHT (overrides terminal-bg detection)
  • QSV_TERMWIDTH — override detected terminal width

See Selection & Inspection → color.

Logging

  • QSV_LOG_LEVEL — error / warn / info / trace / debug (default off; qsvmcp defaults to info)
  • QSV_LOG_DIR — log file directory (auto-created if missing)
  • QSV_LOG_UNBUFFERED — write log lines synchronously
  • QSV_PROGRESSBAR — enable --progressbar on commands that support it
  • QSV_NO_UPDATE — disable qsv --update self-update version check
  • QSV_ERROR_FORMAT — set to json to end a failed run with one JSON line on stderr ({"error":{"kind","level","message","exit_code","command","qsv_version"}}) instead of free text; a no_match exit also gets a line. For programs driving qsv as a subprocess; qsv-client sets it for you (25.0.0)

See docs/Logging.md.

Polars-specific

Polars commands respect Polars's own env vars:

  • POLARS_VERBOSE — verbose logging to stderr
  • POLARS_PANIC_ON_ERR — panic on Polars errors
  • POLARS_BACKTRACE_IN_ERR — include backtrace in Polars errors
  • QSV_POLARS_FLOAT_PRECISION — float precision for Polars → CSV conversion (Avro, Arrow, Parquet, JSON, JSONL). Since #4901 (27.0.1) it no longer applies to gz/zlib/zst compressed CSVs, which are decompressed as-is.
  • QSV_POLARS_DECIMAL_SCALE — Polars Decimal scale (default 5)

MCP server (qsvmcp only)

The MCP server has its own dedicated environment variable namespace — see MCP Server and the canonical reference's MCP section.

Key ones:

  • QSV_MCP_BIN_PATH — full path to qsv/qsvmcp binary
  • QSV_MCP_WORKING_DIR — default working directory (supports ${HOME}, ${DOWNLOADS}, ${DOCUMENTS}, …)
  • QSV_MCP_ALLOWED_DIRS — additional accessible directories (colon-separated on Unix)
  • QSV_MCP_OPERATION_TIMEOUT_MS — operation timeout (default 600,000 = 10 min)
  • QSV_MCP_MAX_OUTPUT_SIZE — max bytes before output is saved to disk (default 50 MB)
  • QSV_MCP_MAX_CONCURRENT_OPERATIONS — concurrency cap (default 3 in plugin mode, 1 in extension mode)
  • QSV_MCP_LOG_LEVEL — info / error / off (separate from QSV_LOG_LEVEL)
  • QSV_MCP_USE_DUCKDB — enable DuckDB SQL when available
  • QSV_MCP_OUTPUT_FORMAT — tsv (default) or csv
  • QSV_MCP_ENABLE_APPS — enable MCP Apps UI features such as the qsv_browse_directory interactive browser (default true)
  • QSV_MCP_SANITIZE_ERRORS — strip absolute paths (usernames, directory layout) from command and error output before returning it to the client (default true). Set false only for local debugging — sanitization is what protects hosted/shared deployments
  • QSV_MCP_EXPOSE_ALL_TOOLS — expose all tools at startup instead of deferred loading (core tools only). For AI clients that don't support deferred tool loading (default: auto-detect)
  • QSV_MCP_SERVER_INSTRUCTIONS — custom server instructions that override the built-in workflow guidance (default: empty = built-in)
  • QSV_MCP_MAX_EXAMPLES — max examples included in tool descriptions, 0–20 (default 5; 0 disables)
  • QSV_MCP_MAX_FILES_PER_LISTING — max files returned in one directory listing (default 1,000)
  • QSV_MCP_CONVERTED_LIFO_SIZE_GB — size cap for the converted-file cache (Excel→CSV, JSONL→CSV) in GB, LIFO eviction (default 1.0)
  • QSV_MCP_DUCKDB_BIN_PATH — full path to the DuckDB binary (default: auto-detect from PATH)
  • QSV_MCP_NOTIFY_UPDATES — log update notifications when a new version is available (default true)
  • QSV_MCP_AUTO_REGENERATE_SKILLS — run qsv --update-mcp-skills automatically when the qsv version changes (default false)
  • QSV_MCP_GITHUB_REPO — repository used for update checks (default dathere/qsv)
  • QSV_MCP_CHECK_UPDATES_ON_STARTUP — check GitHub for a newer qsv release at startup (default true)
  • QSV_MCP_CONCURRENCY_WAIT_TIMEOUT_MS — how long a request waits for a free concurrency slot before being rejected; 0 rejects immediately (default 120,000 = 2 min)
  • QSV_MCP_PLUGIN_MODE — override plugin-mode detection; set true for non-Claude agent CLIs (e.g. Gemini CLI) whose host already provides filesystem isolation (default: auto-detect)
  • MCPB_EXTENSION_MODE — set automatically by Claude Desktop when qsv runs as an extension; enables stricter validation (fully qualified qsv path, version ≥ 17.0.0). Don't set it yourself

Claude Cowork plugin

  • QSV_NO_COWORK_SETUP — set to 1 to stop the Cowork plugin from auto-deploying its workflow-guidance CLAUDE.md. Set it in your shell before launching Claude Code

Dotenv (.env) files

qsv loads .env files in this order:

  1. The file at QSV_DOTENV_PATH if set (overrides everything; set to <NONE> to disable)
  2. .env in the current working directory
  3. <binary-name>.env next to the qsv binary itself (e.g. /usr/local/bin/qsv.env)

Set QSV_DOTENV_PATH=<NONE> to disable dotenv processing entirely.

Dependencies

Some env vars come from qsv's dependencies, not qsv itself:

Discover at runtime

qsv --envlist
# Lists every QSV_* variable currently set in your environment,
# plus allocator-specific (MIMALLOC_*/JEMALLOC_*) and proxy vars.
qsv --capabilities
# JSON: binary name, version, target, features (with Polars/Luau/Python versions)
# and installed commands. Also in qsvlite and qsvdp (25.0.0).

See also

Home · Why qsv? · Tier legend

Quick links

Get Started

Command Reference

Cookbook

Tuning & Internals

Ecosystem

Reference

Legacy

Clone this wiki locally