Design and Architecture of CockroachDb

Key-Value API

// Supplied with every request.
RequestHeader {
  // Specify snapshot_timestamp for snapshot reads.
  // In microseconds since the epoch.
  // This value cannot be specified with tx_id.
  optional uint64 snapshot_timestamp = 1;
  // Set if a transaction is underway. Specify as ‘0’
  // to start a new transaction.
  optional string tx_id = 2;
  // The maximum wall time seen by the client to
  // date. This should be supplied with successive
  // transactions for linearizability for this client.
  option uint64 max_wall_time = 3;
}

// Supplied with every response.
ResponseHeader {
  // Error/Success result.
  message {
    optional message {
      int code = 1;
      optional string message = 2;
      optional string details = 3;
    } error = 1;
  } result = 1;
  // Returned if transaction is underway.
  optional string tx_id = 2;
}

// Multiple values at the same key are supported
// based on timestamp.
Value {
  optional string value = 1;
  // Timestamp of value in microseconds since epoch.
  optional uint64 timestamp = 2;
  // Expiration in microseconds.
  optional uint64 expiration = 3;
}

// Test if key is present.
ContainsRequest {
  RequestHeader header = 1;
  string key = 2;  // must be non-empty
}
ContainsResponse {
  ResponseHeader header = 1;
  bool exists = 2;
}

// Retrieves value for key.
GetRequest {
  RequestHeader header = 1;
  string key = 2;  // must be non-empty
}
GetResponse {
  ResponseHeader header = 1;
  optional Value value = 2;  // present if exists
}

// Puts value for key.
// Conditionally puts a value for key if exp_value is set.
//   - Returns true and sets value if exp_value equals
//     existing value.
//   - If key doesn’t exist and exp_value is empty, sets
//     value and returns true.
//   - Otherwise, returns false.
PutRequest {
  RequestHeader header = 1;
  string key = 2;  // must be non-empty
  Value value = 3;  // empty to test for non-existence
  optional Value exp_value = 4;  // omit to verify
}
PutResponse {
  ResponseHeader header = 1;
  optional Value conditional_fail = 2;  // set if conditional put failed with actual value
}

// Increments the value for key, interpreting the existing
// value as a varint64.
// Returns the new value. If the value could not be
// decoded as specified, returns an error.
IncrementRequest {
  RequestHeader header = 1;
  string key = 2;
  int64 increment = 3;
}
IncrementResponse {
  ResponseHeader = 1;
  Value new_value = 2;  // value is varint64 encoded
}

// Deletes key.
DeleteRequest {
  RequestHeader header = 1;
  string key = 2;  // must be non-empty
}
DeleteResponse {
  ResponseHeader header = 1;
}

// Deletes range of keys.
DeleteRangeRequest {
  RequestHeader header = 1;
  string start_key = 2;  // empty to start at first key
  string end_key = 3;  // non-inclusive; if empty, deletes all
}
DeleteRangeResponse {
  ResponseHeader header = 1;
  int num_deleted = 2;
}

// Scans multiple values in a range of keys.
ScanRequest {
  RequestHeader header = 1;
  string start_key = 2;  // empty to start at first key
  string max_key = 3;  // optional max key; empty to ignore
  int max_results = 4;  // must be > 0
}
ScanResponse {
  ResponseHeader header = 1;
  repeated message {
    string key = 1;  // will be non-empty
    Value value = 2;  // will be non-empty
  } key_values = 2;  // empty if at end of key range
  string last_key = 3;  // non-empty if key_values were returned
}

// Commits or rolls back an ongoing transaction.
EndTransactionRequest {
  RequestHeader header = 1;
  bool commit = 2;  // false to abort and rollback
}
EndTransactionResponse {
  ResponseHeader header = 1;
  optional uint64 commit_timestamp = 2;
  optional uint64 commit_wait = 3;  // remaining wait (us)
}

// Scans and deletes messages from a recipient message queue.
ReapQueueRequest {
  // Must be part of a transaction.
  RequestHeader header = 1;
  string recipient_key = 2;
  int max_results = 3;  // must be > 0
}
ReapQueueResponse {
  ResponseHeader header = 1;
  repeated string messages = 2;
}

// Used internally for accounting.
AccountingRequest {
  RequestHeader header = 1;
  enum AccountingType {
    StableCount = 1;
    EventOccurrence = 2;
  }
  AccountingType type = 2;
  string key = 3;
  int64 timestamp = 4;  // floor(walltime, HOUR)
  repeated int64 counts = 5; // one per minute
}
AccountingResponse {
  ResponseHeader header = 1;
}

// Queues updates for eventual execution or delivery.
QueueRequest {
  RequestHeader header = 1;
  // Either “updates” or “delivery” must be specified.
  optional message {
    optional PutRequest = 1;
    optional IncrementRequest = 2;
    optional DeleteRequest = 3;
    optional DeleteRangeRequest = 4;
    optional AccountingRequest = 5;
  } updates = 2;  // execution-only
  optional message {
    string recipient_key = 1;
    string client_message = 2;
  } delivery = 3;  // delivered to recipient key
}
QueueResponse {
  ResponseHeader header = 1;
}

// Sends a batch of updates.
BatchRequest {
  optional PutRequest = 1;
  optional IncrementRequest = 2;
  optional DeleteRequest = 3;
  optional DeleteRangeRequest = 4;
  optional ReapQueueRequest = 5;
  optional EndTransactionRequest = 6;
  optional AccountingRequest = 7;
  optional QueueRequest = 8;
}
BatchResponse {
  repeated message {
    optional PutResponse = 1;
    optional IncrementResponse = 2;
    optional DeleteResponse = 3;
    optional DeleteRangeResponse = 4;
    optional ReapQueueResponse = 5;
    optional EndTransactionResponse = 6;
    optional AccountingResponse = 7;
    optional QueueResponse = 8;
  } responses = 1;
}