The Sync Monitor is the operations screen for every sync profile: it shows whether each profile is keeping up, and lists the records the engine would not decide on without a person. It sits at Setup → Platform → Monitoring → Sync Monitor, beside Tracing, Jobs, Audit Trail and Message Log. You build a profile under Setup → Platform → Sync profiles (see scheduled sync). After that, you use this screen to keep the profile running. When a cycle fails, you follow it from here into the integration app's run history.
Overview
The monitor has two tabs:
- Health — one row per sync profile. Use it to answer "is anything wrong right now?"
- Conflicts — every open conflict across all profiles. Use it to answer "what needs a decision?"
Each profile's own page (open it from Setup → Platform → Sync profiles, or from a Health row) has the same Conflicts panel limited to that profile. It also has the tabs you need to dig deeper: Cycles, Reconciliation and Records. Push-based profiles such as Tally also have Sites and Outbound queue.
Above each tab the page header shows summary tiles. They are counted from the rows the table has loaded, so they always match the table:
| Tab | Tiles |
|---|---|
| Health | Profiles · Active · Behind schedule · Never run · Failing cycles · Open conflicts · Reseed required · Sites not reporting (shown only when at least one push site exists) |
| Conflicts | Shown · Open · Re-detected 3+ cycles · Delete vs update · Profiles affected · Entities affected |
When to use it
- Every day. Open the Health tab, choose Needs attention, and work down the list.
- When someone reports that a record "didn't come across", use the profile's Records tab to find that record.
- When a profile's lag grows, use the integration app's Errors tab to find the failing runs.
- After an outage, or when you doubt a profile's change detection, use the profile's Reconciliation tab.
Prerequisites
- Your security profile must have the Manage integrations capability (see Permissions).
- At least one sync profile must exist. Without one, the Health tab shows No sync profiles to monitor.
Procedure
Step 1 — Check health
- Go to Setup → Platform → Monitoring → Sync Monitor. The Health tab opens.
- In the table's second header row, choose Needs attention. The other choices are All profiles and Enabled only.
- Read each remaining row from left to right. Use The Health board below to see what each column is telling you. Hover over the lag, parked/deferred, reseed and sites values to see the exact figures.
- If the list is empty, the table shows No profile needs attention. Every enabled profile is on schedule and has no failing cycles, conflicts, parked records, reseeds or silent sites.
From a row's actions, Open profile opens the profile's own page. Open conflicts appears only when the profile has open conflicts. It switches to the Conflicts tab with the Profile filter set to that profile.
Step 2 — Decide a conflict
- Open the Conflicts tab. It shows Open conflicts across all profiles. Use the second header row to filter by Profile, Entity and Status.
- Expand a row to see the contested fields side by side, in three columns: Base (last synced), the xMatix value and the External value. A value shown in bold has moved away from the base, so you can see which side changed what. If a conflict is not a value disagreement (for example a duplicate key or a rejected write), it has no field detail and cannot be expanded.
- In the row's actions, choose one outcome: Keep xMatix, Keep external, Merged by hand, Ignore once or Ignore always (stop syncing this record). Resolution outcomes explains what each one does.
- Confirm the dialog. You see Conflict resolved. For Ignore always you see Conflict closed and record parked. The row leaves the Open list.
- Except for Ignore always, deciding records your choice but does not write any value, and the record stays held as Conflict. Line the two systems up by hand if they still differ, then release the record with Resume on the profile's Records tab (Step 4).
Resolution actions are offered only on Open conflicts. A conflict that is already closed cannot be decided again, because that would overwrite the record of who decided what.
Step 3 — Resolve conflicts in bulk
- On the Conflicts tab, select the rows with the checkboxes. The page-header button changes to *Resolve N selected*.
- Select it. In the *Resolve N conflict(s) dialog, choose an Outcome: Keep xMatix, Keep external, Merged by hand or Ignore. Ignore* is preselected.
- Optionally type a Note of up to 1,000 characters. The note is stored on every conflict you resolve here, against your user.
- Optionally tick Also stop syncing these records (parks each ledger row as Excluded until resumed). With Ignore, this makes the action the bulk form of Ignore always.
- Select Resolve. If every conflict was resolved, you see Resolved N conflict(s). If some were skipped, a Resolved X, skipped Y window lists them with the reason. The usual reason is that another person already closed the conflict, or a newer cycle closed it as Superseded.
Single-row resolutions do not take a note. To record why you made a decision, use the bulk dialog, even for one row.
Step 4 — Find one record and un-park it
- Open the profile and go to its Records tab.
- Type the record's key in the search box. An xMatix record id finds an exact match on either side. Any other text matches against external keys. You can also narrow the list with Entity and Record status.
- Read the row: Status, Last direction, Last synced, Failures (consecutive) and Last error.
- When the status is anything other than In sync, the row shows Resume. Select it and confirm. The record's status becomes In sync and its failure count and last error are cleared. The next cycle considers the record again.
Resume keeps the record's last-synced fingerprint on purpose. If it cleared the fingerprint, the engine would read its own last write as a change from the other side and send it back.
Step 5 — Reseed an entity
Reseed when the Health board lists an entity under Reseed required, or when you no longer trust an entity's incremental position.
- Open the profile. On the Entities tab, choose Reseed in the entity's row actions. To reseed every entity at once, choose Reseed all in the page header.
- Confirm. You see Reseed requested for N entity(ies).
The next pass compares every record in both directions, not just what changed since the cursor. It re-hashes and compares. It does not delete or re-create anything. Expect a long cycle that makes many calls to the external system.
Step 6 — Run a reconciliation
- Open the profile and go to its Reconciliation tab.
- Select Reconcile now in the page header. The button is unavailable until the profile has a Nightly reconciliation schedule. The profile must also have been compiled after you set that schedule. Without a compiled reconciliation, the request fails with The profile has no reconcile flow yet: set a reconcile schedule and compile the profile first.
- You see Reconciliation queued; the run appears here when the worker finishes it. Refresh the table later.
- Read the run's Unexplained count first, then expand the run to see each entity's result. Reading a reconciliation run explains the columns.
Step 7 — Trace a failed run
- Note when the profile's Watermark lag stopped moving. The profile's Cycles tab cannot help here, because cycles are not currently recorded (see The Cycles tab).
- Open the integration app that owns the profile (Setup → Platform → Integrations) and go to its Errors tab. It shows the app's runs with status Failed or DeadLettered. Each run carries its latest error. The error category tells you the kind of failure:
- a deterministic failure
- a transient failure, which is retried automatically with increasing delays before the run is dead-lettered
- retries exhausted
- an orphaned run that the clean-up sweep closed
- a run an operator cancelled
- Use Step data to see the run's steps. Failed runs always capture each executed step's input and output. Successful runs capture them only when the flow has Capture step data switched on. Secrets are removed from the values. Step data is kept for a set period (30 days by default), so an older run may have none. Read the step data like this:
- Credential or reachability errors point at the connection.
- Nulls after the mapping step point at field paths.
- A 4xx response from the connector points at the external system.
- A validation message means xMatix itself refused the write.
- Fix the cause. Then use Replay if you need to. Replay is offered only for runs with status Failed, Succeeded, DeadLettered or Rejected. The original flow version must still exist, and replay needs either a body you supply or the original run's archived input. The replay runs the flow's currently active version, so a repaired mapping applies to the retained data. Leave a run alone while it is still inside its automatic retry window.
Authentication failures are not retried automatically, because a rejected credential cannot fix itself. They keep failing until someone rotates or fixes the credential.
The Health board
| Column | What it means |
|---|---|
| Profile | The profile name. Select it to open the profile |
| Status | Where the profile is in its lifecycle: Draft, Seeding, Active, Paused or Failed |
| Enabled | Enabled or Disabled. Needs attention looks only at enabled profiles |
| Schedule | The profile's schedule in words, or Manual only |
| Watermark lag | How long ago the oldest cursor on the profile's active entities moved forward. Green, amber or red against the profile's schedule (see Business rules). Never run means no cursor exists yet. That is a new or never-seeded profile, not a healthy one |
| Last cycle / Last cycle result | Meant to show when the most recent cycle started and how it ended (Running, Succeeded, PartiallyFailed, Failed or Cancelled). The sync engine does not currently record cycles, so these stay blank |
| Failed streak | Meant to count the most recent cycles in a row that ended Failed or PartiallyFailed (up to 20; amber at 1–2, red at 3 or more). Because cycles are not currently recorded, it stays at zero — use Watermark lag and the app's Errors tab instead |
| Open conflicts | Open conflicts on the profile |
| Parked / deferred | Two numbers. The first counts records held on Conflict or Error, which never clear on their own. The second counts Deferred records, which are waiting for a reference that has not synced yet and usually clear within a cycle or two. Records you parked with Ignore always (Excluded) are counted in neither |
| Reseed required | Active entities that have a cursor but no completed full baseline. Until they are reseeded, "nothing changed" tells you nothing |
| Sites | Push profiles only. N reporting, or X/N not reporting when an active site has never checked in or has gone silent (see Business rules). A silent site produces no run and no error, so this is the only place it shows |
The Sync profiles list also shows a single Parked records total. That total adds Conflict, Error and Deferred together. Use the Health board when you need them apart.
The Conflicts inbox
A conflict is a record the engine would not decide on without a person. The engine keeps at most one open conflict per record. Each time a cycle sees the same disagreement again, it updates that conflict instead of filing a new one.
| Kind | What happened |
|---|---|
| Both changed | Both systems changed the same field or fields since the last sync |
| Delete vs update | One side deleted the record while the other changed it. This always needs a person, whatever the conflict policy |
| Duplicate key | A write to the external system clashed with the key of an existing external record |
| Reference unresolved | The record points at something that has no synced counterpart |
| Validation rejected | The receiving side refused the write, including the guard that stops a record in a final status from being reopened |
| Deleted at source | Push profiles: the source's list of records no longer includes a record the ledger pairs. It was deleted at the source, or it moved out of the filter. Never resolved automatically |
| Column | What it means |
|---|---|
| Profile | Shown on the cross-profile inbox only |
| Entity, Kind | What kind of record, and what kind of conflict |
| Contested fields | The first three contested fields, then +N. Hover over it for the full list |
| xMatix record / External key | The two sides of the pairing |
| Detections | How many cycles have seen this disagreement. Amber at 3, red at 10. A high count means the record has been blocked on every one of those cycles |
| Status | Open, Kept xMatix, Kept external, Merged, Ignored or Superseded |
| First seen / Last seen | When the conflict was first raised, and when a cycle last saw it again |
The inbox loads up to 200 conflicts, the most recently seen first. Profile, Entity and Status are applied on the server, so narrow with them rather than with the search box when the backlog is large.
Resolution outcomes
| Outcome | What it does | Status afterwards |
|---|---|---|
| Keep xMatix | Records that the xMatix values should win. It does not send them: edit the external record to match, then Resume the record | Kept xMatix |
| Keep external | Records that the external values should win. It does not write them into xMatix: edit the xMatix record to match, then Resume the record | Kept external |
| Merged by hand | Records that you lined the values up yourself. The engine writes nothing | Merged |
| Ignore once | Closes the conflict without writing anything | Ignored |
| Ignore always | Closes the conflict and parks the record as Excluded. It stops syncing in both directions until someone selects Resume on the Records tab | Ignored |
None of the outcomes writes a value. After any of the first four, the record stays held as Conflict on the Records tab until someone selects Resume. The next cycle then compares it again under the profile's conflict policy, and raises a new conflict if the two sides still disagree on the same field.
Superseded is set by the engine, not by a person. It means the disagreement went away (the two sides now agree, or the profile's policy settled it), so the conflict was closed and kept for history.
The Records tab
The Records tab is the ledger: it pairs each xMatix record with its external counterpart. Record statuses:
| Status | Meaning |
|---|---|
| In sync | Both sides match the last sync |
| Pending out / Pending in | A change is waiting to go to the external system, or to come into xMatix |
| Conflict | Held by an open conflict |
| Error | Held after failed writes. Failures shows how many in a row |
| Deferred | Waiting for a reference to resolve; tried again next cycle |
| Excluded (parked) | Stopped by Ignore always until resumed |
The tab loads up to 200 rows, the most recently synced first.
The Cycles tab
The sync engine does not currently record cycles, so this tab shows no rows. The columns below describe what the tab is built to show.
| Column | What it tells you |
|---|---|
| Started, Trigger | When the cycle started and why it ran: Scheduled, Manual, Seed or Retry |
| Status, Duration | How the cycle ended and how long it took. Running while it is still going |
| Entities | Entities completed out of entities planned |
| In / Out | Records written into xMatix and records sent out |
| Echoes dropped | Records the engine recognised as its own earlier writes coming back, and dropped. On a settled two-way profile this number is usually the largest. If In, Out and Echoes are all zero, the cycle was idle, which is not the same as settled |
| Conflicts opened, Deferred | New conflicts and deferred records from this cycle |
| Failures | Records that failed in this cycle |
Reading a reconciliation run
Reconciliation lists what changed at the source inside a time window. It then checks each changed record against xMatix.
| Column | Meaning |
|---|---|
| Ran, Window (UTC) | When the run started and the period it checked. Times in this column are UTC |
| Status | Running, Succeeded or Failed. A failed run shows its Error |
| Entities | Entities checked, plus how many were skipped. An entity is skipped when the run could not judge it, for example because its cursor is behind the window or the system cannot list it |
| Source changes | Records that changed at the source in the window |
| Unexplained | Differences the sync cannot account for: Missing + Delete n/a + Deleted here, leaving out informational entities. This is the number to act on |
| Missing | Live at the source with no live record in xMatix |
| Delete n/a | Deleted at the source, still live in xMatix |
| Deleted here | Live at the source, deleted in xMatix |
| Held | Missing, but already held by the engine, which is expected. Not counted as unexplained |
| Informational | Differences on entities that skip some source rows by design. Counted, never alerted |
| Repaired | Records handed back to the engine to read again. This happens only when the profile has auto-repair switched on, and only for entities that support it |
| Alerted | When the run's unexplained differences were reported. Blank when there were none |
Expand a run to see one line per entity. Each line has a Result of Match, N unexplained, Informational or Skipped, plus a Note / samples column with example keys for each class of difference.
Business rules
- Lag colour follows the schedule. If the schedule runs every N minutes, N is the expected interval. Any other schedule — a fixed time of day, a fixed minute each hour, or none — is judged against a one-hour interval. The lag is green up to 2× the interval, amber up to 6×, and red beyond that. A nightly profile therefore turns amber two hours after its cursor last moved and red after six, even though nothing is wrong. Read its lag against its last cycle time. Behind schedule counts the red rows.
- Needs attention lists an enabled profile when any of these is true: lag is amber, red or Never run; the failed streak is above zero; it has open conflicts; it has parked records; an entity needs a reseed; or a site is not reporting. Deferred records alone do not put a profile on the list.
- Sites. Each site has an expected check-in interval, never less than 60 seconds. A site is late after 2× that interval without a check-in and dark after 4×. Not reporting counts only dark sites and sites that have never checked in. A late site still shows as reporting. Sites you switched off are left out.
- One open conflict per record. Seeing the disagreement again updates Detections, Last seen and the contested fields. First seen keeps the original time, so you can tell how old the conflict is.
- A conflict blocks only its own record. Every other record keeps flowing.
- Stored notes are cut to 2,000 characters. The bulk dialog accepts up to 1,000.
Example
On a Monday morning an administrator opens the Sync Monitor and chooses Needs attention. Two profiles remain.
- CRM accounts (every 15 minutes) shows a lag of 2h in red. In the integration app's Errors tab, every run of the last two hours carries an authentication error. The administrator rotates the credential and triggers a cycle. It succeeds, the cursor moves and the row leaves the list.
- Books shows 3 open conflicts. Open conflicts takes the administrator to the Conflicts tab, filtered to that profile. Two are Both changed on an account's phone number. The xMatix number is the newer one, so they copy it into the other system, choose Keep xMatix on both, and select Resume on both records on the Records tab. The third is Delete vs update: the record was deleted in the other system while a sales user edited it here. After checking with the finance team, the administrator selects it, opens Resolve 1 selected, picks Ignore, ticks Also stop syncing these records, and adds the note "Customer closed in books; keep CRM copy." The record now shows Excluded (parked) on the Records tab.
Training
Practice exercise
In a sandbox with at least one sync profile:
- Open Setup → Platform → Monitoring → Sync Monitor and write down the Watermark lag and Parked / deferred values for one profile.
- Edit the same field on one paired record in both systems before the next cycle. After the cycle, find the Both changed conflict on the Conflicts tab and expand it.
- Resolve it with Ignore always. Then find the record on the profile's Records tab by its key.
- Select Resume on it.
Expected result: after step 3 the conflict shows Ignored under All statuses, and the record shows Excluded (parked). After step 4 the record shows In sync with zero failures. If the two values still differ, the next cycle raises the conflict again.
Quick reference
- The Sync Monitor is at Setup → Platform → Monitoring. Profiles are built under Setup → Platform → Sync profiles.
- Start every day on Health → Needs attention.
- Never run is not healthy. It means no cursor exists yet.
- Lag colour assumes a one-hour interval unless the schedule is "every N minutes".
- Cycles are not currently recorded: judge a profile by Watermark lag and the app's Errors tab.
- Parked never clears by itself. Deferred usually does.
- No conflict outcome writes a value. Line the sides up, decide, then Resume the record.
- Ignore always parks the record until Resume on the Records tab.
- To leave a note with a decision, use Resolve selected.
- Deletions the cycle cannot see are found by Reconciliation.
Permissions
| What | Needs |
|---|---|
| Open the Sync Monitor, a profile page and its tabs | Manage integrations (setup.integration.manage) in the user's security profile |
| Resolve conflicts, Resume records, Reseed, Reconcile now | The same capability. There is no separate read-only level |
| Open the integration app's Errors tab, Step data and Replay | Manage integrations |
The Sync profiles menu entry is hidden from users without the capability. The Sync Monitor entry under Monitoring is not hidden. A user without the capability who opens it is refused by the server, and the board shows an error instead of rows.
Configuration
The monitor has no settings of its own. What it shows is controlled by each profile:
| Setting | Where | Effect on the monitor |
|---|---|---|
| Schedule | Profile → Schedule tab | Sets the interval that the lag colour is judged against. Use an "every N minutes" schedule to get exact colouring |
| Enabled | Sync profiles list / profile | Disabled profiles stay on the board but are left out of Needs attention and most tiles |
| Conflict policy | Profile default, and per entity on the Entities tab | Field-level merge settles edits to different fields with no conflict. Manual turns every disagreement into a conflict. Delete vs update always reaches the inbox |
| Conflict check | Per mapped field on the Mapping tab | A field left out of the conflict check is not compared, so it never makes a record conflict. Use it for audit stamps and calculated fields |
| Nightly reconciliation, Reconcile window (hours) | Profile → Schedule tab | Turns on the reconciliation runs. The window is 1–336 hours (default 26). It takes effect on the next Compile |
| Auto-repair | Profile → Schedule tab | Lets a reconciliation hand missing or delete-not-applied records back to the engine (shown as Repaired) |
| Site expected interval | Profile → Sites tab (push profiles) | Sets when a site counts as late or dark |
| Capture step data | The flow in the integration app | Keeps step input and output for successful runs too |
The connector pages explain the settings that matter for each system: Salesforce, Tally and Zoho.
Common problems
A nightly profile is red but its last cycle succeeded
The lag colour assumes a one-hour interval for any schedule that is not "every N minutes", so a once-a-day profile goes red six hours after its cursor moved. Check the integration app's Errors tab for runs since the last scheduled time. If there are none, the profile is fine.
I chose Keep xMatix (or Keep external) but nothing changed
Conflict outcomes record a decision; they do not write values, and the record stays held as Conflict. Copy the winning value to the other side by hand, then select Resume on the record's row on the Records tab.
"Conflict … is already '…' and cannot be resolved again"
Someone else, or the engine, closed the conflict after you loaded the list. Select Refresh. In a bulk resolve, such conflicts are listed as skipped and the rest go through.
A record I resumed is back in Conflict or Error
Resume only lifts the hold. If the two sides still disagree, or the write still fails, the next cycle holds the record again. Fix the data or the cause in Last error first.
Reconcile now is greyed out, or fails
Set Nightly reconciliation on the profile's Schedule tab and select Compile. Until a reconciliation has been compiled, the request fails with The profile has no reconcile flow yet: set a reconcile schedule and compile the profile first.
The Sync Monitor shows an error instead of rows
Your security profile lacks Manage integrations. Ask an administrator to grant it.
Common questions
What is watermark lag, exactly?
Each synced entity keeps a cursor for each direction. The cursor marks the point in the change stream up to which everything has been fully processed. Watermark lag is how long ago the oldest of those cursors last moved, across the profile's active entities. It is the main health signal because it measures results, not activity. A profile can run every cycle on time and still fall behind if its passes keep failing before the cursor moves. A profile with no cursors at all shows Never run, never "0s", so a new or broken profile is not mistaken for a healthy one.
Why does a profile show healthy cycles but sync nothing?
There are three usual causes. First, the profile's sync identity may have narrower record security than it needs; the engine syncs only what that user can see. Second, every read may be dropped as an echo because nothing actually changed — the Echoes dropped column shows this. Third, for push-based systems, the client on the other side may have stopped sending. That is exactly what the Sites column is there to show. For deletions that a delta read cannot see, run a Reconciliation.
Do conflicts block the whole sync?
No. A conflict freezes only its own record, in both directions, and every other record keeps flowing. That is why the backlog still matters: each open conflict is one record standing still. A decided conflict still holds its record until someone selects Resume, so check the Records tab for Conflict rows as well as the inbox.
What is the difference between Ignore once and Ignore always?
Ignore once closes this occurrence. The record stays held as Conflict until you select Resume; after that it syncs again, and a new conflict is raised if the two sides still disagree. Ignore always closes the conflict and also parks the record as Excluded, so it stops syncing in both directions until someone selects Resume on the profile's Records tab. Use Ignore always for records that should deliberately differ between the two systems.
