Skip to Content
Configuration

Configuration

qaws configuration is explicit and strict.

  • It never auto-loads qaws.json.
  • Pass config with --config <file>.
  • Unknown keys are errors.
  • Invalid types are errors.
  • CLI flags override config values.

Validate a file:

qaws check --config qaws.json

Start with a file:

qaws --config qaws.json

Complete shape

qaws.json
{ "listen": { "host": "0.0.0.0", "port": 80 }, "serve": "./public", "daemon": { "enabled": false, "pid_file": null, "log_file": null }, "logging": { "format": "plain", "access": true }, "security": { "dotfiles": "deny_except_well_known" }, "cache": { "enabled": true, "max_file_bytes": 262144, "max_total_bytes": 16777216, "revalidate_ms": 1000 }, "headers": { "Cache-Control": "public, max-age=3600" }, "http": { "last_modified": true, "trailing_slash_redirect": true, "keep_alive": true, "keep_alive_timeout_ms": 5000, "max_requests_per_connection": 1000, "max_connections": 1024, "workers": 4, "sendfile": true, "etag": true, "range_requests": true, "precompressed": true } }

Minimal config

qaws.json
{ "listen": { "host": "127.0.0.1", "port": 8080 }, "serve": "./public" }

listen

KeyTypeDefaultNotes
hoststring0.0.0.0Bind address. Use 127.0.0.1 for local-only service.
portinteger80TCP port. Low ports may require privileges.

serve

serve is a top-level string:

{ "serve": "./public" }

It must point to an existing directory. In daemon mode, qaws resolves the serve directory before detaching so relative paths do not break after the process changes directory.

daemon

KeyTypeDefaultNotes
enabledbooleanfalseSame behavior as -d.
pid_filestring or nullnullExplicit daemon identity.
log_filestring or nullnullExplicit daemon log path.

logging

KeyTypeDefaultValues
formatstringplainplain, jsonl
accessbooleantrueEnables or disables access logs.

security

KeyTypeDefaultValues
dotfilesstringdeny_except_well_knowndeny_except_well_known

Dotfile path segments are denied by default except .well-known.

cache

KeyTypeDefaultNotes
enabledbooleantrueEnables small-file cache.
max_file_bytesinteger262144Maximum cached file size.
max_total_bytesinteger16777216Total cached body byte budget.
revalidate_msinteger1000Stat TTL before cache revalidation.

If the total limit is reached, qaws serves additional files uncached.

headers

headers is an object of custom response headers:

{ "headers": { "Cache-Control": "public, max-age=3600", "Cross-Origin-Resource-Policy": "same-origin" } }

Protected headers are rejected because qaws owns them at runtime:

Content-Length Content-Type Connection Server Allow Location ETag Accept-Ranges Content-Range Content-Encoding Vary

http

KeyTypeDefaultNotes
last_modifiedbooleantrueEnables Last-Modified and If-Modified-Since.
trailing_slash_redirectbooleantrueRedirects directories like /docs to /docs/.
keep_alivebooleantrueHTTP/1.1 keep-alive support.
keep_alive_timeout_msinteger5000Idle timeout.
max_requests_per_connectioninteger1000Keep-alive request cap.
max_connectionsinteger1024Active plus queued connection cap.
workersintegerautomatically detectedExplicit event-worker or fallback-worker count.
sendfilebooleantruePlatform sendfile for uncached GET bodies.
etagbooleantrueWeak representation ETags and If-None-Match.
range_requestsbooleantrueSingle byte ranges and If-Range.
precompressedbooleantrueBrotli/gzip sidecar negotiation.

Zero or negative-like tuning values are invalid.

Automatic worker selection uses the highest-capacity CPU cluster on Linux/Android, macOS performance-level CPU information when available, and the logical CPU count as a portable fallback. --workers remains the explicit override.

qaws docs. Built for static hosting.