Configuration reference | Tigris Object Storage Documentation
On this page
TAG can be configured via a YAML configuration file and/or environment variables. Environment variables take precedence over file configuration.
Configuration precedence
- Command line flags (highest priority)
- Environment variables
- Configuration file
- Default values (lowest priority)
Environment variables
| Variable | Description | Default |
|---|---|---|
AWS_ACCESS_KEY_ID |
Tigris access key (TAG's own credentials, not client credentials) | (required) |
AWS_SECRET_ACCESS_KEY |
Tigris secret key | (required) |
TAG_UPSTREAM_ENDPOINT |
Upstream S3 endpoint URL | https://t3.storage.dev |
TAG_TRANSPARENT_PROXY |
Transparent proxy mode; set false/0 for signing mode |
true |
TAG_MAX_IDLE_CONNS_PER_HOST |
HTTP connection pool size per upstream host | 100 |
TAG_MAX_INFLIGHT_REQUESTS |
Max concurrent S3 requests before shedding with 503 SlowDown | 1024 |
TAG_CACHE_DISK_PATH |
Path to cache data directory | /var/tmp/tag |
TAG_CACHE_MAX_DISK_USAGE |
Max disk usage in bytes (0 = unlimited) | 0 |
TAG_CACHE_TTL |
Default TTL for cached objects (Go duration, e.g. 12h, 30m) |
24h |
TAG_CACHE_DISABLED |
Disable caching (true or 1) |
false |
TAG_CACHE_MAX_CONCURRENT_WRITES |
Max concurrent cache-populate operations | 256 |
TAG_CACHE_MAX_POPULATE_MEMORY |
Aggregate memory budget (bytes) for concurrent cache-populate buffering | 1073741824 (1 GiB) |
TAG_CACHE_DELETE_BATCH_SIZE |
File deletions processed per deletion-queue batch | 1000 |
TAG_CACHE_RECOVERY_WORKERS |
Parallel workers for startup file recovery | 16 |
TAG_HTTP_PORT |
HTTP listen port | 8080 |
TAG_LOG_LEVEL |
Log level: debug, info, warn, error |
info |
TAG_LOG_FORMAT |
Log format: json or console |
json |
TAG_TLS_CERT_FILE |
Path to TLS certificate file (PEM format) | (none) |
TAG_TLS_KEY_FILE |
Path to TLS private key file (PEM format) | (none) |
TAG_CACHE_GRPC_ADDR |
Address for gRPC server | :9000 |
TAG_CACHE_NODE_ID |
Unique node identifier for cluster mode (clustering) | (none) |
TAG_CACHE_CLUSTER_ADDR |
Address for memberlist gossip (clustering) | :7000 |
TAG_CACHE_ADVERTISE_ADDR |
Address advertised to other nodes (clustering) | (defaults to gRPC addr) |
TAG_CACHE_SEED_NODES |
Comma-separated seed nodes for cluster discovery (clustering) | (none) |
TAG_PPROF_ENABLED |
Enable pprof endpoints (true or 1) |
false |
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY are TAG's own Tigris credentials with read-only access to all buckets accessed through TAG (required). Clients use their own credentials directly.
Configuration file
The configuration file uses YAML format. Specify the path with the --config flag:
./tag --config /etc/tag/config.yaml
Full configuration reference
# Server configuration
server:
# HTTP port for the S3 API
# Default: 8080
http_port: 8080
# IP address to bind to
# Default: "0.0.0.0" (all interfaces)
bind_ip: "0.0.0.0"
# Enable pprof profiling endpoints
# Default: false (disabled for security)
pprof_enabled: false
# Path to TLS certificate file (PEM format)
# When both tls_cert_file and tls_key_file are set, TAG serves HTTPS
# Default: "" (TLS disabled, serves HTTP)
tls_cert_file: ""
# Path to TLS private key file (PEM format)
# Must be set together with tls_cert_file
# Default: "" (TLS disabled, serves HTTP)
tls_key_file: ""
# Upstream Tigris configuration
upstream:
# Tigris S3 endpoint URL
# Default: "https://t3.storage.dev"
endpoint: "https://t3.storage.dev"
# AWS region for request signing
# Default: "auto"
region: "auto"
# HTTP connection pool size per upstream host
# Higher values improve throughput for cache-miss scenarios
# Default: 100
max_idle_conns_per_host: 100
# Transparent proxy mode forwards client requests as-is with proxy headers
# (Tigris only). Set to false for signing mode, which validates and re-signs
# requests and works with any S3-compatible endpoint.
# Default: true
transparent_proxy: true
# Cache configuration
cache:
# Enable caching
# Default: true
enabled: true
# Default TTL for cached objects
# Default: 24h
ttl: 24h
# Maximum object size to cache (in bytes)
# Objects larger than this are not cached
# Default: 1073741824 (1GB)
size_threshold: 1073741824
# Path to cache data directory
# /var/tmp/tag works on both macOS and Linux without root
# Default: /var/tmp/tag
disk_path: "/var/tmp/tag"
# Max disk usage in bytes (0 = unlimited)
# Default: 0
max_disk_usage_bytes: 0
# Max concurrent cache-populate operations (upstream fetch + streaming write).
# When saturated, objects are still served from upstream, just not cached.
# Default: 256 (0 or unset = default; negative = disabled)
max_concurrent_writes: 256
# Aggregate memory budget for concurrent cache-populate buffering. Each populate
# reserves its object size, capped at the per-populate buffer ceiling, so many
# small objects populate concurrently while a burst of large objects is throttled
# to keep buffered memory bounded. This, rather than the raw count above, is what
# bounds populate memory; both limits apply.
# Default: 1073741824 (1 GiB) (0 or unset = default; negative = memory cap disabled)
max_populate_memory_bytes: 1073741824
# Unique node identifier for cluster mode
# Required for multi-node deployments
node_id: "tag-node-1"
# Address for memberlist gossip protocol
# Default: :7000
cluster_addr: ":7000"
# Address for gRPC server (cache cluster routing)
# Default: :9000
grpc_addr: ":9000"
# Address advertised to other nodes
# Defaults to grpc_addr if not specified
advertise_addr: "tag-node-1:9000"
# Seed nodes for cluster discovery
# List of cluster addresses for other nodes
# or can also be DNS name of headless service in Kubernetes (e.g. tag-headless-svc:7000)
seed_nodes:
- "tag-node-1:7000"
- "tag-node-2:7000"
- "tag-node-3:7000"
# Broadcast configuration (request coalescing)
broadcast:
# Streaming chunk size in bytes
# Default: 65536 (64 KiB)
chunk_size: 65536
# Buffer size per listener in chunks
# Total buffer per listener = chunk_size × channel_buffer
# Default: 32 (~2 MiB with default chunk size)
channel_buffer: 32
# Logging configuration
log:
# Log level: debug, info, warn, error
# Default: "info"
level: "info"
# Log format: json (fast) or console (human-readable)
# Default: "json"
format: "json"
Additional notes
TLS
When both tls_cert_file and tls_key_file are set, TAG serves HTTPS. See
TLS/HTTPS for certificate setup across Docker, Kubernetes, and native deployments.
Endpoint validation
The upstream endpoint must be a well-formed absolute http:// or https:// URL with a host. In transparent proxy mode (the default) the host must also match one of localhost, *.tigris.dev, or *.storage.dev; TAG exits at startup otherwise. Signing mode does not apply this allowlist and accepts any S3-compatible endpoint — see
Using TAG with other S3-compatible services.
Using TAG with other S3-compatible services
Signing mode re-signs requests with standard AWS SigV4, so it works against any S3-compatible endpoint (AWS S3, MinIO, Ceph, etc.), not just Tigris:
upstream:
transparent_proxy: false
endpoint: "https://s3.us-east-1.amazonaws.com"
# Set the backend's region; the default "auto" only works with Tigris. AWS and
# other region-sensitive services reject signatures whose credential-scope
# region does not match the endpoint.
region: "us-east-1"
- Transparent proxy mode and its zero-config, no-double-auth experience are Tigris-only. Third-party backends are supported on a best-effort, community-supported basis.
- The
AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEYcredentials are the credentials for that backend; clients must present the same credentials, and they need permissions covering whatever operations clients perform (read-only is insufficient if clients write).
Cluster mode
For multi-node deployments, configure each node with a unique node_id, the
same seed_nodes list, and an advertise_addr reachable from other nodes.
| Port | Protocol | Purpose |
|---|---|---|
| 8080 | TCP | HTTP API (S3-compatible) |
| 7000 | TCP | Gossip protocol for cluster discovery |
| 9000 | TCP | gRPC for inter-node cache communication |
macOS port conflict
On macOS, port 7000 is used by AirPlay Receiver. Use ports 17000 (gossip) and 19000 (gRPC) instead:
cache:
cluster_addr: ":17000"
grpc_addr: ":19000"
seed_nodes:
- "node1:17000"
Profiling
TAG exposes pprof endpoints for performance profiling when enabled. Disabled by default for security (exposes runtime internals).
TAG_PPROF_ENABLED=true ./tag
Endpoints (when enabled):
/debug/pprof/— Index/debug/pprof/profile?seconds=30— CPU profile/debug/pprof/heap— Heap profile/debug/pprof/goroutine— Goroutine stacks
Usage with go tool pprof:
go tool pprof http://localhost:8080/debug/pprof/profile?seconds=30
go tool pprof http://localhost:8080/debug/pprof/heap
Command line flags
| Flag | Description |
|---|---|
--version |
Print version information and exit |
--config |
Path to configuration file |
--http-port |
HTTP listen port (default: 8080, env: TAG_HTTP_PORT) |
--log-level |
Log level (overrides config file and env) |
--log-format |
Log format (overrides config file and env) |
--disable-cache |
Disable caching (pass-through mode) |
# Print version
./tag --version
# Use configuration file
./tag --config /etc/tag/config.yaml
# Override port and log level via flags
./tag --http-port 9090 --log-level debug
# Disable caching via flag (overrides config)
./tag --config /etc/tag/config.yaml --disable-cache
# Use environment variables only (no config file)
AWS_ACCESS_KEY_ID=xxx AWS_SECRET_ACCESS_KEY=yyy ./tag
Example configurations
Development (standalone)
server:
http_port: 8080
upstream:
endpoint: "https://t3.storage.dev"
cache:
disk_path: "/tmp/tag-cache"
node_id: "dev-node"
log:
level: "debug"
Production (single node)
server:
http_port: 8080
bind_ip: "0.0.0.0"
cache:
disk_path: "/var/tmp/tag"
max_disk_usage_bytes: 429496729600 # 400 GiB
ttl: 24h
size_threshold: 1073741824
node_id: "tag-prod"
log:
level: "info"
format: "json"
To add TLS to any of these configs, set tls_cert_file and tls_key_file under
server. See TLS/HTTPS for full examples.
Production (cluster mode)
Configure each node with a unique node_id and the same seed_nodes list:
server:
http_port: 8080
cache:
disk_path: "/var/tmp/tag"
max_disk_usage_bytes: 429496729600 # 400 GiB per node
ttl: 24h
size_threshold: 1073741824
# Cluster configuration — unique per node
node_id: "tag-1"
cluster_addr: ":7000"
grpc_addr: ":9000"
advertise_addr: "tag-1.tag-svc.default.svc.cluster.local:9000"
seed_nodes:
- "tag-svc.default.svc.cluster.local:7000"
log:
level: "info"
format: "json"