Open-Source Wikis

/

etcd

/

Reference

/

Data models

etcd-io/etcd

Data models

What etcd stores, in protobuf and on disk.

Protobuf

The public protobuf surface lives under api/:

Type Source Carried fields
mvccpb.KeyValue api/mvccpb/kv.proto key, create_revision, mod_revision, version, value, lease
mvccpb.Event api/mvccpb/kv.proto type (PUT/DELETE), kv, prev_kv
etcdserverpb.RangeRequest api/etcdserverpb/rpc.proto key, range_end, limit, revision, sort_order/target, serializable, keys_only, count_only, min/max_*_revision
etcdserverpb.PutRequest same key, value, lease, prev_kv, ignore_value, ignore_lease
etcdserverpb.TxnRequest same compare, success, failure
etcdserverpb.Compare same result, target, target_union (one of version, create_revision, mod_revision, value, lease)
etcdserverpb.WatchRequest / WatchResponse same streaming envelopes
etcdserverpb.LeaseGrantRequest etc. same lease lifecycle
etcdserverpb.MemberAdd... etc. same cluster membership
authpb.User, Role, Permission api/authpb/auth.proto RBAC
membershippb.ClusterVersionSetRequest, Member, ClusterMembersJointSetRequest, DowngradeInfoSetRequest api/membershippb/membership.proto Cluster metadata in Raft entries
versionpb.Version api/versionpb/version.proto Cluster version negotiation

Internal-only protobuf:

Type Source Use
etcdserverpb.InternalRaftRequest api/etcdserverpb/raft_internal.proto Envelope serialized into every Raft Entry.Data
walpb.Record server/storage/wal/walpb/record.proto WAL record header
snappb.SnapshotHeader server/etcdserver/api/snap/snappb/snap.proto Raft snapshot file header
leasepb.Lease server/lease/leasepb/lease.proto On-disk lease persistence
v3lockpb, v3electionpb server/etcdserver/api/v3lock/v3lockpb/, v3election/v3electionpb/ Lock/Election services

On-disk layout

Data directory tree (<data-dir>/):

<data-dir>/
├── member/
│   ├── wal/                          # write-ahead log segments
│   │   ├── 000000000000000a-...wal
│   │   └── 000000000000000b-...wal
│   └── snap/
│       ├── 0000000000000007-0000000000000064.snap   # raft snapshot
│       ├── ...
│       └── db                       # bbolt database (MVCC + everything)
└── (lock files)

Bbolt buckets

Defined in server/storage/schema/bucket.go:

Bucket Contents
key <revision-bytes>mvccpb.KeyValue
lease <leaseID-bytes>leasepb.Lease
auth enabled flag, revision counter
authUsers <username>authpb.User
authRoles <role>authpb.Role
members <memberID-bytes> → JSON-encoded Member
members_removed tombstones for removed members
cluster clusterVersion, downgrade
alarm active alarms (NOSPACE, CORRUPT)
meta consistent_index, term, scheduled compaction, storage version

The on-disk version stamp lives in the meta bucket and is read by server/storage/schema/version.go. It gates compatibility — a 3.5 binary refuses to open a DB written by 3.6 unless downgrade was previously enabled.

Revision encoding

server/storage/mvcc/revision.go encodes revisions as 16-byte (main, sub) big-endian. The bbolt key bucket is keyed by this 16-byte revision, not by user keys; lookup uses the in-memory treeIndex (server/storage/mvcc/index.go) to translate a user key + revision range into bucket keys.

WAL record

walpb.Record is the on-disk WAL row:

Field Purpose
Type metadataType, entryType, stateType, crcType, snapshotType
CRC Running CRC checkpoint
Data Type-specific payload (e.g. a raftpb.Entry for entryType)

Cross-references

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Data models – etcd wiki | Factory