Incremental Backup & Change Detection

For SharePoint, OneDrive, and Exchange, BYOVault does not re-list an entire tenant on every run. Two independent layers decide what actually needs to move: Microsoft Graph's own change-tracking API, which limits what gets asked for, and a separate internal check that limits what gets re-uploaded.

Layer 1: Microsoft Graph’s change-tracking API

For each drive (a SharePoint site library or a OneDrive) and each Exchange mailbox folder, BYOVault calls Microsoft Graph’s delta query instead of listing every item on every run.

The first backup of a given resource receives every item, plus a cursor Graph provides for tracking future changes. Every subsequent run passes that saved cursor back to Graph, which returns only what changed since it was issued: created, modified, and deleted items.

BYOVault keeps track of that cursor per tenant, workload, and resource. It only updates the cursor once the entire resource’s batch of changes has been processed and uploaded — not per file.

An interrupted run (a service restart, a cancelled job) therefore re-asks Graph for the same change set on its next attempt, rather than silently missing whatever did not finish. That re-ask is what Layer 2 exists to make cheap.

Recovering from an expired cursor

If a cursor has expired — Graph returns an HTTP 410 Gone, which happens when a cursor is held past Graph’s own retention window for it — BYOVault first retries in-memory as a full, non-delta request. Only if that retry also fails does it clear the saved cursor, so the next scheduled or on-demand run performs an honest full rescan instead of resubmitting a cursor Graph has already rejected.

An operator can also trigger this manually: the dashboard’s “Force Full Rescan” action clears the saved cursor for a tenant (optionally scoped to one workload) so the next backup re-lists everything from Graph.

Layer 2: confirming a file hasn’t already been uploaded

A delta query can still hand back items that have not actually changed in any way that matters to a backup. This happens in the re-ask-after-an-interruption case above, but also when Graph reports an item as part of a delta batch without its underlying content having changed.

Before downloading and re-uploading anything, BYOVault checks whether it has already confirmed an upload for that exact item — matched on the item’s identity plus its last-modified time and size, as Graph is reporting them right now:

  • For SharePoint and OneDrive, those two fields come from the drive item’s last-modified time and size.
  • For Exchange, they come from the message’s last-modified time and the byte length of the message BYOVault actually stores.

If both match, the item is skipped. If either has changed, it is treated as genuinely new content and re-uploaded, regardless of what was previously confirmed.

This check is always scoped to the tenant’s current storage account. An item confirmed as uploaded to one storage account is never treated as already present in a different one.

Why the storage account matters, not just last-modified and size

Saving a tenant’s storage configuration — connecting a storage account for the first time, or replacing it later — always resets this check for that tenant. It resets on every save, not only when the account name or container actually differs: re-entering the identical account and container name still resets it, so the next backup run re-uploads every item rather than skipping items it had previously confirmed against the old storage account.

This is deliberate, not incidental. Without it, a tenant that replaced a deleted-and-recreated storage account under the exact same name would have every file treated as already uploaded and silently skipped — with the backup job reporting full success while writing nothing into the new, empty account. Resetting on every save closes that gap unconditionally: a storage account swap cannot be mistaken for a run with nothing to do.

Change tracking is not affected the same way
Change-tracking progress is handled differently, for the opposite reason: it tracks progress against Microsoft 365 itself rather than against a storage account, so it remains valid after a storage swap. A tenant that moves from one storage account to another and later moves back does not lose its place in Microsoft 365.

The practical consequence of a storage account swap

After a storage credential or account change, the next backup for that tenant still uses Graph delta query as normal — it does not re-list the entire tenant from Microsoft 365 unless the delta change-tracking progress has also been cleared or has separately expired.

What changes is the outcome of every item Graph reports: each one is downloaded, encrypted, and written to the new storage account as if it were being backed up for the first time. The next backup after a storage swap is, in effect, a full copy of the tenant’s content into the new account, item by item.

This is intentional. A storage account swap means the destination changed, not that the source content did — and the check only ever answers “does this exact content already exist at the destination BYOVault is currently pointed at,” which a new, empty account can never answer yes to.

Scope

This two-layer model applies to the Microsoft 365 workloads — SharePoint, OneDrive, and Exchange — which are the workloads Microsoft Graph exposes a delta query for. See File Servers for how change detection works for on-prem shares backed up through the local agent, which is a separate mechanism.