Skip to main content
Skip to main content
Edit this page

Configuration reference

This page documents every configurable option in clickhouse-go v2.x. For narrative guides with code examples, see Configuration.

How options are set

Options exist at three scopes:

ScopeHow to setLifetime
Connectionclickhouse.Options struct or DSN stringAll queries on the connection
Queryclickhouse.Context() with WithXxx functionsSingle query execution
BatchPrepareBatch() option functionsSingle batch operation

Via Options struct:

conn, err := clickhouse.Open(&clickhouse.Options{
    Addr:        []string{"localhost:9000"},
    Auth:        clickhouse.Auth{Database: "default", Username: "default", Password: ""},
    DialTimeout: 10 * time.Second,
    Compression: &clickhouse.Compression{Method: clickhouse.CompressionLZ4},
})

Via DSN string:

db, err := sql.Open("clickhouse", "clickhouse://user:pass@localhost:9000/default?dial_timeout=10s&compress=lz4")

Via Connector (database/sql with Options struct):

db := sql.OpenDB(clickhouse.Connector(&clickhouse.Options{
    Addr:        []string{"localhost:9000"},
    Auth:        clickhouse.Auth{Database: "default", Username: "default"},
    DialTimeout: 10 * time.Second,
}))
// Set database/sql-only pool settings after creation
db.SetConnMaxIdleTime(5 * time.Minute)

Via context (per-query):

ctx := clickhouse.Context(context.Background(),
    clickhouse.WithQueryID("my-query-123"),
    clickhouse.WithSettings(clickhouse.Settings{"max_execution_time": 60}),
)
rows, err := conn.Query(ctx, "SELECT ...")

Connection options

Protocol and connection

OptionTypeDefaultDSN paramDescriptionBest practiceWhen misconfigured
ProtocolProtocol (int)NativeScheme: clickhouse://=Native, http://=HTTPCommunication protocol: Native (0) for TCP, HTTP (1) for HTTPUse Native for ~30% better performance. Use HTTP for proxy support, firewall traversal (port 80/443), or HTTP-only compression (gzip/br). See TCP vs HTTP.HTTP scheme with Native port (9000): connection refused. Native blocked by firewall: timeouts.
Addr[]string["localhost:9000"] (Native) ["localhost:8123"] (HTTP)Comma-separated hosts in URLList of "host:port" addresses for connection and failoverSpecify multiple addresses in production for HA. Correct ports: 9000 (Native), 8123 (HTTP), 9440 (Native+TLS), 8443 (HTTP+TLS).Single address: no failover. Wrong port: "connection refused". Empty/nil: defaults to localhost, fails in distributed deployments.
ConnOpenStrategyConnOpenStrategy (uint8)ConnOpenInOrder (0)connection_open_strategy (in_order, round_robin, random)Strategy for selecting a server from Addr. InOrder (0)=failover, RoundRobin (1)=load balance, Random (2)=random.InOrder for active-standby. RoundRobin for active-active/K8s. Random to avoid thundering herd.InOrder with active-active: first server gets all load, others idle. All strategies try all servers on failure -- only affects which is tried first.

Authentication

OptionTypeDefaultDSN paramDescriptionBest practiceWhen misconfigured
Auth.Usernamestring"default"username or URL user portionUsername for ClickHouse authenticationNever use default in production. Create dedicated users with minimal permissions.Wrong username: "Code: 516. DB::Exception: Authentication failed". Empty string: silently uses "default".
Auth.Passwordstring""password or URL password portionPassword for ClickHouse authenticationUse env vars or secret managers in production. URL-encode special characters in DSN.Wrong password: "Code: 516. DB::Exception: Authentication failed". Special chars not URL-encoded: parsing errors.
Auth.Databasestring"" (server default)database or URL path (/mydb)Default database for the connectionAlways specify explicitly. Use dedicated databases per application in production.Non-existent: "Code: 81. DB::Exception: Database xyz doesn't exist". Empty in multi-tenant setup: queries hit wrong database.
GetJWTfunc(ctx) (string, error)nil— (programmatic only)Callback returning JWT for ClickHouse Cloud auth. Overridable per query with WithJWT(token).Implement token caching/refresh -- called per connection/request.Expired token: auth errors. Blocking callback: timeouts. JWT takes precedence over user/pass. Requires TLS -- without it, falls back to user/pass silently.
GetJWT: func(ctx context.Context) (string, error) {
    return getTokenFromVault(ctx)
}

Timeouts

OptionTypeDefaultDSN paramDescriptionBest practiceWhen misconfigured
DialTimeouttime.Duration30sdial_timeoutMax time to establish a new connection. Also controls pool acquisition wait when MaxOpenConns is reached.5-10s on LAN, 15-30s on WAN/cloud. Never below 1s.Too short: "clickhouse: acquire conn timeout" during congestion. Too long (> 60s): app hangs during outages.
ReadTimeouttime.Duration5m (300s)read_timeoutMax time to wait for a server response per read call. Applied per block, not entire query. Context deadline takes precedence.10-30s for OLTP, 5-30m for OLAP/long queries.Too short: "i/o timeout" or "read: connection reset by peer" mid-query; server continues executing. Too long: dead connections not detected.

Connection pool

OptionTypeDefaultDSN paramAPIDescriptionBest practiceWhen misconfigured
MaxIdleConnsint5max_idle_connsBothMax idle (unused but alive) connections in pool50-80% of expected concurrent queries. Low: 2-5, medium: 10-20, high: 20-50.Too low: connection churn, higher latency. Too high: wasted memory. Capped at MaxOpenConns automatically.
MaxOpenConnsintMaxIdleConns + 5 (default: 10)max_open_connsBothMax total connections (idle + active)Low: 10-20, medium: 20-50, high: 50-100. Formula: concurrent queries + burst + buffer. Monitor: SELECT * FROM system.metrics WHERE metric='TCPConnection'.Too low: "clickhouse: acquire conn timeout". Too high: server "Too many connections", FD limits exceeded. ClickHouse default max_connections: 1024 (shared).
ConnMaxLifetimetime.Duration1hconn_max_lifetimeBothMax duration a connection can be reused. Checked on return to pool.1-5h stable envs. 5-15m for K8s/rolling deploys. Never infinite.Too short (< 1m): churn, higher latency. Too long/infinite: stale connections, DNS changes not picked up, traffic never rebalances.
ConnMaxIdleTimetime.Duration0 (none)database/sql onlyMax time a connection can sit idle before closing. Not in Options struct -- set via db.SetConnMaxIdleTime().5-10m for K8s/bursty workloads to reclaim idle connections after traffic spikes.Not set: idle connections persist until ConnMaxLifetime. Too short (< 30s): connections recreated during normal gaps.
database/sql only

ConnMaxIdleTime is a standard Go database/sql pool setting. It is not available in the clickhouse.Options struct or via clickhouse.Open(). Set it after OpenDB():

db := clickhouse.OpenDB(&clickhouse.Options{...})
db.SetConnMaxIdleTime(5 * time.Minute)

See Connection Pooling for usage details.


database/sql post-creation settings

When using clickhouse.OpenDB() or sql.Open("clickhouse", dsn), the returned *sql.DB supports Go's standard pool methods. OpenDB() auto-applies the first three from Options:

MethodOptions equivalentNotes
db.SetMaxIdleConns(n)MaxIdleConnsAuto-applied by OpenDB()
db.SetMaxOpenConns(n)MaxOpenConnsAuto-applied by OpenDB()
db.SetConnMaxLifetime(d)ConnMaxLifetimeAuto-applied by OpenDB()
db.SetConnMaxIdleTime(d)NoneMust be set manually post-creation
ClickHouse API (clickhouse.Open)

These methods are NOT available on the connection returned by clickhouse.Open(). The ClickHouse API manages its own pool internally using the Options struct fields directly.


Compression

OptionTypeDefaultDSN paramDescriptionBest practiceWhen misconfigured
Compression.MethodCompressionMethod (byte)Nonecompress (lz4, zstd, lz4hc, gzip, deflate, br, or true for LZ4)Compression algorithm for data transfer. See protocol support matrix below.LAN: None or LZ4. WAN: ZSTD or LZ4. CPU constrained: LZ4. Max compression: ZSTD (Native) or Brotli (HTTP). Skip for inserts < 1 MB.GZIP/Brotli on Native: handshake failure. LZ4HC on HTTP: error or silent fallback. No compression on slow networks: 10-100x slower inserts.
Compression.Levelint3compress_levelAlgorithm-specific intensity. GZIP/Deflate: -2 to 9. Brotli: 0 to 11. LZ4/ZSTD: ignored.GZIP balanced: 3-6. Brotli balanced: 4-6.Very high levels: extreme CPU, minimal benefit. Non-zero for LZ4/ZSTD: silently ignored. Level without compression enabled: no effect.
MaxCompressionBufferint (bytes)10485760 (10 MiB)max_compression_bufferMax compression buffer size before flushing. Each connection has its own buffer.Default 10 MiB is good. 20-50 MiB for wide rows. Total memory = buffer x MaxOpenConns.Too small (< 1 MiB): frequent flushes, poor efficiency. Too large (> 100 MiB): OOM with many connections.

Compression method support by protocol:

MethodNativeHTTP
CompressionLZ4YesYes
CompressionLZ4HCYesNo
CompressionZSTDYesYes
CompressionGZIPNoYes
CompressionDeflateNoYes
CompressionBrotliNoYes

TLS

OptionTypeDefaultDSN paramDescriptionBest practiceWhen misconfigured
TLS*tls.Confignil (plain text)secure=true, skip_verify=trueTLS/SSL config. Non-nil enables TLS. Ports: Native 9000/9440, HTTP 8123/8443.Always enable in production and ClickHouse Cloud (required). InsecureSkipVerify: false in production. Add custom CAs via RootCAs.Wrong port: "connection reset by peer". skip_verify=true in prod: MITM vulnerable. Expired cert: "x509: certificate has expired". Wrong host: "x509: certificate is valid for X, not Y". Untrusted CA: "x509: certificate signed by unknown authority". HTTP DSN with secure=true: use https:// scheme instead.

See TLS for code examples.


Logging

OptionTypeDefaultDSN paramDescriptionBest practiceWhen misconfigured
Logger*slog.Loggernil (no logging)Structured logger via Go's log/slog. Priority: Debug+Debugf > Logger > no-op.Use slog with JSON handler in production. Add app context with logger.With(...).
Debug (deprecated)boolfalsedebugLegacy debug toggle. Use Logger instead. Logs to stdout unless Debugf is set.Enabled in production: performance overhead, verbose logs, sensitive data in output.
Debugf (deprecated)func(string, ...any)nilCustom debug log function. Use Logger instead. Requires Debug: true.
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
conn, err := clickhouse.Open(&clickhouse.Options{
    Logger: logger,
    // ...
})

See Logging for full examples.


Buffers and memory

OptionTypeDefaultDSN paramPer-queryDescriptionBest practiceWhen misconfigured
BlockBufferSizeuint82block_buffer_sizeYes (WithBlockBufferSize)Decoded blocks to buffer when reading results. Enables concurrent read + decode.Default 2 is fine. 5-10 for large streaming results. Memory = buffer x block size x concurrent queries.Too small (1): blocks reader, higher latency. Too large (> 50): high memory, diminishing returns.
FreeBufOnConnReleaseboolfalseNoRelease connection memory buffer after each query instead of reusing.false for high query rates. true in memory-constrained containers or infrequent large batches.false + limited memory: buffers accumulate (memory = buffer x idle conns). true + high rate: GC pressure, increased CPU.

HTTP-specific

These options only affect Protocol: clickhouse.HTTP. Silently ignored for Native.

OptionTypeDefaultDSN paramDescriptionBest practiceWhen misconfigured
HttpHeadersmap[string]stringnilAdditional HTTP headers on every requestUse for tracing (X-Request-ID), auth proxy headers. Keep minimal.Overriding internal headers (Content-Type, Authorization): unpredictable behavior.
HttpUrlPathstring""http_pathURL path appended to requests. Leading / added automatically.Use when behind reverse proxy with path routing.Wrong path: HTTP 404 from proxy/LB.
HttpMaxConnsPerHostint0 (unlimited)TCP connections per host at transport layer (http.Transport.MaxConnsPerHost).Leave at 0 for most apps. Only set when server has strict connection limits.Too low (e.g., 10 with MaxOpenConns=50): transport bottleneck, slow queries despite low server load.
HTTPProxyURL*url.URLnil (uses env vars)http_proxy (URL-encoded)HTTP proxy for routing requestsSet explicitly if proxy required. Overrides HTTP_PROXY/HTTPS_PROXY env vars.Wrong address: "dial tcp: lookup proxy: no such host". Proxy needs auth: HTTP 407.
TransportFuncfunc(*http.Transport) (http.RoundTripper, error)nilCustom HTTP transport factory. Receives default transport for wrapping.Use for observability middleware. Don't override Proxy, DialContext, TLSClientConfig.Returning nil: panic. Overriding client fields: TLS/proxy silently ignored. Blocking RoundTripper: deadlocks.
Two-layer HTTP pooling

When using HTTP, there are two connection pools:

  • Layer 1 (application): MaxIdleConns / MaxOpenConns -- controls httpConnect objects
  • Layer 2 (transport): HttpMaxConnsPerHost -- controls underlying TCP connections

The Native protocol has a simple 1:1 mapping and ignores HttpMaxConnsPerHost.

TransportFunc: func(t *http.Transport) (http.RoundTripper, error) {
    return &loggingRoundTripper{transport: t}, nil
}

Advanced connection

OptionTypeDefaultDSN paramDescriptionBest practiceWhen misconfigured
DialContextfunc(ctx, addr) (net.Conn, error)nil (standard dialer)Custom dial function for TCP connections. Works with both Native and HTTP.Leave nil for 99% of cases. Use for Unix sockets, SOCKS proxy, custom DNS.Not respecting context: hangs, resource leaks. With TLS set: custom dialer must handle TLS itself. Invalid net.Conn: crashes.
DialStrategyfunc(ctx, connID, options, dial) (DialResult, error)DefaultDialStrategyCustom server selection and connection strategy. Overrides ConnOpenStrategy.Use default for 99.9% of cases. Custom only for geo-aware routing, weighted selection, health checks.Not trying all servers: fails with healthy servers available. Expensive ops inside: blocks pool acquisition on every connect.

Client information

OptionTypeDefaultDSN paramPer-queryDescriptionBest practiceWhen misconfigured
ClientInfoClientInfo structAuto: clickhouse-go version + Go runtimeclient_info_product=myapp/1.0Yes (WithClientInfo, appends)App identification sent to ClickHouse. Contains Products ([]struct{Name,Version}) and Comment ([]string). Visible in system.query_log.Always set app name + version. Query attribution: SELECT client_name FROM system.query_log WHERE client_name LIKE '%myapp%'Not setting: can't identify which service issued queries in multi-service environments.
ClientInfo: clickhouse.ClientInfo{
    Products: []struct{ Name, Version string }{
        {Name: "my-service", Version: "1.0.0"},
    },
}
// Appears as: clickhouse-go/2.x my-service/1.0.0 (lv:go/1.23; os:linux)

ClickHouse server settings

OptionTypeDefaultDSN paramPer-queryDescriptionBest practiceWhen misconfigured
Settingsmap[string]anynilAny unrecognized param (e.g. ?max_execution_time=60)Yes (WithSettings, context wins on conflict)ClickHouse server settings applied to every query. DSN conversion: "true"1, "false"0, numeric→int.Set common limits at connection level, override per-query via context.Typos: silently ignored or error by version. Wrong types: "Cannot parse string 'abc' as Int64". max_execution_time=0 + no deadline: queries run forever.
CustomSettingCustomSetting{Value string}Yes (via WithSettings)Marks a setting as "custom" (non-important) for Native protocol. Won't error if server doesn't recognize it. HTTP treats all settings as custom by default.Use for experimental or version-specific settings.Marking important settings as custom: silently ignored if unsupported.

Common settings:

SettingTypeDescription
max_execution_timeintQuery timeout in seconds
max_memory_usageintMemory limit per query (bytes)
max_block_sizeintBlock size for processing
readonlyint1 = read-only, 2 = read-only + settings changes
Settings: clickhouse.Settings{
    "max_execution_time":  60,                                        // important -- errors if unknown
    "my_custom_setting":   clickhouse.CustomSetting{Value: "value"},  // custom -- ignored if unknown
}

Context-level query options

Set per-query using clickhouse.Context():

ctx := clickhouse.Context(context.Background(),
    clickhouse.WithQueryID("my-query"),
    clickhouse.WithSettings(clickhouse.Settings{"max_execution_time": 60}),
)
Context deadline behavior

If the context has a deadline > 1s, max_execution_time is automatically set to seconds_remaining + 5. This overrides any manually set value.

OptionTypeDefaultProtocolDescriptionBest practiceWhen misconfigured
WithQueryIDstringAuto-generatedBothCustom query identifier. Visible in system.query_log and system.processes.Use UUIDs. Useful for KILL QUERY WHERE query_id='...'.Duplicate IDs: confusion in system.query_log.
WithQuotaKeystring""BothQuota key for multi-tenant resource limits. Requires server-side quota config.Use for per-customer/per-user limits.Quota not configured: silently ignored.
WithJWTstring""HTTPS onlyPer-query JWT override for ClickHouse Cloud.Use for per-request auth in multi-tenant proxies.Without TLS: ignored, falls back to connection auth. Expired: "Token has expired".
WithSettingsSettingsInherits connectionBothPer-query server settings. Merged with connection settings; context wins on conflict.Override max_execution_time or max_rows_to_read per query type.Same as connection-level Settings.
WithParametersParameters (map[string]string)nilBothServer-side parameterized query values. Query syntax: {param_name:Type}.Use instead of string concatenation for SQL injection safety.Missing param: "Substitution {param_name:Type} is not set". Wrong type: "Cannot parse string 'abc' as UInt64".
WithAsyncbool (wait)SyncBothAsync insert mode. Sets async_insert=1. wait=true adds wait_for_async_insert=1. Requires ClickHouse 21.11+.Use for high-throughput inserts.wait=false: errors may be async -- check system.asynchronous_insert_log. With SELECT: ignored. Old server: "Unknown setting async_insert".
WithLogsfunc(*Log)nilNative onlyServer log entries callback during query execution.Keep fast -- blocks execution. Use goroutines for heavy processing.On HTTP: silently never called.
WithProgressfunc(*Progress)nilNative onlyQuery progress updates (rows/bytes processed).Keep fast -- blocks execution.On HTTP: silently never called.
WithProfileInfofunc(*ProfileInfo)nilNative onlyQuery execution statistics callback.Keep fast -- blocks execution.On HTTP: silently never called.
WithProfileEventsfunc([]ProfileEvent)nilNative onlyPerformance counters callback.Keep fast -- blocks execution.On HTTP: silently never called.
WithoutProfileEventsEvents sentNative onlySuppress profile events. Performance optimization for servers ≥ 25.11.Use when you don't need profile events.On older servers: error for unknown setting.
WithExternalTable...*ext.TablenilBothAttach temporary lookup tables to query. Data transferred per query.Keep tables < 10 MB. Native more efficient than HTTP (multipart).Large tables: network overhead per query.
WithUserLocation*time.LocationServer timezoneBothOverride timezone for DateTime parsing.Set explicitly when client/server timezones differ.Wrong timezone: DateTime values silently off by hours, potential data corruption.
WithColumnNamesAndTypes[]ColumnNameAndTypenil (runs DESCRIBE)HTTP onlySkip DESCRIBE TABLE round trip on HTTP inserts by providing column info upfront.Use when schema is known and stable.Wrong types: "Cannot convert String to UInt64". Schema drift after migration: stale info.
WithBlockBufferSizeuint8Connection-level (2)BothOverride connection-level BlockBufferSize for a single query.Increase for large result sets on specific queries.
WithClientInfoClientInfoConnection-levelBothAppend additional client info for a single query. Does not replace, appends.Add per-request context (e.g., endpoint name).
WithSpantrace.SpanContextEmptyNative onlyOpenTelemetry span context for distributed tracing.See OpenTelemetry.
ctx := clickhouse.Context(ctx,
    clickhouse.WithQueryID("query-123"),
    clickhouse.WithParameters(clickhouse.Parameters{
        "user_id": "12345",
    }),
    clickhouse.WithProgress(func(p *clickhouse.Progress) {
        log.Printf("Progress: %d rows, %d bytes", p.Rows, p.Bytes)
    }),
)
rows, err := conn.Query(ctx, "SELECT * FROM users WHERE id = {user_id:String}")

Batch options

Passed to PrepareBatch(). Import: github.com/ClickHouse/clickhouse-go/v2/lib/driver.

OptionDefaultDescriptionBest practiceWhen misconfigured
WithReleaseConnectionConnection held until Send()Release connection to pool immediately after PrepareBatch(). Re-acquires on Send()/Flush().Use for long-lived batches (minutes/hours) to prevent pool exhaustion.Not using for long batches: "acquire conn timeout" if many active.
WithCloseOnFlushBatch stays openAuto-close batch when Flush() is called.Use for one-shot batches. Saves explicit Close().Using with multiple Flush() calls: first flush closes batch, subsequent ops fail.
batch, err := conn.PrepareBatch(ctx, "INSERT INTO table",
    driver.WithReleaseConnection(),
    driver.WithCloseOnFlush(),
)

Quick reference tables

Connection pool sizing

Application typeMaxIdleConnsMaxOpenConnsConnMaxLifetime
Low-traffic web app5101h
Medium-traffic API205030m
High-traffic service5010015m
Background batch jobs10202h
Kubernetes deployment102010m
Serverless (Lambda)155m

Timeout recommendations

EnvironmentDialTimeoutReadTimeout
Local / LAN5s30s
Cloud, same region10s2m
Cloud, cross region30s5m
OLAP workload10s30m
Realtime / OLTP5s10s

DSN parameter quick reference

DSN parameterOptions fieldExample
usernameAuth.Username?username=admin
passwordAuth.Password?password=secret
databaseAuth.Database?database=mydb or /mydb in path
dial_timeoutDialTimeout?dial_timeout=10s
read_timeoutReadTimeout?read_timeout=5m
max_open_connsMaxOpenConns?max_open_conns=50
max_idle_connsMaxIdleConns?max_idle_conns=20
conn_max_lifetimeConnMaxLifetime?conn_max_lifetime=30m
connection_open_strategyConnOpenStrategy?connection_open_strategy=round_robin
block_buffer_sizeBlockBufferSize?block_buffer_size=10
compressCompression.Method?compress=lz4
compress_levelCompression.Level?compress_level=6
max_compression_bufferMaxCompressionBuffer?max_compression_buffer=20971520
secureTLS?secure=true
skip_verifyTLS.InsecureSkipVerify?skip_verify=true
debugDebug?debug=true
client_info_productClientInfo.Products?client_info_product=myapp/1.0
http_proxyHTTPProxyURL?http_proxy=http%3A%2F%2Fproxy%3A8080
http_pathHttpUrlPath?http_path=/clickhouse
(any other)Settings[key]?max_execution_time=60

Troubleshooting

"acquire conn timeout"

Cause: Connection pool exhausted -- all MaxOpenConns connections are in use and none became available within DialTimeout.

Fix:

  • Increase MaxOpenConns to match actual concurrency
  • Increase DialTimeout for burst tolerance
  • Check for long-running queries holding connections
  • Use WithReleaseConnection() for long-lived batches

"i/o timeout" or "read: connection reset by peer"

Cause: ReadTimeout exceeded while waiting for a server response, or the connection was closed by the server/network.

Fix:

  • Increase ReadTimeout for long-running queries
  • Use context deadlines for per-query timeout control
  • Check ClickHouse server-side max_execution_time limits

"Code: 516. Authentication failed"

Cause: Wrong username, password, or the user doesn't exist.

Fix:

  • Verify credentials against system.users table
  • Check for URL-encoding issues with special characters in DSN passwords
  • Confirm the user has access to the specified database

TLS certificate errors

ErrorCauseFix
x509: certificate has expiredServer cert expiredRenew server certificate
x509: certificate is valid for X, not YHostname mismatchUse correct hostname or add to SANs
x509: certificate signed by unknown authorityUntrusted CAAdd CA to tls.Config.RootCAs
connection reset by peerTLS/port mismatchUse port 9440 (Native) or 8443 (HTTP) for TLS

Gradual memory growth

Cause: Large idle connection buffers accumulating.

Fix:

  • Set FreeBufOnConnRelease: true in memory-constrained environments
  • Reduce MaxIdleConns to limit idle connections
  • Reduce MaxCompressionBuffer if using compression
  • Lower ConnMaxLifetime to cycle connections more frequently