FoundationDB for Go
A from-scratch FoundationDB client in pure Go — no cgo, 2–4× faster reads than libfdb_c. Plus a wire-compatible Record Layer and SQL engine, so Go and Java services share one cluster, byte-for-byte.
import "fdb.dev/pkg/fdbgo/fdbclient" // pure Go. CGO_ENABLED=0. static binary.
db, _ := fdbclient.Open("/etc/foundationdb/fdb.cluster")Pre-1.0, built in the open. The wire format is the hard line — conformance- and differential-tested against the Java reference. Pin a commit and run the suites before production. Maturity →
No cgo. Static binary. Faster reads.
Most FDB tooling links Apple’s C library through cgo — no static binaries, painful cross-compilation, a glibc dependency. The pure-Go client speaks the FoundationDB wire protocol directly and is the default backend, producing byte-identical reads and writes. The Go runtime skips the C client’s network-thread hop and multi-version-client shim; writes share the same commit path and run at parity.
The 10 ms-RTT row is the realistic signal — localhost microbenchmarks are syscall/IPC-bound, so they're the optimistic end. The read advantage holds under real latency (2.4× at 10 ms) and converges to parity at extreme RTT, where both clients are network-bound. Writes run at parity. Reproducible from TestBenchmarkSanity; method in PERFORMANCE.md. Prefer Apple's C client? One build tag (-tags libfdbc) swaps it in — same bytes on the wire.
Quickstart
Install the driver, then open a database, create a schema, and read and write — all from Go. The pure-Go client is the default backend; you only need a cluster file.
Install
go get fdb.dev/pkg/relational/sqldriverOpen a database, create a schema, write and read — in Go
package main
import (
"database/sql"
"fmt"
"log"
_ "fdb.dev/pkg/relational/sqldriver"
)
func main() {
db, err := sql.Open("fdbsql",
"fdbsql:///myapp?cluster_file=/etc/foundationdb/fdb.cluster&schema=main")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// Create the database, a schema template, and a schema.
db.Exec(`CREATE DATABASE /myapp`)
db.Exec(`CREATE SCHEMA TEMPLATE app
CREATE TABLE users (id BIGINT, name STRING, email STRING, PRIMARY KEY (id))
CREATE INDEX by_email ON users (email)`)
db.Exec(`CREATE SCHEMA /myapp/main WITH TEMPLATE app`)
// Write a row, then read it back.
db.Exec(`INSERT INTO users (id, name, email) VALUES (1, 'Alice', 'alice@example.com')`)
var name string
if err := db.QueryRow(
`SELECT name FROM users WHERE email = ?`, "alice@example.com",
).Scan(&name); err != nil {
log.Fatal(err)
}
fmt.Println(name) // Alice
}Or query the same data from the CLI
$ frl sql --database /myapp --schema main
fdb> SELECT name, email FROM users WHERE email = 'alice@example.com';
NAME │ EMAIL
──────┼───────────────────
Alice │ alice@example.com
(1 row)The Cascades planner picks the by_email index for that query — no full scan. The same store is reachable from Go's typed record API (store protobuf records directly); see the record-layer guide.
A client, and layers on top.
FoundationDB is an ordered, transactional key-value store — strict-serializable ACID, fault-tolerant, proven by deterministic simulation testing. It’s the storage substrate under systems like Snowflake and Apple’s CloudKit. Higher-level data models are built as layers on top. fdb.dev is the Go client and a growing set of them.
Pure-Go Client
A from-scratch FDB wire-protocol client — no cgo, faster reads, read-your-writes, retries, commit_unknown_result handling. Validated against libfdb_c 7.3.77.
Record Layer
Structured records, secondary indexes, versions, continuations, split records, schema evolution. Record format byte-identical to Java — share a cluster.
SQL Engine
A database/sql driver backed by a Cascades optimizer ported from Java’s fdb-relational-core: index selection, sort elimination, streaming aggregation.
Share a cluster with Java.
Wire compatibility is the project’s hard line, not a feature. Record, index, version, continuation, and split-record formats are byte-identical to Java Record Layer 4.12.11.0, and the client speaks the FoundationDB 7.3 wire protocol (validated against 7.3.77; 8.0 is future work). Enforced in CI against real FoundationDB by a Java conformance suite, a cross-backend differential, and a binding-stress tester — not mocks.