Versions and last-writer-wins

How suo resolves two writes to the same record, and what read-your-writes means for you.

Every record carries a monotonic version. suo uses it, not arrival order, to decide which write sticks.

Setting version

Pass your own version — typically your record's updatedAt timestamp or a database revision number — on upsert and delete. If you omit it, the server assigns one from the time it accepts the write.

JSON
{ "action": "upsert", "record": { "objectID": "a", "title": "…", "version": 1732550400000 } }

Last-writer-wins

If two writes to the same objectID arrive out of order — a retry, a slow network, a queued batch replaying after a fresher direct write — the one with the higher version wins. A write with a lower or equal version than what is already stored is accepted but ignored, and counted in the response as ignoredAsStale:

JSON
{ "dataVersion": 481, "applied": 3, "ignoredAsStale": 1 }

This is why version should track your own source of truth's update time, not the time you happen to call the API.

Unchanged records

Re-sending a record whose fields are identical to what is stored, apart from version, is cheap. suo accepts it and counts it in applied, and the stored version still moves forward so last-writer-wins holds. Nothing is re-indexed, and it isn't copied to replicas. A batch where every record is unchanged leaves dataVersion where it was. This is what keeps a daily re-crawl of an unchanged site close to free.

Fields are compared exactly, key order included. Sending the same record with its keys in a different order counts as a change.

Deletes are tombstones

A delete does not immediately erase a record; it becomes a versioned tombstone kept for 30 days, so a delayed upsert from before the delete cannot bring the record back. After 30 days the tombstone itself is dropped.

Read-your-writes

Every successful write returns the index's new dataVersion. Pass it as minDataVersion on a search against the same index's primary, and the primary will not answer until it has applied at least that version — so a search right after a write is guaranteed to see it, without a fixed delay or a retry loop.

JSON
{ "q": "note-taking", "minDataVersion": 481 }

This only applies to the primary. Reads against a replica (used for hot, read-heavy indexes) are eventually consistent — see Partitions for when an index gets replicas versus a partition per key.