apache/cassandra-gocql-driver: the Go client for Cassandra after the v2 rewrite
GoCQL Driver for Apache Cassandra®
At a glance
- What is it?
- The Apache-hosted GoCQL driver is the Cassandra project's own Go client, now at v2.1.2. This review covers what v2 changed, how the connection pool and type conversions behave, and where the driver's defaults will bite you.
- Who is it for?
- Adopt apache/cassandra-gocql-driver if you are writing new Go services against Cassandra 4.1 or 5.0 and want the client that ships under the Cassandra project's own name, with protocol 5 keyspace and timestamp overrides available. Do not adopt it if you are still on a 1.x codebase and cannot schedule the migration described in UPGRADE_GUIDE.md, because the v2 module path and the removal of "use <keyspace>" statements will break the build and the query path at the same time.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 64 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the GoCQL driver is for, and who should reach for it
This is the Go client for Apache Cassandra, published under the Apache Cassandra organisation rather than by a third party. The README describes it as implementing "a fast and robust Cassandra client for the Go programming language", and the module path in go.mod is github.com/apache/cassandra-gocql-driver/v2. The audience is narrow and specific: Go services that talk to a Cassandra cluster over the native transport and need type conversion, connection pooling and paging handled for them.
If you are writing a Go service that reads and writes CQL, this removes the work of speaking the native protocol yourself. If you are not on Go, it is irrelevant, and the related searches make the point that the ecosystem is split by language: people looking for a Cassandra Java driver, a Cassandra Python driver or a Rust Cassandra driver are looking at entirely separate projects with separate release cycles. The choice of driver is really a choice of language, and this one only serves Go.
The support matrix in the README is worth reading before anything else. It lists Go 1.25 and 1.26 as tested against Cassandra 4.1.x and 5.0.x in the integration suite. The README also states that gocql has been tested in production against many versions of Cassandra, but that CI only covers the latest two GA releases. That gap between what the community has run and what CI verifies is the honest framing of this project's compatibility story.
How the connection pool, protocol negotiation and type binding actually work
The driver is built around a Cluster value that you configure and then turn into a Session. The session owns the connections. According to the README's feature list, the pool is policy based, with token aware and round robin implementations, and queries are distributed round robin across hosts and then across connections on a host. Automatic reconnect uses exponential falloff. Node discovery is optional rather than automatic. Each connection can execute up to n concurrent queries, where n is the limit imposed by the protocol version the client negotiates.
Protocol negotiation matters more than it first appears. The README maps protocol 3 to Cassandra 2.1 and later, protocol 4 to Cassandra 3.0 and later, and protocol 5 to Cassandra 4.0 and later. Protocol 5 is what unlocks per-query keyspace override through Query.SetKeyspace() and Batch.SetKeyspace(), plus per-query custom timestamps through Query.WithNowInSeconds() and Batch.WithNowInSeconds(). Cassandra 5.0 adds vector types for vector search. If you are on an older cluster, those APIs are not available to you regardless of driver version, because the server side will not negotiate the protocol.
Type handling is where the driver does the most invisible work. The README claims automatic conversion between Cassandra and Go for sets, lists and maps, strict conversions without loss of precision, and built-in UUID support for versions 1 and 4. Custom types can implement Marshaler and Unmarshaler. For user defined types there are three documented routes: a custom marshaller, struct tags, or the map-based APIs. The README also notes that the only time the driver copies data out of its read buffer is during Unmarshal, which is the design decision that keeps the hot path cheap and also explains why iterators need closing.
Installing the driver and running a first query
Installation is a single module fetch. The README gives the command as:
go get github.com/apache/cassandra-gocql-driver/v2The README carries a note that version 2.0.0 introduced breaking changes and points to an upgrade guide at UPGRADE_GUIDE.md in the repository for moving off 1.x. If you are starting fresh, that note does not apply to you, but the /v2 suffix in the import path is not optional. Pulling the module without it will get you the old line.
The first real use is creating a cluster and a session. The README's own correct-usage example looks like this, with the keyspace set on the cluster before the session exists:
cluster := gocql.NewCluster("192.168.1.1", "192.168.1.2", "192.168.1.3")
cluster.Keyspace = "example"
session, err := cluster.CreateSession()What you should see is a session that is ready to run queries against the example keyspace. The README's incorrect-usage example is the same code followed by an attempt to execute a "use example2" statement. That call returns an error, because the driver no longer supports executing "use <keyspace>" statements. The README states the keyspace can only be defined before a session is created, and that queries can still reach other keyspaces by qualifying the table, as in SELECT * FROM example2.table. If your existing code runs a "use" statement anywhere, that is the first thing to find and delete.
Where the driver's defaults and design choices will cost you
The removal of "use" statements is the sharpest edge in v2. It is a deliberate simplification, and the README is explicit about it, but it means a per-request keyspace switch is no longer a statement you can run. On protocol 5 you get Query.SetKeyspace() instead. On protocol 3 or 4 you do not, so a service that needs to touch several keyspaces has to qualify every table name or maintain separate sessions. That is a real design constraint, not a footnote.
The README is candid about performance in a way that most client libraries are not. It states that the driver is built with maintainability and code readability in mind first and performance second, and that "every now and then performance may degrade", with a request to file an issue if it does. That is an unusual admission and you should take it at face value when comparing against a driver that optimises for throughput first.
The performance tips in the README double as a list of things that go wrong by default. Reading from the network into your types causes a large number of allocations, which pressures the garbage collector, and the README suggests tuning GOGC. Iterators must be closed to recycle byte buffers, which is a leak if you forget. The driver is asynchronous underneath but exposes a synchronous API, so the README recommends many goroutines for inserts. Query page size needs tuning. None of this is done for you.
gocqlx and the other Cassandra drivers as alternatives
The README names gocqlx, from ScyllaDB, as "an idiomatic extension to gocql" that provides usability improvements. The difference in approach is layering rather than replacement: gocqlx sits on top of this driver and adds query building and struct mapping, so it inherits the connection pool, protocol negotiation and type conversion described above. If you find the driver's data binding options verbose, gocqlx is the documented next step rather than a competing client.
Within the driver itself, the README lists five binding routes, and choosing between them is the real architectural decision. Writing the binding by hand gives the most flexibility but requires you to keep application code in sync with the schema. SliceMap() marshals an entire result into a slice of maps keyed by column name, which requires your application to handle a key-value view. MapScan() does the same row by row. Bind() is the low-level route that introspects query metadata and pulls fields from your own structs. There is no single right answer, and the README does not pretend there is.
The language-level alternatives are outside this project's scope but worth naming for anyone still choosing. A Cassandra Java driver, a Cassandra Python driver and a Rust Cassandra driver all exist as separate projects with their own protocol support and release cadence. Picking this driver is picking Go, and the migration cost of changing that later is a rewrite of the data access layer, not a configuration change.
Maintenance, licensing and the cost of the v2 upgrade
The repository is not archived and the last push was on 2026-07-28, roughly two months before this review. Recent releases are v2.1.0 on 2026-04-02, v2.1.1 on 2026-04-22 and v2.1.2 on 2026-06-16. The version numbering is stable and the patch cadence is regular, but note that the project's own support policy, described in the README under "Sunsetting Model", is to support the current and previous versions of Go. Older Go toolchains may still work, but official support for them has been sunset. That is a recurring upgrade cost you should budget for, because a Go toolchain bump can move you out of support independently of any change in this driver.
The licence is Apache-2.0, and the repository carries both LICENSE and NOTICE files, which is the standard Apache Software Foundation arrangement. The go.mod header carries the ASF copyright notice. If your organisation has rules about ASF-licensed dependencies, this one fits the familiar pattern. That is a description of the licence, not legal advice.
The upgrade cost is concentrated in one place. The README states that 2.0.0 introduced breaking changes and points to UPGRADE_GUIDE.md for moving from 1.x. The two changes visible in the README itself are the /v2 module path and the removal of "use" statement execution. The upgrade guide is where the rest would be, and the README does not summarise it. Read that file before estimating the work.
Editorial conclusion
Adopt apache/cassandra-gocql-driver if you are writing new Go services against Cassandra 4.1 or 5.0 and want the client that ships under the Cassandra project's own name, with protocol 5 keyspace and timestamp overrides available. Do not adopt it if you are still on a 1.x codebase and cannot schedule the migration described in UPGRADE_GUIDE.md, because the v2 module path and the removal of "use <keyspace>" statements will break the build and the query path at the same time. Before writing code, read UPGRADE_GUIDE.md and confirm three things in your own tree: that every keyspace is set on the cluster before CreateSession, that no code path executes a "use" statement, and that your Go toolchain is one of the versions the README's support matrix lists as tested.
Frequently asked questions
How do I install the apache/cassandra-gocql-driver in a Go project?
Run go get github.com/apache/cassandra-gocql-driver/v2. The README notes that version 2.0.0 introduced breaking changes and links to UPGRADE_GUIDE.md for moving from 1.x.
Which versions of Go and Cassandra does apache/cassandra-gocql-driver support?
The README's support matrix lists Go 1.25 and 1.26 as tested against Cassandra 4.1.x and 5.0.x in the integration suite. It also states that CI only covers the latest two GA releases of Cassandra, even though the driver has been tested in production against many versions.
Why does apache/cassandra-gocql-driver return an error for a "use" statement?
The README states that gocql no longer supports executing "use <keyspace>" statements, and that the default keyspace can only be defined before a session is created. Other keyspaces are still reachable by qualifying the table in the query.
Does apache/cassandra-gocql-driver support per-query keyspace overrides?
Yes, but only on protocol 5, which maps to Cassandra 4.0 and later. The README lists Query.SetKeyspace() and Batch.SetKeyspace() under protocol 5 features, alongside Query.WithNowInSeconds() and Batch.WithNowInSeconds() for custom timestamps.
Is there an idiomatic extension to apache/cassandra-gocql-driver?
The README names gocqlx, from ScyllaDB, as an idiomatic extension to gocql that provides usability improvements. It layers on top of the driver rather than replacing it.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/apache-cassandra-gocql-driver)