Skip to main content

Multi-Debit, Multi-Credit Transfers

TigerBeetle is designed for maximum performance. In order to keep it lean, the database only supports simple transfers with a single debit and a single credit.

However, you'll probably run into cases where you want transactions with multiple debits and/or credits. For example, you might have a transfer where you want to extract fees and/or taxes.

Read on to see how to implement one-to-many and many-to-many transfers!

Note that all of these examples use the Linked Transfers flag (flags.linked) to ensure that all of the transfers succeed or fail together.

One-to-Many Transfers

Transactions that involve multiple debits and a single credit OR a single debit and multiple credits are relatively straightforward.

You can use multiple linked transfers as depicted below.

Single Debit, Multiple Credits

This example debits a single account and credits multiple accounts. It uses the following accounts:

  • A source account A, on the USD ledger.
  • Three destination accounts X, Y, and Z, on the USD ledger.
LedgerDebit AccountCredit AccountAmountflags.linked
USDAX10000true
USDAY50true
USDAZ10false

Multiple Debits, Single Credit

This example debits multiple accounts and credits a single account. It uses the following accounts:

  • Three source accounts A, B, and C on the USD ledger.
  • A destination account X on the USD ledger.
LedgerDebit AccountCredit AccountAmountflags.linked
USDAX10000true
USDBX50true
USDCX10false

Many-to-Many Transfers

Transactions with multiple debits and multiple credits are a bit more involved (but you got this!).

This is where the accounting concept of a Control Account comes in handy. We can use this as an intermediary account, as illustrated below.

In this example, we'll use the following accounts:

  • Two source accounts A and B on the USD ledger.
  • Three destination accounts X, Y, and Z, on the USD ledger.
  • A compound entry control account Control on the USD ledger.
LedgerDebit AccountCredit AccountAmountflags.linked
USDAControl10000true
USDBControl50true
USDControlX9000true
USDControlY1000true
USDControlZ50false

Here, we use two transfers to debit accounts A and B and credit the Control account, and another three transfers to credit accounts X, Y, and Z.

If you looked closely at this example, you may have noticed that we could have debited B and credited Z directly because the amounts happened to line up. That is true!

For a little more extreme performance, you might consider implementing logic to circumvent the control account where possible, to reduce the number of transfers to implement a compound journal entry.

However, if you're just getting started, you can avoid premature optimizations (we've all been there!). You may find it easier to program these compound journal entries always using a control account -- and you can then come back to squeeze this performance out later!