go-elasticsearch

The official Go client for Elasticsearch, providing type-safe REST API bindings, bulk indexing, and connection-pooled transport for v7 clusters.

SDK
Go
vv7.17.10
6,064stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
88/100Excellent
Development Activity80
Maintenance80
Community92
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
79/100Good
Architecture88
Code Quality85
Innovation62
Learning Curve80

go-elasticsearch is the officially maintained Go client for Elasticsearch, built and shipped by Elastic itself. It wraps the full Elasticsearch REST API surface in generated, typed Go functions under the esapi package, so callers work with Go structs and functional options instead of hand-building HTTP requests and parsing raw JSON responses.

The client is split into focused packages: elasticsearch for client construction and configuration, esapi for the generated per-endpoint request/response types, estransport for connection pooling, node discovery, retries, and metrics, and esutil for higher-level ergonomics like a concurrent bulk indexer and JSON response helpers. This separation lets advanced users swap the transport or wrap the low-level API while still using the generated request types.

Because Elasticsearch itself ships major versions in lockstep with client libraries, the v7 line of this client (module path github.com/elastic/go-elasticsearch/v7) targets Elasticsearch 7.x clusters specifically, with the generated API surface pinned to a corresponding Elasticsearch specification version. Later major client versions (v8, v9) exist in the same repository for newer Elasticsearch releases, and Go modules’ semantic import versioning lets multiple major versions coexist in a single project.

What You Get

  • A generated esapi package covering the full Elasticsearch REST API (search, indexing, cat APIs, cluster and index management, and more) as typed Go functions with functional-option configuration
  • An estransport layer handling connection pooling, round-robin node selection, retries with configurable backoff, node discovery, and optional request metrics/debug logging
  • An esutil.BulkIndexer for high-throughput, concurrent, buffered bulk indexing with success/failure callbacks per item
  • Support for Cloud ID and API key/service token authentication for connecting to Elastic Cloud deployments, alongside standard basic auth and custom CA certificates
  • Compatibility-mode headers so the client can talk to a differently-versioned Elasticsearch server during upgrades

Common Use Cases

  • Indexing and searching application data (logs, product catalogs, documents) from a Go backend service
  • Bulk-loading large datasets into Elasticsearch efficiently using the concurrent bulk indexer instead of one request per document
  • Building internal tooling or ETL pipelines that read from Elasticsearch’s cat/cluster APIs for monitoring and operations
  • Connecting Go services to Elastic Cloud using CloudID and API-key auth without managing raw HTTP endpoints
  • Running multiple Elasticsearch client major versions side-by-side in one Go module during a cluster upgrade

Under The Hood

Architecture The client is organized as four cooperating packages: elasticsearch (root) builds a Client that embeds *esapi.API directly, so every generated endpoint method is available on the client value itself; estransport owns the Transport interface, connection pool, node selector, and retry/backoff logic and is constructed once inside NewClient from the Config struct; esapi holds hundreds of generated per-endpoint files (api.<namespace>.<action>.go) each defining a *Request type with a Do(ctx, transport) method, all built on shared helpers in api._.go; and esutil layers optional conveniences (the concurrent BulkIndexer, JSON response readers) on top of the public esapi/estransport types rather than reaching into internals. Swapping the transport (custom http.RoundTripper, custom Logger, custom ConnectionPool) is a first-class extension point exposed through Config, so the core abstraction that would break the most on change is the estransport.Interface contract between the client and its transport.

Tech Stack This is a dependency-light, standard-library-first Go module (go 1.11 for the v7 line) — the root elasticsearch.go imports only net/http, encoding/json, and other stdlib packages plus its own esapi/estransport/internal/version subpackages, with no third-party HTTP or JSON library pulled in. The esapi package is machine-generated from the Elasticsearch API specification (each file carries a Code generated ... DO NOT EDIT header pinned to a specific spec version, e.g. 7.17.10), keeping the request surface mechanically synchronized with the server API rather than hand-maintained. CI (visible via badge references to GitHub Actions workflows: Build, Unit, Integration, API) runs unit tests plus integration tests against real Elasticsearch instances and a generated-API conformance suite.

Code Quality Tests are present throughout — root, esapi, estransport, and esutil each ship _internal_test.go, _integration_test.go, _example_test.go, and in several cases _benchmark_test.go files, indicating unit, integration, documentation (example), and performance test coverage as separate concerns using Go’s standard testing package and build tags (//go:build !integration) to separate fast unit runs from cluster-dependent integration runs. Error handling is explicit throughout — functions return (*Response, error) or wrapped errors via fmt.Errorf/errors.New rather than panicking, and the generated esapi layer has a consistent, uniform shape across all endpoints since it’s templated. Naming follows idiomatic Go conventions (exported Config, Client, *Request types; unexported helpers), and the project carries a Makefile with lint/test/generate targets standard to Elastic’s Go tooling.

API Design The public API favors Go idioms over cleverness: NewDefaultClient() for zero-config use, NewClient(Config{...}) for explicit configuration, and functional options (o ...func(*XRequest)) on generated per-endpoint functions for optional parameters, which keeps call sites readable without constructor telescoping. Every generated request type implements Do(ctx, transport), giving a single consistent invocation pattern across hundreds of endpoints. Getting started requires minimal boilerplate — es, _ := elasticsearch.NewDefaultClient(); res, _ := es.Info() — while power users can reach every transport-level knob (retry policy, node discovery, custom pooling, metrics, debug logging) through the same Config struct, and documentation is dense with inline godoc comments plus a large _examples/ directory covering bulk indexing, security, instrumentation, and cloud functions.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search