Go and etcd3

Packages for Go

Go is the default language of etcd3 given that the database is written in Go. A client, clientv3 is included as part of the distribution of etcd.


Use a release version of clientv3

Go, by default, checks out the master branch of a github repository when you run go get... for a package. The master of the clientv3 package is documented as being unstable and, more often than not, throw out errors due to incompatibility.

We, therefore, recommend that you either download a release version of the package or use a tool like glide to vendor in a known release version.

Once you have installed clientv3, you will have everything you need to connect.

Connecting with Go

To illustrate the process of connecting, we have a minimal Go etcd application which will return a count of all the keys in the database. We start with the obligatory import preamble

package main

import (


Note here the importing of github.com/coreos/etcd/clientv3. This is the essential import for the library but there are some other etcd libraries you may have to bring in with more advanced usages, predominantly for constant values.

The next part is us setting up some variables which we'll use in the process of connecting. Endpoints is a string array of the gRPC endpoints, which as we mention in Connecting to etcd3 are available in the Overview. The other two parameters, username and password are found in the same place.

func main() {
    endpoints := []string{"https://portal200-5.threetcd.compose-3.composedb.com:18279", "https://portal200-0.threetcd.compose-3.composedb.com:18279"}
    username := "root"
    password := "ROOTPASSWORD"

When you write your application, these values can come from whatever flags, configuration files or other mechanisms you choose to use. With those values in place, we can move to connecting.

The first stage of that is to create a Config struct with our connection details, then we can use the clientv3.New() function to turn that config into a connection:

cfg := clientv3.Config{
        Endpoints:   endpoints,
        Username:    username,
        Password:    password,
        DialTimeout: 5 * time.Second,

    etcdclient, err := clientv3.New(cfg)

    if err != nil {

    defer etcdclient.Close()

We now have the etcdclient, or we will have once we've checked for errors and set up a defer to close the client cleanly when done.

We can now we can start using the client's KV (Key Value) interface. Here we want to count all the keys in the namespace. We can do that with a .Get() function. This function takes a context to handle timing out, a key and then any number of options. These are obtained by calling the client library with an appropriate function.

response, err := etcdclient.Get(context.TODO(), "", clientv3.WithCountOnly(), clientv3.WithPrefix())

    if err != nil {


Here, the context is TODO(), as in we're not setting any timeouts currently. We are also passing an empty key, but if you look, we pass the WithPrefix() option too. This makes the key value into a prefix and it'll return all the keys. We're not interested in the values, we only want to count so with use the WithCountOnly() option.

The Get() function returns a response which includes a Count field, and after checking for errors, we'll print that.

That's the basics of accessing etcd3 on Compose. The endpoints themselves are HTTPS secured with Let's Encrypt certificates and the gRPC connections are also TLS encrypted.

Further reading

Still Need Help?

If this article didn't solve things, summon a human and get some help!