ClickHouse Go

[Edit this page](https://github.com/ClickHouse/clickhouse-docs/blob/main/docs/integrations/language-clients/go/index.md)

## Quickstart[​](#quick-start "Direct link to 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[​](#connection-details "Direct link to 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[​](#initialize-a-module "Direct link to Initialize a module")

```
mkdir clickhouse-golang-example
cd clickhouse-golang-example
go mod init clickhouse-golang-example
```

### Copy in some sample code[​](#copy-in-some-sample-code "Direct link to Copy in some sample code")

Copy this code into the `clickhouse-golang-example` directory as `main.go`.

```
package main

import (
    "context"
    "crypto/tls"
    "fmt"
    "log"

    "github.com/ClickHouse/clickhouse-go/v2"
    "github.com/ClickHouse/clickhouse-go/v2/lib/driver"
)

func main() {
    conn, err := connect()
    if err != nil {
        panic(err)
    }

    ctx := context.Background()
    rows, err := conn.Query(ctx, "SELECT name, toString(uuid) as uuid_str FROM system.tables LIMIT 5")
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()

    for rows.Next() {
        var name, uuid string
        if err := rows.Scan(&name, &uuid); err != nil {
            log.Fatal(err)
        }
        log.Printf("name: %s, uuid: %s", name, uuid)
    }

    // NOTE: Do not skip rows.Err() check
    if err := rows.Err(); err != nil {
        log.Fatal(err)
    }

}

func connect() (driver.Conn, error) {
    var (
        ctx       = context.Background()
        conn, err = clickhouse.Open(&clickhouse.Options{
            Addr: []string{"<CLICKHOUSE_SECURE_NATIVE_HOSTNAME>:9440"},
            Auth: clickhouse.Auth{
                Database: "default",
                Username: "default",
                Password: "<DEFAULT_USER_PASSWORD>",
            },
            ClientInfo: clickhouse.ClientInfo{
                Products: []struct {
                    Name    string
                    Version string
                }{
                    {Name: "an-example-go-client", Version: "0.1"},
                },
            },
            Debugf: func(format string, v ...interface{}) {
                fmt.Printf(format, v)
            },
            TLS: &tls.Config{
                InsecureSkipVerify: true,
            },
        })
    )

    if err != nil {
        return nil, err
    }

    if err := conn.Ping(ctx); err != nil {
        if exception, ok := err.(*clickhouse.Exception); ok {
            fmt.Printf("Exception [%d] %s \n%s\n", exception.Code, exception.Message, exception.StackTrace)
        }
        return nil, err
    }
    return conn, nil
}
```

### Run go mod tidy[​](#run-go-mod-tidy "Direct link to Run go mod tidy")

```
go mod tidy
```

### Set your connection details[​](#set-your-connection-details "Direct link to Set your connection details")

Earlier you looked up your connection details. Set them in `main.go` in the `connect()` function:

```
func connect() (driver.Conn, error) {
  var (
    ctx       = context.Background()
    conn, err = clickhouse.Open(&clickhouse.Options{
    #highlight-next-line
      Addr: []string{"<CLICKHOUSE_SECURE_NATIVE_HOSTNAME>:9440"},
      Auth: clickhouse.Auth{
    #highlight-start
        Database: "default",
        Username: "default",
        Password: "<DEFAULT_USER_PASSWORD>",
    #highlight-end
      },
```

### Run the example[​](#run-the-example "Direct link to Run the example")

```
go run .
```

```
2023/03/06 14:18:33 name: COLUMNS, uuid: 00000000-0000-0000-0000-000000000000
2023/03/06 14:18:33 name: SCHEMATA, uuid: 00000000-0000-0000-0000-000000000000
2023/03/06 14:18:33 name: TABLES, uuid: 00000000-0000-0000-0000-000000000000
2023/03/06 14:18:33 name: VIEWS, uuid: 00000000-0000-0000-0000-000000000000
2023/03/06 14:18:33 name: hourly_data, uuid: a4e36bd4-1e82-45b3-be77-74a0fe65c52b
```

### Learn more[​](#learn-more "Direct link to Learn more")

The rest of the documentation in this category covers the details of the ClickHouse Go client.

## Overview[​](#overview "Direct link to Overview")

ClickHouse supports two official Go clients. These clients are complementary and intentionally support different use cases.

- [clickhouse-go](https://github.com/ClickHouse/clickhouse-go) - High level language client which supports either the Go standard `database/sql` interface or the native ClickHouse API.
- [ch-go](https://github.com/ClickHouse/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[​](#four-ways-to-connect "Direct link to 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.