ClickHouse Go Driver: High-Performance Go Client
The ClickHouse Go Driver is the official Go client for ClickHouse, shipping both a native protocol interface (clickhouse.Open) and a standard database/sql interface (clickhouse.OpenDB) in one package. Reach for the native interface on new, performance-sensitive code — it encodes columns directly. Reach for OpenDB instead when you're already standardized on database/sql tooling or an ORM and don't want a second driver API in the codebase.
Connecting Go Applications to ClickHouse
The ClickHouse Go Driver is a Golang SQL database client for ClickHouse, published as github.com/ClickHouse/clickhouse-go/v2. It exposes two ways to connect: a ClickHouse-specific driver.Conn opened with clickhouse.Open, and a database/sql-compatible interface opened with clickhouse.OpenDB. Both work over native TCP or HTTP transport, and versions 2.3.0+ use the lower-level ch-go library for encoding and compression.
Core Capabilities and Advanced Features
- ✓Two connection interfaces in one package: clickhouse.Open returns a ClickHouse-specific driver.Conn for direct column encoding, and clickhouse.OpenDB returns a standard database/sql.DB for existing tooling and ORMs.
- ✓Native TCP and HTTP transport are both supported by either interface, so the same client can run through a proxy such as ChProxy or an HTTP load balancer without switching APIs.
- ✓Struct marshaling in both directions — ScanStruct/Select map query results into structs, and AppendStruct writes a struct back out as a row.
- ✓Connection pooling with configurable MaxOpenConns, MaxIdleConns, and ConnMaxLifetime, plus failover and load balancing across a host list using in_order, round_robin, or random strategies.
- ✓Compression covers LZ4, ZSTD, LZ4HC, GZIP, Deflate, and Brotli, with native block compression and HTTP web compression treated as separate, explicitly configurable layers.
- ✓Async insert through the WithAsync() helper, usable on both the native and database/sql interfaces, replacing the deprecated AsyncInsert() API.
- ✓Structured logging via Go's log/slog package, JWT authentication support, and context-based access to protocol features like query ID, quota key, OpenTelemetry, and execution progress events.
Getting Started with the Driver
Install it with `go get github.com/ClickHouse/clickhouse-go/v2` — that's the only install step the README documents; there's no separate CLI or config file to set up first. Go version support tracks the client's own release: versions 2.0-2.2 need Go 1.17/1.18, 2.3+ need 1.18.4+/1.19, 2.29+ support Go 1.21 through 1.24, and the newest listed range, 2.41+, needs Go 1.24 or 1.25, per the compatibility table in the README. Full documentation lives at clickhouse.com/docs/en/integrations/go.
Connecting and Querying Examples
Opening a native connection means building a clickhouse.Options struct — address, Auth (Database/Username/Password), and optionally Settings, Compression, and timeouts — then calling clickhouse.Open(&options) and conn.Ping(ctx) to confirm it's reachable: ```go conn, err := clickhouse.Open(&clickhouse.Options{ Addr: []string{"127.0.0.1:9000"}, Auth: clickhouse.Auth{ Database: "default", Username: "default", Password: "", }, }) if err != nil { return err } return conn.Ping(context.Background()) ``` For database/sql, clickhouse.OpenDB(&options) returns a *sql.DB you configure the normal way, with SetMaxIdleConns, SetMaxOpenConns, and SetConnMaxLifetime. A DSN string works too — `clickhouse://user:pass@host1:9000,host2:9000/database?dial_timeout=200ms&read_timeout=30s` — and query parameters like compress, secure, and connection_open_strategy map directly to Options fields. Bulk writes go through PrepareBatch on the native interface, or a begin→prepare→exec-in-loop→commit pattern with database/sql.
Strengths
- ✓Native and database/sql interfaces live in the same package, so moving from one to the other doesn't mean pulling in a different driver.
- ✓Connection pooling, failover, and load balancing (in_order, round_robin, random) are built in and configurable through either the Options struct or DSN query parameters.
- ✓Compression is genuinely varied — LZ4, ZSTD, LZ4HC, GZIP, Deflate, and Brotli are all supported, with native block compression and HTTP web compression kept as separate, explicit layers instead of one opaque flag.
- ✓TLS setup uses Go's standard tls.Config directly, so certificate chains, SNI, and cipher suites are configured the normal Go way instead of through a driver-specific abstraction.
- ✓Apache-2.0 license with no proprietary strings attached.
Interface Trade-offs and Experimental Features
- △Methods handling arbitrary input/output formats (QueryFormat/InsertFormat, which support raw CSV, JSONEachRow, Parquet, and comparable options) are labeled experimental in the README document and could be modified or eliminated in a subsequent minor release.
- △Those raw-format streaming methods only work over HTTP — the native TCP protocol returns ErrFormatNativeUnsupported for them, so getting both fast native queries and raw-format streaming means using two connection modes.
- △database/sql compatibility comes at a documented performance cost: the README's own benchmark section calls it slower than the native interface, so it's a real trade-off, not a free convenience.
- △The old AsyncInsert() API and the Debug/Debugf logging options are already deprecated in favor of WithAsync() and the Logger field, so code written against the older APIs needs updating.
- △Compression has sharp edges: the README warns that enabling both HTTP web compression and native block compression at once can waste CPU compressing already-compressed blocks.
Choosing Between Native and `database/sql` Interfaces
Frequently Asked Questions
ClickHouse Go Driver is tested against the currently supported versions of ClickHouse, as tracked in the ClickHouse project's own SECURITY.md file, rather than pinned to one fixed release list.
ClickHouse Go Driver's Go support tracks its own release: client versions 2.0-2.2 need Go 1.17/1.18, 2.3+ need 1.18.4+/1.19, 2.29+ support Go 1.21 through 1.24, and 2.41+ needs Go 1.24 or 1.25, per the README's compatibility table.
ClickHouse Go Driver's native interface is faster because it uses direct column encoding, while the database/sql interface is slower according to the project's own benchmark section — the README recommends native for performance-sensitive work.
ClickHouse Go Driver supports TLS/SSL on all three connection paths — DSN, OpenDB, and Open — using Go's standard tls.Config, and the DSN's secure and skip_verify parameters both default to false, meaning certificate verification is on by default.
ClickHouse Go Driver supports HTTP on both interfaces: use an http:// DSN or set Protocol: clickhouse.HTTP in the Options struct, and native-format data can travel over HTTP for use with proxies like ChProxy.
ClickHouse Go Driver is released under the Apache-2.0 license, as listed on its GitHub repository.
The problem it solves
Every Go application talking to ClickHouse has to pick a wire protocol and an API shape before writing the first query, and getting that choice wrong later costs real throughput or forces a rewrite. The README addresses this head-on with its own "Which interface should I use?" comparison table — a ClickHouse-specific driver.Conn for direct column encoding, or a database/sql-compatible driver for existing tooling — rather than shipping one generic SQL driver and leaving that trade-off for you to discover through a benchmark later.
Best use cases
- •Building a new Go service that writes to or queries ClickHouse and wants the fastest path — the README recommends the native driver.Conn interface with its direct column encoding when in doubt.
- •Adding ClickHouse to a codebase already built on database/sql tooling or an ORM, via clickhouse.OpenDB, without introducing a second driver-specific API.
- •Streaming bulk inserts or exports in the server's own format — QueryFormat/InsertFormat pass raw CSV, JSONEachRow, or Parquet straight through without the driver re-encoding it.
- •Connecting through an HTTP proxy or load balancer such as ChProxy, since the native format can travel over the HTTP transport as well as raw TCP.
- •Running async, non-blocking inserts via WithAsync() in write-heavy pipelines that don't need each insert acknowledged before moving on.
Who should try it — and who should skip
Reach for the ClickHouse Go Driver if you're writing new Go code against ClickHouse and want direct access to native-protocol features — connection pooling, failover, compression choices, and the driver.Conn API — without routing through database/sql. Use the database/sql interface specifically, but keep the same driver, if you're bolting ClickHouse onto an existing database/sql-based codebase or ORM and are willing to trade some throughput for compatibility, per the project's own benchmark comparison. Skip the package entirely if you need a client in a language other than Go.
Related repositories
Want a second opinion on clickhouse-go?
Ask an AI that can read this page — one click and you get its take on clickhouse-go.
