# Transactions

Commit one atomic decision across up to 64 keys with Ferrite atomic property envelopes.

Ferrite Transactions, implemented by the Atomic Property Envelope (APE), let
you update several keys with one commit decision. Readers never observe a
partially applied envelope.

## When to use transactions

Use a transaction for invariants that cross records: reserve inventory while
creating an order, hold a booking slot while recording its owner, or update an
account balance with its idempotency ledger.

```text
inventory/product-42  stock: 8 → 7
order/order-91        absent → pending
idempotency/checkout  absent → order-91
```

All three changes commit or none do.

## Keep the envelope bounded

One envelope can cover 1 to 64 keys. This is a deliberate boundary: model a
domain decision, not an unbounded batch job. For large fan-out, commit the
authoritative state and outbox record atomically, then process downstream work
through a Queue.

## Handle conflicts

Transactions use expected versions to reject stale decisions. On conflict,
reload the current state and reevaluate the business rule. Do not retry an old
decision indefinitely.

The shop uses transactions for guarded inventory and order state. The calendar
uses them to ensure two requests cannot own the same time slot.

See [Key-value Store](/developers/store/) for individual records and
[Workflows](/developers/workflows/) for long-running transitions.
