Data Modeling

Schema decisions that cause data corruption or sync issues.

Complex Objects in Reorderable Arrays

// WRONG
const slides = yDoc.getArray('slides')
slides.push([{ id: 'k8d2fn3m', title: 'Intro', content: [...] }])

Y.Array delete + insert creates copies, not moves. Concurrent reordering causes duplicates or data loss.

Fix: Store content in Y.Map, only IDs in Y.Array. See ID-Based Storage.

Index-Based References

// WRONG
cells.set('A1', { formula: '=B1 * C1' })  // References shift when columns inserted

Array indices change on insert/delete. References break silently.

Fix: Use stable IDs:

cells.set('r8k2mf9n:c3nd8k2m', { formula: { refs: ['r8k2mf9n:c9m2pt3q', 'r8k2mf9n:c2n7ks4w'], expr: '*' } })

Large Binary Data in CRDT

// WRONG
images.set('hero', { data: base64EncodedImage })  // 500KB+ in CRDT

CRDT metadata adds 2-10x overhead. History accumulates. Sync becomes slow.

Fix: Use blob storage, store only reference:

images.set('hero', { blobId: 'b8k2mf9n', width: 1920, height: 1080 })

Checklist

  • Complex content in Y.Map with IDs, order in Y.Array
  • All references use stable IDs, not indices
  • Binary data external, only references in CRDT

See Also