INSERT
Insert typed rows into append, keyed, and attribute tables.
Values
Specify columns explicitly in production code:
INSERT INTO trades (id, market, price, quantity, observed_at) VALUES
(101, 'BTC-USD', 60123.25, 2, '2026-07-09 14:00:00.000000'),
(102, 'ETH-USD', 3310.50, 4, '2026-07-09 14:00:01.000000');Without a column list, values must match the table's declared column order:
INSERT INTO counters VALUES (1, 10);The binder checks column names, arity, types, nullability, and required values.
Defaults are evaluated for omitted columns that declare DEFAULT.
Keyed behavior
An insert into a keyed table creates or replaces current state for the primary key:
INSERT INTO balances (address, asset, balance)
VALUES ('alice', 'USD', 100);
INSERT INTO balances (address, asset, balance)
VALUES ('alice', 'USD', 125);The current row for ('alice', 'USD') is now 125. This is key replacement,
not a multi-statement upsert transaction.
Attribute values
Supply the entity key and the attributes being changed:
INSERT INTO account_attributes (account_id, balance, tier) VALUES
(1, 100, 'gold'),
(2, 200, 'silver');
INSERT INTO account_attributes (account_id, balance)
VALUES (1, 125);The projection reconstructs the latest attribute values for each entity.
Statement atomicity and durability
Rows in one INSERT ... VALUES statement are validated as a unit. For durable
policies, visibility is published after the statement's commit manifest is
accepted. The acknowledgement point then follows the configured WAL sync mode
and table policy.
Do not split a logical atomic batch across separate SQL requests: the current engine has no multi-statement transaction.
Binary block ingest
Status: Experimental
The wire protocol also supports typed columnar blocks for high-throughput ingest. It avoids SQL literal parsing while preserving schema and type validation. Use a driver that implements the current block format and enforce server-side block-size limits. See the wire protocol.