Skip to main content

Requests

A request queries or updates the database state.

A request consists of one or more events of the same type sent to the cluster in a single message. For example, a single request can create multiple transfers but it cannot create both accounts and transfers.

The cluster commits an entire request at once. Events are applied in series, such that successive events observe the effects of previous ones and event timestamps are totally ordered.

Each request receives one reply message from the cluster. The reply contains one result for each event in the request.

Request Types

More request types, including more powerful queries, are coming soon!

Events and Results

Each request has a corresponding event and result type:

Request TypeEventResult
create_accountsAccountCreateAccountResult
create_transfersTransferCreateTransferResult
lookup_accountsAccount.idAccount or nothing
lookup_transfersTransfer.idTransfer or nothing
get_account_transfersAccountFilterTransfer or nothing
get_account_balancesAccountFilterAccountBalance or nothing

Idempotency

Events that create objects are idempotent. The first event to create an object with a given id will receive the ok result. Subsequent events that attempt to create the same object will receive the exists result.

Batching Events

To achieve high throughput, TigerBeetle amortizes the overhead of consensus and I/O by batching many events in each request.

In the default configuration, the maximum batch sizes for each request type are:

Request TypeRequest Batch Size (Events)Reply Batch Size (Results)
lookup_accounts81908190
lookup_transfers81908190
create_accounts81908190
create_transfers81908190
get_account_transfers18190
get_account_balances18190

TigerBeetle clients automatically batch events. Therefore, it is recommended to share the client instances between multiple threads or tasks to have events batched transparently.

Linked Events

Events within a request succeed or fail independently unless they are explicitly linked using the flags.linked (Account.flags.linked or Transfer.flags.linked).

When the linked flag is specified, it links the outcome of a Transfer or Account creation with the outcome of the next one in the request. These chains of events will all succeed or fail together.

The last event in a chain is denoted by the first Transfer or Account without this flag.

The last Transfer or Account in a request may never have the flags.linked set, as it would leave a chain open-ended. Attempting to do so will result in the linked_event_chain_open error.

Multiple chains of events may coexist within a request to succeed or fail independently.

Events within a chain are executed in order, or are rolled back on error, so that the effect of each event in the chain is visible to the next. Each chain is either visible or invisible as a unit to subsequent transfers after the chain. The event that was the first to fail within a chain will have a unique error result. Other events in the chain will have their error result set to linked_event_failed.

Linked Transfers Example

Consider this set of Transfers as part of a request:

TransferIndex in Requestflags.linked
A0false
B1true
C2true
D3false
E4false

If any of transfers B, C, or D fail (for example, due to exceeds_credits), then B, C, and D will all fail. They are linked.

Transfers A and E fail or succeed independently of B, C, D, and each other.

After the chain of linked events has executed, the fact that they were linked will not be saved. To save the association between Transfers or Accounts, it must be encoded into the data model, for example by adding an ID to one of the user data fields.

Guarantees

  • A request executes within the cluster at most once.
  • Requests do not time out. Clients will continuously retry requests until they receive a reply from the cluster. This is because in the case of a network partition, a lack of response from the cluster could either indicate that the request was dropped before it was processed or that the reply was dropped after the request was processed. Note that individual pending transfers within a request may have timeouts.
  • Requests retried by their original client session receive identical replies.
  • Requests retried by a different client (same request body, different session) may receive different replies.
  • Events within a request are executed in sequence. The effects of a given event are observable when the next event within that request is applied.
  • Events within a request do not interleave with events from other requests.
  • All events within a request batch are committed, or none are. Note that this does not mean that all of the events in a batch will succeed, or that all will fail. Events succeed or fail independently unless they are explicitly linked
  • Once committed, an event will always be committed — the cluster's state never backtracks.
  • Within a cluster, object timestamps are unique and strictly increasing. No two objects within the same cluster will have the same timestamp. Furthermore, the order of the timestamps indicates the order in which the objects were committed.