Pipelines

Large values and LOBs

How SQL Flow captures, loads and applies large values such as nvarchar(max), CLOB and bytea, per source and target, and the limits that apply.

Large values, or LOBs, are column values too big to travel inside an ordinary log record: varchar(max), nvarchar(max), varbinary(max), xml, text and image on SQL Server, CLOB, NCLOB and BLOB on Oracle, and large text, bytea and BLOB values elsewhere. SQL Flow never truncates a large value to fit. It either writes the whole value or stops with a message that names the value and the limit.

How large values are captured

Source and capture modeWhere the value comes fromAn update that doesn't change the value
SQL Server DirectLogThe transaction log on SQL Server 2022 and 2025, and for xml columns on every supported version. Otherwise a read from the table by key.Left out of the change. The target keeps its value.
SQL Server PollingA read from the table by primary key, for a value stored off-row.The whole current row is written.
SQL Server ReconstructionAn update carries the row's current value, read by key. text, ntext, image and xml are read as their (max) equivalents.The current value is written.
SQL Server and Azure SQL Native CDCThe CDC change tables, as SQL Server captured them.As CDC recorded it.
Oracle LogMinerLogMiner, or a read from the table as of the change's commit SCN when LogMiner doesn't return the value in full.Left out of the change. The target keeps its value.
Oracle DirectLogThe redo where it is complete, otherwise a read from the table as of the commit SCN.Left out of the change. The target keeps its value.
PostgreSQL logical replicationThe replication stream.An unchanged stored (TOAST) value is left untouched at the target.
MySQL binlogThe full row images.The full row is written.
Sybase ASE DirectLogNot captured: a table with a text, unitext or image column is refused. Capture it with Reconstruction.Not applicable.
Sybase ASE ReconstructionThe value's pages on the data and LOB devices, through the log broker.Only the key and changed columns are written.

Reads by key give the current value

When SQL Server DirectLog or Polling reads a value from the table, it gets the row as it is now, not as it was at the change. The target converges to the source, but may skip an intermediate version of a large value. SQL Server DirectLog reads by key on versions before 2022 (except for xml columns), and for compressed, partitioned, FILESTREAM, memory-optimized, sparse and encrypted columns.

Source requirements

  • Oracle LogMiner reads the historical value, so it needs enough undo and the FLASHBACK privilege on the tables. If the history is gone, capture stops; it never substitutes the current value.
  • Oracle DirectLog needs SecureFile LOBs with RETENTION MIN of at least 3,600 seconds and Flashback Database on, or RETENTION MAX with a MAXSIZE, and guaranteed undo retention. See Oracle DirectLog requirements.
  • MySQL needs binlog_row_image=FULL and an empty binlog_row_value_options; the start refuses PARTIAL_JSON. One binlog event can be at most 1 GiB.
  • Sybase ASE Reconstruction may run checkpoint in the source database so that a value's pages are on disk before it reads them. A value whose page chain is longer than 4,096 pages is refused with LOB chain exceeded 4096 pages; refusing to walk a runaway/corrupt chain.

SQL Server DirectLog: max text repl size

When a selected table has large-value columns, the server option max text repl size must be -1 (unlimited) or 2147483647. Once a table is marked for capture, SQL Server applies this option to every writer, and a longer write fails with error 7139. SQL Flow never changes a server option, and doesn't mark these tables until the option is met. The Prepare step shows the requirement. A DBA with ALTER SETTINGS (sysadmin or serveradmin) runs:

EXEC sys.sp_configure N'max text repl size', -1;
RECONFIGURE;

RECONFIGURE also activates any other sp_configure change that is pending on the instance.

The initial load

For a SQL Server source in DirectLog or Reconstruction mode, a table whose rows all hold at most 8 MiB of large values loads like any other table. A table with a larger row loads each row as an INSERT followed by updates that stream the large values, in one target transaction per row.

This streamed load runs into SQL Server, Azure SQL, SQL database in Fabric, Oracle and PostgreSQL targets. It reads the source without locks, so the source database needs READ_COMMITTED_SNAPSHOT or ALLOW_SNAPSHOT_ISOLATION on. An interrupted streamed load starts those tables again from the beginning.

Allow streamed large-object loads despite triggers

Because each row arrives as an INSERT and then updates, a target trigger sees different statements than it would for one INSERT. When a mapped target table has an enabled trigger, the streamed load is refused until you tick Allow streamed large-object loads despite triggers on the wizard's Target step. Tick it only if your triggers accept that. The option key is lobInitialLoadAcceptsInsertThenStreamedUpdates, and it is off by default.

Size limits

WhereLimitWhen it is exceeded
SQL Server target2,147,483,647 bytes per valueThe value is refused before it is sent.
PostgreSQL targetAbout 1 GiB per value, PostgreSQL's limit for an ordinary fieldRefused. Store the column as a PostgreSQL large object with the postgresLargeObjectColumns option, which holds up to 4 TiB.
Kafka target1,000,000 bytes per messageRefused, with the table's name. Leave the column out with output columns, or replicate the table to another target.
Google Pub/Sub target10,000,000 bytes per messageRefused, with the table's name. Leave the column out with output columns, or replicate the table to another target.
Fabric Open Mirroring targetmaxValueBytes, 16,000,000 bytes by defaultRefused.

Large values in flight are kept encrypted in the agent's spool directory on disk, not in memory, so plan the agent's disk space for them.

Applying large values

SQL Server, Azure SQL, SQL database in Fabric, Oracle and PostgreSQL targets stream a large value into the target rather than building it in memory. On SQL Server, a very large value is written in pieces within the row's own transaction, so a partly written value is never committed or visible to other readers. SQL Flow tracks partly written values in the control table __sqlflow_lob_apply_head in its bookkeeping schema.

With relay, the capture agent sends large values to the apply agent, including during the initial load. The apply agent never reads the source.

Large values in processing rules

A large-value column can be kept, filtered on or masked by in-flight processing rules, with limits: it can't be a key, it can't be listed twice in the output columns, and values over 1 MiB pass only through the operations that stream them. See Output and computed columns.

See also

If this was useful,
our newsletter will be too.

Get monthly insights on data engineering, AI, and building critical infrastructure - direct from the Spectral Core team and CEO Damir Bulic.