Product

How Incremental Sync Keeps Memory Fresh Without Re-Indexing

A stale memory is a confident liar. It answers with yesterday's ownership, last week's architecture, and a bug that was fixed on Tuesday. That is worse than no memory at all, because your agent trusts it. So the real question for any memory layer is not how it indexes once. It is how it stays current.

The Oynix Team · June 10, 2026 · 6 min read

Why the naive answer fails

The obvious way to stay fresh is to re-index everything on a schedule. Read every file, every ticket, every doc again, and rebuild the graph from scratch. It works, and it is ruinous. On a large codebase a full rebuild is slow, expensive, and something you will avoid running often, which is how memory goes stale in the first place.

The trap is that full re-indexing makes freshness cost more the bigger you get. The teams with the most code, the ones who need current memory most, are the ones for whom keeping it current hurts the most. That is backwards.

The insight is that almost nothing changes between syncs. A monorepo with four million lines might see a few hundred lines move in a day. Reprocessing four million to capture a few hundred is the waste. Incremental sync exists to touch only what moved.

The four mechanisms that make it incremental

  • Modified-time cursors. Each source remembers the timestamp of the last item it saw. On re-sync it asks only for things changed since that mark, so unchanged files and closed tickets are never fetched again.
  • High-water marks. Per source, Oynix tracks the furthest point it has fully processed. If a sync is interrupted, it resumes from the mark instead of starting over, and it never double-counts what it already ingested.
  • Content-hash dedup. Every item carries a hash of its content. If the hash matches what is already in the graph, the item is skipped. A file that was touched but not actually changed costs nothing to re-see.
  • Per-source selection. You choose which channels, spaces, or folders sync. Work that you never selected is never scanned, so the surface area of every sync is exactly what you care about and no more.

What happens on a re-sync

  1. 1

    Ask each source what changed

    Oynix reads the modified-time cursor for every connected source and requests only items updated since that timestamp. Unchanged history is left untouched.

  2. 2

    Filter to your selection

    Changes are narrowed to the channels, spaces, and folders you chose to sync. Anything outside that selection is dropped before any work begins.

  3. 3

    Hash and dedup

    Each remaining item is hashed. Matches against the existing graph are skipped, so files that were touched but not truly changed cost nothing.

  4. 4

    Update only the affected graph

    The genuinely new or changed items are parsed, and only the nodes and edges they affect are rewritten. The rest of the graph stays exactly as it was.

  5. 5

    Advance the marks

    Cursors and high-water marks move forward to the newest point seen. The next re-sync starts from here, so the work never repeats.

Full rebuild versus incremental sync

AspectFull re-indexOynix incremental sync
What gets readEverything, every timeOnly what changed since the last mark
Cost as the codebase growsGrows with total sizeTracks the size of the change, not the repo
Interrupted runStart overResume from the high-water mark
Touched but unchanged fileReprocessedSkipped by content hash
Sources scannedAll of themOnly the ones you selected
How often you will run itRarely, because it hurtsOften, because it is cheap

Why the monorepo costs the same as the side project

Incremental sync prices work by change, not by size. A side project where you edited ten files today and a four million line monorepo where you edited ten files today do the same amount of work on re-sync, because the same ten files changed. The rest of the monorepo is untouched, unhashed, and unread.

This flips the usual penalty. Instead of large codebases being expensive to keep fresh, they are simply large. Freshness cost is decoupled from repository size and tied to daily churn, which stays roughly constant no matter how big the history behind it gets.

It also means you can sync often. When a re-sync only pays for what moved, running it frequently is cheap, and frequent is how memory stays honest. The graph reflects this morning's merge, not last month's snapshot.

Incremental sync bills the diff, not the repository. Ten changed files cost the same whether they live in a toy or a monorepo.

Fresh by default

A memory layer earns trust by being right about now. The cursors, marks, hashes, and selection all serve one goal, which is to keep the graph current without ever paying to reprocess what did not change.

The result is a graph you can re-sync as often as you like without watching a cost curve. Your agent asks who owns a file and gets today's owner. It asks what a function calls and gets this morning's call sites. The memory keeps up because keeping up is cheap.

Keep your graph honest without re-indexing

Sync as often as you want and pay only for what actually changed, so your agent always reasons over the state of your work right now.

Install Oynix