cockroachdb/cockroach
Patterns and conventions
Coding idioms that recur across the CockroachDB tree. The canonical style guide is docs/style.md.
Formatting
Always run crlfmt -w -tab 2 path.go after editing a Go file. It enforces 100-column code lines, 80-column comment lines, CRDB import grouping (stdlib / cockroachdb / others), and CRDB long-signature wrapping. It is not gofmt. Imports are auto-grouped on save by most editor integrations; otherwise crlfmt does it.
Errors
CockroachDB uses github.com/cockroachdb/errors everywhere. Key guidelines:
- Wrap with
errors.Wrapf(err, "context %s", arg)to add context. - Use
errors.Is/errors.Asfor sentinel checks. - Mark errors as redactable when they may carry user data:
errors.Newf(...)is preferred overfmt.Errorfbecause it captures redactable arguments. - Errors that cross network boundaries must be encodable: see
errors.EncodeError.
For CockroachDB-specific error types, see pkg/sql/sqlerrors/, pkg/server/srverrors/, and pkg/kv/kvpb/errors.go.
Logging
Use pkg/util/log rather than log from the standard library:
log.Infof(ctx, "starting replica %d", repl.RangeID)
log.VEventf(ctx, 2, "lock %s acquired by %s", key, txn.ID)
log.Errorf(ctx, "fatal error: %+v", err)%+v prints redactable arguments in their unredacted form; %v prints them with redaction markers. Always pass a context.Context so the logger can attach span info.
Verbose logging is gated by V-levels: prefer log.VEventf (which is also a tracing event) over log.V(2).Infof for new code.
Cluster-version gating
Any backwards-incompatible behavior must be gated on a cluster version. The pattern:
if !cv.IsActive(ctx, clusterversion.V25_4FooNew) {
// legacy path
return legacy()
}
return newPath()Add the version to pkg/clusterversion/cockroach_versions.go and write a migration in pkg/upgrade/upgrades/ if the upgrade is more than a feature toggle. See systems/cluster-version-and-upgrade.
Cluster settings
Runtime knobs live in pkg/settings/:
var fooEnabled = settings.RegisterBoolSetting(
settings.SystemVisible,
"kv.foo.enabled",
"whether foo is enabled",
true,
)Use the right Class: SystemOnly for host-only knobs, TenantWritable for per-tenant overrides, SystemVisible for read-only-from-tenant. Documented in docs/configuration.md.
Concurrency
CockroachDB has a few non-obvious primitives:
syncutil.Mutexinpkg/util/syncutil/— async.Mutexwith deadlock detection in race builds.stop.Stopperinpkg/util/stop/— owns goroutine lifecycles. Always launch goroutines withstopper.RunAsyncTask(orRunTask) to ensure they participate in shutdown.ctxgroupinpkg/util/ctxgroup/— likeerrgroup, but cancellation-aware.quotapoolinpkg/util/quotapool/— generic resource quota.
Never call go fn() in production code. Goroutines must be tracked.
Context propagation
Pass context.Context as the first argument to nearly every function (a few hot-path KV functions accept it as a separate field for performance). The context carries the trace span, logging tags, and cancellation. When you need to derive a new tag, use logtags.AddTag(ctx, "k", v).
Protobuf and wire compatibility
When changing a proto:
- Never change a field's tag number.
- Removing a field requires reservation:
reserved 5. - Renaming a field is fine on the wire but breaks Go callers — coordinate.
- Add a
// keepcomment inBUILD.bazelfor proto-only deps that gazelle would otherwise drop.
pkg/clusterversion/ gates the use of new wire fields when older nodes might still be in the cluster.
Tests
- Use table-driven tests where appropriate (
docs/style.mdhas examples). - Datadriven tests are encouraged for compiler-style code (parser, optimizer, MVCC).
defer leaktest.AfterTest(t)()at the start of any test that spawns goroutines.- Tests should not depend on
time.Now()directly; usehlc.NewClockForTesting. - Build skip directives (
skip.UnderRace,skip.UnderStress,skip.UnderShort) explicit and explained.
Naming
- Exported types/functions get GoDoc starting with the symbol name (
// Foo does …). - Test functions:
TestSomething,BenchmarkSomething,ExampleSomething. Sub-tests uset.Run("name", ...). - Files implementing one type/feature: name them after the type/feature (
replica_send.go). - Avoid stuttering:
kvserver.Store, notkvserver.KVServerStore.
Comments
Comments add depth, not repetition. From CLAUDE.md:
CockroachDB is a complex system. Write code under the assumption that future readers have basic familiarity but are not experts. Explain key concepts and abstractions, state lifecycles and ownership, use examples, and don't repeat the code in comments.
Release notes
User-visible changes need a release-note line in the commit body:
Release note (sql change): foo now supports bar.
Release note (bug fix): fixed crash when …
Release note (none)The bot enforces the format and rejects PRs without one.
Imports
Import alphabetical order, grouped:
- stdlib
github.com/cockroachdb/...packages- third-party
crlfmt will reformat imports for you.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.