Skip to main content

Go API Reference

The SochDB Go SDK is remote-first: a plain go build / go get compiles only the remote (gRPC) and IPC clients plus the pure-Go helpers. The in-process embedded FFI engine (and everything that depends on it) is gated behind the sochdb_embedded build tag.

  • Module: github.com/sochdb/sochdb-go
  • Version: 0.4.5 (exported as sochdb.Version)
  • Go version: 1.24.0
  • License: Apache-2.0 (the language SDK; the core Rust engine is AGPL-3.0-or-later)
import "github.com/sochdb/sochdb-go"

func main() {
println(sochdb.Version) // "0.4.5"
}

Installation

go get github.com/sochdb/sochdb-go

The embedded engine, embedded semantic cache, and the embedded Memory System are only compiled in when you build with the embedded tag (which additionally requires the native libsochdb_storage library, CGO, and pkg-config):

go build -tags sochdb_embedded ./...
"Remote-first" means the default build target, not transport auto-selection

There is no unified Client type or Config struct that auto-selects remote vs embedded. "Remote-first" means the non-tagged build only includes the remote/IPC clients and the pure-Go helpers; the FFI engine is excluded unless you pass -tags sochdb_embedded. The three connection entrypoints are distinct, explicitly named functions (below).

Connecting

There are three clients, each with its own constructor.

The default-build path. Talks to a SochDB gRPC server.

import "github.com/sochdb/sochdb-go"

// Convenience: connect with default options to an address.
client, err := sochdb.GrpcConnect("localhost:50051")
if err != nil {
panic(err)
}
defer client.Close()

// Full options form.
client, err = sochdb.NewGrpcClient(sochdb.GrpcClientOptions{
Address: "localhost:50051",
Timeout: 30 * time.Second,
Secure: false, // see caution below
})

GrpcClientOptions defaults: Address falls back to "localhost:50051" when empty, Timeout defaults to 30 * time.Second, and the max receive message size is 100 MiB.

TLS is not implemented

Setting Secure: true returns the error "secure connections not yet implemented". Only insecure (plaintext) credentials are available today. Do not expose a gRPC endpoint over an untrusted network until TLS lands.

Key-value operations

IPC client

err := client.Put([]byte("greeting"), []byte("Hello, SochDB!"))
value, err := client.Get([]byte("greeting")) // ([]byte, error)
err = client.Delete([]byte("greeting"))

// Path-based hierarchical keys.
err = client.PutPath("users/alice/name", []byte("Alice"))
name, err := client.GetPath("users/alice/name")

For prefix iteration prefer Scan, which returns all matches at once:

results, err := client.Scan("users/") // []KeyValue
for _, kv := range results {
fmt.Printf("%s = %s\n", kv.Key, kv.Value)
}

// Paged variant.
page, err := client.Query("users/", 100 /*limit*/, 0 /*offset*/)
type KeyValue struct {
Key []byte
Value []byte
}

gRPC client

// Convenience helpers (namespace-scoped, string keys).
err := client.PutKv(ctx, "default", "greeting", []byte("Hello"))
value, err := client.GetKv(ctx, "default", "greeting")

// Low-level forms.
err = client.GrpcPut([]byte("k"), []byte("v"), "default", 0 /*ttlSeconds*/)
value, found, err := client.GrpcGet([]byte("k"), "default")
err = client.GrpcDelete([]byte("k"), "default")

Embedded engine

err := db.Put([]byte("k"), []byte("v")) // auto-transaction
value, err := db.Get([]byte("k"))
err = db.Delete([]byte("k"))

Prefix scans (embedded)

ScanPrefix returns a *ScanIterator. You must call Close() — the iterator holds an open transaction until you do.

it := db.ScanPrefix([]byte("users/"))
defer it.Close()

for {
key, val, ok := it.Next()
if !ok {
break
}
fmt.Printf("%s = %s\n", key, val)
}
if err := it.Err(); err != nil {
panic(err)
}
Do not split queue keys on /

Queue keys contain binary big-endian fields that may include the / byte (0x2F). Splitting a queue key on / is unsafe; use the SDK's DecodeQueueKey (positional parsing) instead.

Transactions

Commit returns error only in the Go SDK — it does not return a commit timestamp. (A uint64 is returned by BeginTransaction as the transaction ID, and by the embedded Checkpoint, but not by Commit.)

IPC client

txnID, err := client.BeginTransaction() // (uint64, error)
// ... perform writes within the transaction ...
err = client.CommitTransaction(txnID) // error only
// or, on failure:
err = client.AbortTransaction(txnID)

Embedded engine

// Closure form (recommended): auto-commit on success, auto-abort on error.
err := db.WithTransaction(func(txn *embedded.Transaction) error {
// ... use txn ...
return nil
})

// Explicit form.
txn := db.Begin()
// txn.ID() uint64, txn.SnapshotTS() uint64
if err := txn.Commit(); err != nil { // error only
// A serialization failure surfaces as:
// "SSI conflict: transaction aborted due to serialization failure"
_ = txn.Abort()
}

SQL

No SQL surface in the Go SDK

The Go SDK has no exported SQL execution method. The OpExecuteSQL opcode is defined internally but is not wired to any method, and IPCClient.Query() is a prefix query (path + limit + offset), not SQL. The only Execute() in the SDK belongs to the context builder (below) and is unrelated to SQL. For SQL, use the gRPC server with another SDK or the SQL API.

Namespaces and collections

gRPC client

err := client.CreateCollection("docs", 384 /*dimension*/, "default" /*namespace*/)

ids, err := client.AddDocuments("docs", []sochdb.GrpcDocument{
{ID: "1", Content: "hello", Embedding: emb, Metadata: map[string]string{"k": "v"}},
}, "default")

hits, err := client.SearchCollection("docs", queryVec, 10 /*k*/, "default")

Embedded / pure-Go handles

// Namespace handle.
coll, err := ns.CreateCollection(sochdb.CollectionConfig{
Name: "docs",
Dimension: 384,
Metric: sochdb.DistanceMetricCosine, // "cosine" | "euclidean" | "dot"
Indexed: true,
})
// Other namespace ops: Collection(name), GetOrCreateCollection,
// DeleteCollection(name), ListCollections().

// Collection ops.
id, err := coll.Insert(vector, map[string]interface{}{"title": "Intro"}, "doc-1")
results, err := coll.Search(sochdb.SearchRequest{
QueryVector: queryVec,
K: 10,
IncludeMetadata: true,
})
count, err := coll.Count()
Embedded vector search is brute-force

The HNSW knobs in CollectionConfig (HNSWM, HNSWEfConstruction) are stored as JSON metadata only. The embedded Collection.Search performs a brute-force cosine similarity over a prefix scan, sorted descending and truncated to K. Use the gRPC server for real HNSW indexing (its CreateIndex builds an HNSW index, though the HNSW parameters are not configurable from the Go client).

Vector indexes (gRPC)

err := client.CreateIndex("vectors", 384 /*dimension*/, "cosine")
n, err := client.InsertVectors("vectors", ids, vectors) // (int, error)
hits, err := client.GrpcSearch("vectors", queryVec, 10 /*k*/)
for _, h := range hits {
fmt.Printf("id=%d distance=%f\n", h.ID, h.Distance) // GrpcSearchResult
}

The accepted metric strings are "l2", "dot" / "dot_product", and anything else falls back to cosine. There is no DropIndex / DeleteIndex in the Go SDK.

Memory System

Embedded-only

The Memory System requires -tags sochdb_embedded. The shared types in memory_types.go (Entity, Relation, Assertion, RawAssertion, CanonicalFact, etc.) always compile, but the pipelines below do not link in without the tag.

// Extraction: compile LLM output into typed Entity / Relation / Assertion.
pipeline := sochdb.NewExtractionPipeline(db, "default", schema)
result, err := pipeline.Extract(text)
err = pipeline.ExtractAndCommit(text)

// Consolidation: merge multi-source RawAssertions into CanonicalFacts.
c := sochdb.NewConsolidator(db, "default", config)
c.Add(rawAssertion)
n, err := c.Consolidate() // (int, error)

// Retrieval: BM25 + semantic hybrid.
r := sochdb.NewHybridRetriever(db, "default", config)
err = r.IndexDocuments(docs)
resp, err := r.Retrieve("query", allowedSet)

ExtractorFunction is func(text string) (map[string]interface{}, error). A standalone scorer is available via NewBM25Scorer(k1, b float64).

Policy and access pre-filtering

These are pure-Go types (always compiled) for tenant isolation and result pre-filtering:

// Namespace policies: Strict | Explicit | Permissive.
var p sochdb.NamespacePolicy = sochdb.NamespacePolicyStrict

// AllowedSet implementations for pre-filtering retrieval.
allowed := sochdb.NewNamespaceAllowedSet("tenant-a")
// Also: NewIdsAllowedSet, NewFilterAllowedSet, NewAllAllowedSet.

Cross-namespace access is expressed with NamespaceGrant.

Queue

The priority queue is always compiled (pure-Go over a backing store).

q := sochdb.NewPriorityQueue(db, "jobs", &sochdb.QueueConfig{
Name: "jobs",
VisibilityTimeout: 30000, // ms (default)
MaxRetries: 3, // default
DeadLetterQueue: "jobs-dlq",
})

taskID, err := q.Enqueue(10 /*priority*/, payload, metadata)
task, err := q.Dequeue("worker-1")
err = q.Ack(taskID)
err = q.Nack(taskID)
stats, err := q.Stats()
purged, err := q.Purge()

Task states: pending, claimed, completed, dead_lettered. NewPriorityQueue is also aliased as CreateQueue.

Semantic cache

There are three implementations.

err := client.CachePut("answers", "key", "value", keyEmbedding, 3600 /*ttlSeconds*/)
value, found, err := client.CacheGet("answers", queryEmbedding, 0.9 /*threshold*/)

Context builder

A pure-Go fluent builder for assembling token-budgeted context windows.

result, err := sochdb.NewContextQueryBuilder().
ForSession("session-123").
WithBudget(4096). // default 4096 tokens
SetFormat(sochdb.FormatTOON). // default; also FormatJSON, FormatMarkdown
SetTruncation(sochdb.TailDrop). // default; also HeadDrop, Proportional
Literal("system", 100, "You are a helpful assistant.").
Execute() // (*ContextResult, error)

TOON is the default wire/context format (documented as 40-66% fewer tokens than JSON).

Graph

err := client.AddNode("default", "node-1", "person", props)
err = client.AddEdge("default", "node-1", "node-2", "knows", props)
res, err := client.Traverse("default", "node-1", 3 /*maxDepth*/, "bfs" /*order*/)

Tracing

Both clients expose observability spans.

// IPC
trace, err := client.StartTrace(/* ... */)
span, err := client.StartSpan(/* ... */)
err = client.EndSpan(/* ... */)

// gRPC has the equivalent StartTrace / StartSpan / EndSpan.
No routing module

The Go SDK has no "routing" / "router" subsystem. The only *Policy types are IndexPolicy (storage layout) and NamespacePolicy (tenant isolation); neither is a query router.

Errors

The SDK exposes sentinel errors for errors.Is matching plus typed error structs.

import "errors"

if errors.Is(err, sochdb.ErrNotFound) {
// key/value not present
}

Sentinel errors

SentinelMeaning
ErrClosedOperation on a closed client/database.
ErrNotFoundKey, collection, or record not found.
ErrInvalidResponseMalformed response from the server.
ErrDatabaseLockedDatabase is locked by another process.
ErrLockTimeoutTimed out acquiring a lock.
ErrEpochMismatchEpoch fencing mismatch.
ErrSplitBrainSplit-brain condition detected.

Error structs

ConnectionError (wraps the underlying error via Unwrap), ProtocolError, ServerError, TransactionError, and SochDBError{Op, Message}.

Lock/concurrency error structs implement Is() so they match the sentinels above: LockError, DatabaseLockedError (→ ErrDatabaseLocked), LockTimeoutError (→ ErrLockTimeout), EpochMismatchError (→ ErrEpochMismatch), and SplitBrainError (→ ErrSplitBrain).

Namespace/collection errors: NamespaceNotFoundError, NamespaceExistsError, CollectionNotFoundError, CollectionExistsError. Format errors: FormatConversionError{FromFormat, ToFormat, Reason}.

See also