Bulk ingest routes
Move decoded rows in bulk with write batches and native bulk frames, or one row per statement in plain SQL.
Turn decoded chain events into typed, versioned entity state inside the engine, with each writer owning its own slice of the row.
The problem
On-chain data is the messiest input in the industry: events arrive out of order, come back on a reorganization, and mean nothing until they are folded into the entity state your product actually queries.
You bolt that together from an indexer, a queue, a transform layer and a warehouse, and then a holder count or a balance differs depending on which copy answered, because each copy applied the events in a different order.
What you want is ordering that does not depend on arrival, per-entity rows that several producers can extend independently, and point-in-time reads, inside the database rather than beside it.
Architecture
Decoded events land in one table and a transformation folds them into one slice of a versioned entity table; other producers write their own slices of the same row, and the engine settles which version wins, so late and shuffled writes converge to the same state.
Decoded events land in an append-only table, one row at a time through SQL or in bulk through write batches and native bulk frames.
Entity state stays current on its own: CREATE TRANSFORMATION folds events per entity into one ATTRIBUTE GROUP, with MAX and COUNT lanes.
Add a new slice to the row while everything keeps running, with ALTER TABLE … ADD ATTRIBUTE GROUP, and let another producer write it.
Reread the winners exactly as they stood at a commit, with AS OF COMMIT and the sequence from a write receipt.
Examples
CREATE TRANSFORMATION balance_activity INTO balances ATTRIBUTE GROUP activity ASSELECT chain_id, recipient AS address, token, COUNT(*) AS transfer_count, MAX(transferred_at) AS last_transfer_at, MAX(_index) AS activity_indexFROM transfersGROUP BY chain_id, recipient, token;SELECT address, token, amount, updated_atFROM balancesWHERE chain_id = 1 AND address = '0x9c2e4f1a';SELECT address, token, amountFROM balances AS OF COMMIT 42WHERE chain_id = 1;The examples use the same two tables on every page. See the SQL reference for full syntax.
Capabilities
Move decoded rows in bulk with write batches and native bulk frames, or one row per statement in plain SQL.
Entity state stays current from the event table, with no indexer state layer to run, with CREATE TRANSFORMATION.
Several producers each own a slice of one keyed row, and no group ever overwrites another.
In-order, shuffled and late writes all converge to the same state, with VALID BY and REVISION BY.
Read the winners as they stood at any commit sequence, with AS OF COMMIT.
Add a group or a column while running transformations keep running.
Learn more
Fold a stream of events into one slice of a row, then read it as it was at any commit.