ClickHouse Go
Quickstart
Let's Go with a simple example. This will connect to ClickHouse and select from the system database. To get started you will need your connection details.
Connection details
To connect to ClickHouse with native TCP you need this information:
| Parameters | Description |
|---|---|
HOST and PORT | Typically, the port is 9440 when using TLS, or 9000 when not using TLS. |
DATABASE NAME | Out of the box there is a database named default, use the name of the database that you want to connect to. |
USERNAME and PASSWORD | Out of the box the username is default. Use the username appropriate for your use case. |
The details for your ClickHouse Cloud service are available in the ClickHouse Cloud console. Select the service that you will connect to and click Connect:
Choose Native, and the details are available in an example clickhouse-client command.
If you're using self-managed ClickHouse, the connection details are set by your ClickHouse administrator.
Initialize a module
Copy in some sample code
Copy this code into the clickhouse-golang-example directory as main.go.
Run go mod tidy
Set your connection details
Earlier you looked up your connection details. Set them in main.go in the connect() function:
Run the example
Learn more
The rest of the documentation in this category covers the details of the ClickHouse Go client.
Overview
ClickHouse supports two official Go clients. These clients are complementary and intentionally support different use cases.
- clickhouse-go - High level language client which supports either the Go standard
database/sqlinterface or the native ClickHouse API. - ch-go - Low level client. Native interface only.
clickhouse-go provides a high-level interface, allowing users to query and insert data using row-orientated semantics and batching that are lenient with respect to data types - values will be converted provided no precision loss is potentially incurred. ch-go, meanwhile, provides an optimized column-orientated interface that provides fast data block streaming with low CPU and memory overhead at the expense of type strictness and more complex usage.
From version 2.3, clickhouse-go utilizes ch-go for low-level functions such as encoding, decoding, and compression. Both clients use the native format for their encoding to provide optimal performance and can communicate over the native ClickHouse protocol. clickhouse-go also supports HTTP as its transport mechanism for cases where users need to proxy or load balance traffic.
Four ways to connect
clickhouse-go gives you two independent choices: which API to use and which transport to use. These combine into four connection modes:
| TCP (Native protocol, port 9000/9440) | HTTP (port 8123/8443) | |
|---|---|---|
ClickHouse API (clickhouse.Open) | Default — best performance | Set Protocol: clickhouse.HTTP |
database/sql API (OpenDB / sql.Open) | clickhouse://host:9000 | http://host:8123 |
Choosing an API: Pick the ClickHouse API for maximum performance and the full feature set (progress callbacks, columnar inserts, rich type support). Pick database/sql when you need to integrate with ORMs or tools that expect a standard Go database interface.
Choosing a transport: TCP is faster and is the default. Switch to HTTP when your infrastructure requires it — for example, when connecting through an HTTP load balancer or proxy, or when you need HTTP-specific features like sessions with temporary tables, or additional compression algorithms (gzip, deflate, br).
Both APIs use the native binary encoding regardless of transport, so HTTP carries no serialization overhead.
| Native format | TCP transport | HTTP transport | Bulk write | Struct marshaling | Compression | Progress callbacks | |
|---|---|---|---|---|---|---|---|
| ClickHouse API | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
database/sql API | ✅ | ✅ | ✅ | ✅ | ✅ |
Choosing a client
Selecting a client library depends on your usage patterns and need for optimal performance. For insert heavy use cases, where millions of inserts are required per second, we recommend using the low level client ch-go. This client avoids the associated overhead of pivoting the data from a row-orientated format to columns, as the ClickHouse native format requires. Furthermore, it avoids any reflection or use of the interface{} (any) type to simplify usage.
For query workloads focused on aggregations or lower throughput insert workloads, the clickhouse-go provides a familiar database/sql interface and more straightforward row semantics. You can also optionally use HTTP for the transport protocol and take advantage of helper functions to marshal rows to and from structs.
| Native format | Native protocol | HTTP protocol | Row Orientated API | Column Orientated API | Type flexibility | Compression | Query Placeholders | |
|---|---|---|---|---|---|---|---|---|
| clickhouse-go | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| ch-go | ✅ | ✅ | ✅ | ✅ |
Installation
v1 of the driver is deprecated and won't reach feature updates or support for new ClickHouse types. You should migrate to v2, which offers superior performance.
To install the 2.x version of the client, add the package to your go.mod file:
require github.com/ClickHouse/clickhouse-go/v2 main
Or, clone the repository:
To install another version, modify the path or the branch name accordingly.
Versioning
The client is released independently of ClickHouse. 2.x represents the current major under development. All versions of 2.x should be compatible with each other.
ClickHouse compatibility
The client supports:
- All currently supported versions of ClickHouse as recorded here. As ClickHouse versions are no longer supported they're also no longer actively tested against client releases.
- All versions of ClickHouse 2 years from the release date of the client. Note only LTS versions are actively tested.
Golang compatibility
| Client Version | Golang Versions |
|---|---|
| => 2.0 <= 2.2 | 1.17, 1.18 |
| >= 2.3, < 2.41 | 1.18+ |
| >= 2.41 | 1.21+ |
| >= 2.43 | 1.24+ |
Best practices
- Utilize the ClickHouse API where possible, especially for primitive types. This avoids significant reflection and indirection.
- If reading large datasets, consider modifying the
BlockBufferSize. This will increase the memory footprint but will mean more blocks can be decoded in parallel during row iteration. The default value of 2 is conservative and minimizes memory overhead. Higher values will mean more blocks in memory. This requires testing since different queries can produce different block sizes. It can therefore be set on a query level via the Context. - Be specific with your types when inserting data. While the client aims to be flexible, e.g., allowing strings to be parsed for UUIDs or IPs, this requires data validation and incurs a cost at insert time.
- Use column-oriented inserts where possible. Again these should be strongly typed, avoiding the need for the client to convert your values.
- Follow ClickHouse recommendations for optimal insert performance.
Next steps
- Configuration — connection settings, TLS, authentication, logging, compression
- ClickHouse API — native Go API for queries and inserts
- Database/SQL API — standard
database/sqlinterface - Data Types — Go type mappings and complex type support