Skip to content
Sheetwrite

Sheetwrite / Documentation

Compatibility and limits

Explicit compatibility boundaries, resource ceilings, tuning defaults, limit behavior, and override paths.
AreaSupported contractBoundary
DataEager columnar data or cancellable datasource pages; dense and allocation-lazy paged storageFull-sheet queries and exports are incomplete until required pages load
FormulasPersisted formula source, A1/range references, named ranges, the inventory-derived supported function contract, bounded lexical LET, and bounded dynamic-array spillsNo blanket Excel/Sheets/OpenFormula claim; external/network/database/cube/LAMBDA categories and automatic volatility beyond the clock barrier are unsupported
ProtectionSerializable client interaction policy with atomic/partial local mutation behaviorNever server authorization; remote operations bypass local UX policy
CollaborationHost sequencing, stable mutation IDs, durable optimistic edits, ordered remote operations, presence/comments/revisions, conservative rebaseNo bundled server, CRDT, or general OT; ambiguous structural/formula conflicts require host UX
WorkerOffscreenCanvas rendering with capability/startup fallbackCustom function renderers cannot transfer to the worker
XLSXTable interchange plus supported workbook formulas/styles/merges/dimensions/frozen panes/names and Sheetwrite metadataUnsupported workbook features are warned, flattened, or dropped; not full Excel fidelity
AccessibilityARIA grid mirror for the visible virtualized window with keyboard-driven updatesThe full document is not duplicated into hidden DOM

Compatibility statements are feature contracts, not claims of Excel or Google Sheets parity.

The detailed compatibility results link each formula, workbook, clipboard, and XLSX status to its evidence record and exact difference.

The generated formula function contract publishes names, families, signatures, behavior profiles, source links, implementation evidence, and unsupported categories directly from the checked versioned inventory.

The tables below describe the owning source definition, not generated API signatures. Ceilings are inclusive unless a row says otherwise. MiB means 1,048,576 bytes. “Compatibility” identifies an external or product boundary; “resource defense” identifies bounded allocation or retained state; “interaction tuning” identifies a non-failing operational default.

Rendering, interaction, and paged data

Owner / resourceDefault and unitWhy / evidence classBehavior at the boundarySupported override
GridOptions.overscan / DEFAULT_OVERSCAN6 row and visible-column positions per viewport edgeInteraction tuning: keep the virtual paint and ARIA windows close to the viewportIt is not a document ceiling; the window is clipped to available rows/columnsGridOptions.overscan or grid.setOverscan(); 0 disables the buffer
measureMaxElementHeightMeasured browser clamp minus 4,096 CSS px; 15,000,000 CSS px fallbackCompatibility: browser layout and scroll-offset clamps varyTaller logical sheets use scaled scrolling while the DOM sizer stays at the safe clampNot configurable
AUTO_FIT_CHUNK_CELLS16,384 cells per store readResource defense: bound one synchronous auto-fit readLarger scans continue in frame-scheduled chunks and commit after the scanNot configurable
DEFAULT_COL_WIDTH100 CSS pxInteraction tuning: keep synthesized sheet and padding columns consistentUsed for generated columns; it is not a width ceilingNo global setting; supply or update individual column widths
DEFAULT_SIMPLE_COLUMN_WIDTH120 CSS pxInteraction tuning: give adapter-created schemas an explicit usable widthUsed only when a simple column omits widthSimpleColumn.width
DataSourceStorageOptions.chunkRows / DEFAULT_PAGE_CHUNK_ROWS4,096 rows per chunkResource defense: allocation-lazy page granularityChunks allocate on load/edit; a positive non-power-of-two value is rounded up to a power of twoGridOptions.datasourceStorage.chunkRows or SheetwriteStoreOptions.chunkRows
DataSourceStorageOptions.cacheBytes / DEFAULT_PAGED_CACHE_BYTES32 MiB per paged sheetResource defense: bound clean cached chunksBefore a new chunk would exceed the budget, the least-recent clean, unpinned chunks are evicted; dirty/visible chunks may exceed itGridOptions.datasourceStorage.cacheBytes or SheetwriteStoreOptions.cacheBytes; 0 disables eviction
DataSourceStorageOptions.dirtyCellLimit / DEFAULT_PAGED_DIRTY_CELL_LIMIT1,000,000 sparse local cells per paged sheetResource defense: bound dirty overlay memory independently of clean cached chunksA transaction that would add cell 1,000,001 is rejected atomically with a paged-dirty-cells resource-limit issue; rewrites of already-dirty cells do not consume more capacityGridOptions.datasourceStorage.dirtyCellLimit or SheetwriteStoreOptions.dirtyCellLimit
Grid.distinctValues1,000 distinct valuesResource defense: bound the default filter-menu resultReturns the first 1,000 distinct resolved values in first-seen orderPass limit; 0 requests an uncapped scan
UndoManager200 transactionsResource defense: bound retained undo resourcesPushing entry 201 disposes the oldest undo entryNot configurable through the public Grid API

The accessibility mirror uses the same virtual window and overscan as the canvas; it has no separate full-document DOM budget. See datasource paging and storage, data operations, and the visible-window accessibility limit.

Formula evaluation

Owner / resourceDefault and unitWhy / evidence classBehavior at the boundarySupported override
PARSE_RECURSION_LIMIT256 nested parser levelsResource defense: bound recursive formula parsingDeeper syntax is a malformed formula and resolves to #VALUE!Not configurable
FORMULA_RECURSION_LIMIT256 dependency/evaluation levelsResource defense: bound recursive dependency evaluationA deeper dependency or expression resolves to #NUM!Not configurable
RANGE_CELL_LIMIT1,000,000 materialized cells per formula rangeResource defense: bound range/matrix allocationAn oversized range resolves to #NUM!Not configurable
SPILL_MAX_ROWS / SPILL_MAX_COLS1,048,576 rows and 16,384 columns per matrixCompatibility and resource defense: match worksheet axes before allocationAn invalid or oversized dimension resolves to #NUM!Not configurable
SPILL_MAX_CELLS / SPILL_MAX_BYTES1,000,000 cells and 64 MiB value/intermediate storage per matrix operationResource defense: bound dynamic arrays, criteria matrices, transforms, and spill materializationPreflight or materialization resolves to #NUM!; no truncated matrix is installedNot configurable
SPILL_MAX_RECOMPUTE_CELLS2,000,000 cell operations per dynamic recomputeResource defense: bound filtering, sorting, uniqueness comparisons, and transformsThe operation resolves to #NUM!; spill publication remains atomicNot configurable
LET_BINDING_LIMIT126 lexical bindings per LETResource defense: bound binding state and source expansionBinding 127 resolves to #VALUE!Not configurable
LET_EXPANDED_NODE_LIMIT16,384 reachable expanded AST nodesResource defense: bound lazy substitution, including repeated bindingsThe first node above the ceiling resolves to #NUM!; unused bindings do not consume expansion workNot configurable
MAX_TEXT_OUTPUT_BYTES / MAX_SEARCH_STEPS16 MiB generated text and 4,000,000 bounded search stepsResource defense: bound Unicode output and text search/substitution workExcess work resolves to #NUM!Not configurable
Financial root solver14 bracket steps, 100 solve steps, fixed 1e-12 tolerancesDeterminism and resource defense for IRR/RATEInvalid domains or non-convergence resolve to #NUM!Not configurable

See formula functions, exact semantics, errors, and compatibility and the inventory-generated function reference.

Transactions and snapshots

DEFAULT_TRANSACTION_RESOURCE_LIMITS owns the atomic mutation defaults. A transaction at the ceiling is accepted; exceeding either ceiling returns a resource-limit rejection and applies none of an atomic transaction.

Owner / resourceDefault and unitWhy / evidence classBehavior above the ceilingSupported override
maxOperations10,000 DocumentOp objects per transactionResource defense: bound object-heavy validation and dispatchTransaction is rejectedGridOptions.transactionResourceLimits, SheetwriteStoreOptions.transactionResourceLimits, or an explicit limit passed to validateTransactionResources
maxEncodedBytes8 MiB of UTF-8 JSON per operation arrayResource defense: bound exact payload inspectionTransaction is rejectedSame paths as maxOperations

DEFAULT_SNAPSHOT_RESOURCE_LIMITS owns validation and allocation defaults. Exceeding one produces a path-qualified validation error or SnapshotResourceError before store allocation; an allocation failure within a configured ceiling still surfaces as a resource failure.

Owner / resourceDefault and unitWhy / evidence classBehavior above the ceilingSupported override
maxSheets256 sheets per workbookResource defense: bound sheet-indexed schema/store stateSnapshot or direct workbook construction is rejectedSnapshotValidationOptions.resourceLimits, SheetwriteStoreOptions.snapshotResourceLimits, or SnapshotGridOptions.snapshotResourceLimits
maxRowsPerSheet1,000,000 rows per sheetCompatibility: million-row allocation-lazy sheet contractRejected before allocationSame snapshot resource-limit paths
maxColumnsPerSheet16,384 columns per sheetCompatibility: worksheet width shared with XLSXRejected before allocationSame snapshot resource-limit paths
maxMetadataEntries1,000,000 aggregate entriesResource defense: bound names and sheet metadata collectionsRejected during resource preflightSame snapshot resource-limit paths
maxSerializedBytes64 MiB of UTF-8 JSONResource defense: bound snapshot JSON-safety inspectionValidation returns a resource-limit errorSame snapshot resource-limit paths
maxLogicalCellsPerSheet4,294,967,295 row-by-column cells per sheetResource defense: cap logical area even when paged storage defers allocationRejected before dense or paged allocationSame snapshot resource-limit paths
maxDenseCells5,000,000 aggregate cells per dense workbookResource defense: bound eager allocationDense construction is rejected; paged storage does not consume this budgetSame snapshot resource-limit paths; choose storage: "paged" for allocation-lazy data

See persistence and recovery and document operations.

Delimited text

DEFAULT_DELIMITED_TEXT_RESOURCE_LIMITS owns synchronous CSV/TSV defaults. Except for the writer window, exceeding a ceiling throws DelimitedTextResourceError before the next oversized parse/encode allocation; no partial string is returned.

ResourceDefault and unitWhy / evidence classBehavior at or above the boundarySupported override
maxInputBytes32 MiB UTF-8 inputResource defense: bound the caller-owned string before parser allocationsAt the ceiling parses; above it throwsDelimitedTextOptions.resourceLimits.maxInputBytes
maxOutputBytes64 MiB UTF-8 output, including BOMResource defense: bound the single returned stringAt the ceiling returns; above it throwsDelimitedTextOptions.resourceLimits.maxOutputBytes
maxRows1,000,000 syntactic recordsCompatibility: million-row data contractRecord 1,000,001 throwsDelimitedTextOptions.resourceLimits.maxRows
maxColumns16,384 fields in one recordCompatibility: worksheet widthField 16,385 in one record throwsDelimitedTextOptions.resourceLimits.maxColumns
maxCells1,000,000 aggregate fieldsResource defense: bound parser arrays and encoder workAggregate field 1,000,001 throwsDelimitedTextOptions.resourceLimits.maxCells
maxFieldBytes1 MiB decoded UTF-8 per fieldResource defense: prevent one quoted field dominating memoryOne byte above the ceiling throwsDelimitedTextOptions.resourceLimits.maxFieldBytes
maxWriterWindowRows4,096 rows per packed store readResource defense: bound each synchronous store windowExport continues with the next window; this is not a total-row ceilingDelimitedTextOptions.resourceLimits.maxWriterWindowRows

The override object accepts positive safe integers. CSV and TSV still return complete in-memory strings; raising byte/cell ceilings is not streaming. See data import and export.

Synchronization and presence

DEFAULT_SYNC_COORDINATOR_LIMITS owns remote-input and durable-queue defaults. All fields accept positive safe-integer overrides through SyncCoordinatorOptions.limits.

ResourceDefault and unitWhy / evidence classBehavior at or above the boundarySupported override
maxMutationIdBytes256 UTF-8 bytes per mutation IDResource defense: IDs cross transport and persistence boundariesAt the ceiling accepted; an oversized ID is a typed protocol errorlimits.maxMutationIdBytes
maxOperationsPerVersion10,000 operations per remote versionResource defense: match one atomic transactionAt the ceiling accepted; above it emits a protocol error and reload requirementlimits.maxOperationsPerVersion
maxVersionPayloadBytes8 MiB UTF-8 JSON per remote versionResource defense: match one atomic transaction payloadAt the ceiling accepted; above it emits a protocol error and reload requirementlimits.maxVersionPayloadBytes
maxFutureVersionDistance1,024 versions aheadRecovery bound: avoid retaining an unbounded gapA greater distance clears the gap buffer and requests reload/recoverylimits.maxFutureVersionDistance
maxBufferedVersions256 future versionsResource defense: bound retained gap countThe next version clears the gap buffer and requests reload/recoverylimits.maxBufferedVersions
maxBufferedOperations40,000 aggregate operationsResource defense: bound retained gap workThe operation that would exceed it clears the gap buffer and requests reload/recoverylimits.maxBufferedOperations
maxBufferedBytes32 MiB aggregate UTF-8 JSONResource defense: bound retained gap payloadsThe operation that would exceed it clears the gap buffer and requests reload/recoverylimits.maxBufferedBytes
maxRecentAcknowledgements4,096 mutation IDsResource defense: bound echo-deduplication stateThe oldest ID expires; a later stale echo is a reload-requiring protocol violationlimits.maxRecentAcknowledgements
maxPendingCommits10,000 pending commitsDurability bound: cap retained offline workAt the ceiling capacity is full; another local transaction is rejected atomicallylimits.maxPendingCommits
maxPendingOperations100,000 aggregate pending operationsDurability bound: cap retained offline workAt the ceiling capacity is full; a transaction that would exceed it is rejectedlimits.maxPendingOperations
maxPendingEncodedBytes128 MiB aggregate UTF-8 JSONDurability bound: cap retained offline payloadsAt the ceiling capacity is full; a transaction that would exceed it is rejectedlimits.maxPendingEncodedBytes

PresenceCoordinator owns its independent ephemeral defaults:

ResourceDefault and unitWhy / evidence classBehavior at the boundarySupported override
heartbeatMs15,000 msInteraction tuning: periodic publish and stale pruningTimer publishes/prunes each intervalPresenceCoordinatorOptions.heartbeatMs; 0 disables the timer
timeoutMs45,000 msInteraction tuning: three default heartbeat intervals of silenceAn actor at or beyond the idle cutoff is expiredPresenceCoordinatorOptions.timeoutMs
maxActors32 remote actorsResource defense: bound overlay stateReceiving a new actor at capacity evicts the oldest actorPresenceCoordinatorOptions.maxActors (minimum 1)
maxRangesPerActor8 selection rangesResource defense: bound payload and overlay workAdditional outbound/inbound ranges are truncatedPresenceCoordinatorOptions.maxRangesPerActor (minimum 1)

See durable commits, version gaps, and presence.

XLSX codec

DEFAULT_XLSX_RESOURCE_LIMITS owns every optional codec path. Each ceiling is inclusive; exceeding one throws XlsxResourceError and returns no partial workbook. Override maxCells through XlsxWorkbookOptions.maxCells; override every other field through XlsxWorkbookOptions.resourceLimits.

ResourceDefault and unitWhy / evidence classBehavior above the ceilingSupported override
maxInputBytes32 MiB compressed inputResource defense: bound caller inputImport throws before ZIP parsingresourceLimits.maxInputBytes
maxOutputBytes128 MiB encoded outputResource defense: bound the returned byte arrayExport throws during preflight or after encodingresourceLimits.maxOutputBytes
maxArchiveEntries1,024 ZIP entriesResource defense: bound archive fan-outImport/export throwsresourceLimits.maxArchiveEntries
maxEntryUncompressedBytes64 MiB per ZIP entryResource defense: bound one inflated/encoded partImport/export throwsresourceLimits.maxEntryUncompressedBytes
maxTotalUncompressedBytes256 MiB aggregate ZIP contentResource defense: bound total inflated/encoded partsImport/export throwsresourceLimits.maxTotalUncompressedBytes
maxCompressionRatio100:1 uncompressed/compressedResource defense: reject zip-bomb-like entriesImport throwsresourceLimits.maxCompressionRatio
maxSheets256 worksheetsResource defense: bound workbook collectionsImport/export throwsresourceLimits.maxSheets
maxRowsPerSheet1,048,576 rows per worksheetCompatibility: SpreadsheetML worksheet heightImport/export throwsresourceLimits.maxRowsPerSheet
maxColumnsPerSheet16,384 columns per worksheetCompatibility: SpreadsheetML worksheet widthImport/export throwsresourceLimits.maxColumnsPerSheet
maxCells1,000,000 cells accounted by the conversion pathResource defense: bound conversion workImport/export throwsTop-level XlsxWorkbookOptions.maxCells
maxMerges100,000 aggregate merged rangesResource defense: bound merge collectionsImport/export throwsresourceLimits.maxMerges
maxSharedStrings1,000,000 shared-string entriesResource defense: bound the shared-string tableImport throwsresourceLimits.maxSharedStrings
maxStyles65,536 style-related recordsResource defense: bound style tablesImport/export throwsresourceLimits.maxStyles
maxXmlElements2,000,000 elements per XML partResource defense: bound parser nodesImport throwsresourceLimits.maxXmlElements
maxXmlDepth64 nested elements per XML partResource defense: bound parser nestingImport throwsresourceLimits.maxXmlDepth
maxXmlAttributesPerElement128 attributes per elementResource defense: bound per-node parsingImport throwsresourceLimits.maxXmlAttributesPerElement
maxXmlTextBytes16 MiB UTF-8 text per element or attributeResource defense: bound XML text accumulationImport/export throwsresourceLimits.maxXmlTextBytes

Table and workbook conversions account cells according to the active path (for example, table export accounts its rectangular table). Raising dimensions does not add fidelity for unsupported workbook features. See XLSX compatibility.