Limitations
n8n-sync is intentionally narrow: it is a one-way, eventually-consistent mirror of workflow, credential, and (opt-in) execution state across n8n instances. These are the things it explicitly does not do, and the platform reasons why.
n8n-platform quirks
- Deactivation does not sync. n8n fires no external hook on workflow deactivation;
deactivateWorkflowonly emits an internal event. The target corrects state on the next update or activate event, or stays active until then. Do not try to work around this with polling. workflow.activatefires pre-commit. If a later hook rejects the activation, the subscriber may briefly hold an uncommitted state; the next event converges it. The applier treatsactivateas an upsert so state converges.- Repository access happens only inside the
n8n.readyhook, where n8n's DIContaineris initialized. Resolving it earlier crashes the subscriber.
Wire / delivery semantics
- One-way, revision-ordered, last-write-wins. Sync is directional. The subscriber first enforces source-scoped
entityRevisionordering, then row timestamp guards (updatedAtfor workflows/credentials,stoppedAtfor executions). Exact duplicate deliveries are no-ops; conflicting revision reuse returns409 SYNC_REVISION_CONFLICT. - The delivery queue is in-memory and bounded. Events queued but not yet delivered when the source instance restarts are lost. If
SYNC_MAX_QUEUE_SIZEis exceeded, the oldest queued event for that target is dropped and logged. Later upserts may converge state, but dropped deletes, archives, or mixed operations are not reconstructed automatically. - Active state publishes on the target. With
SYNC_APPLY_ACTIVE_STATE=true, the subscriber publishes/unpublishes the synced workflow via n8n'sWorkflowService, which registers triggers/webhooks with the target's active workflow manager. Publication failures are logged as warnings and the event still returns applied, so a failed publish retries on the next event. Keep itfalse(the default) for passive-standby targets. - Deletes and archives for unknown IDs are no-ops.
update/deleteon missing rows return early; sync is eventually consistent by design. - State is file-backed. Publisher and subscriber JSON state writes are atomic per file only; they are not atomic with n8n database mutations or other sync state files. See Persistence & Readiness.
Credentials
- Credential sync requires a shared
N8N_ENCRYPTION_KEYon all instances. Credentialdatais an encrypted blob passthrough — the publisher never decrypts it and the subscriber stores it as-is, so the target instance's key must match the source's for the credential to remain usable at runtime.
Executions
- Execution sync requires workflow sync.
SYNC_ENTITIEScannot enableexecutionswithout also enablingworkflows; startup fails fast. - Execution sync is summary-only.
SYNC_ENTITIES=...,executionsupserts a row in the target'sexecution_entitytable with a target-generated id recorded in the file-backed source-execution mapping, plus scalar lifecycle columns (source id,workflowId,status,mode,finished,startedAt,stoppedAt) and a best-effort workflow snapshot. Theexecution_datablob (per-stepfullRunData) is not written to keep payloads small; target-side reads via the Public API will see the execution summary but not its run detail. - Execution staleness is based on
stoppedAt. In-flight executions (running,waiting,new) carrystoppedAt: null; for them the last-write-wins guard is skipped so a later delivery can still converge state. Re-deliveries of the same event are no-ops. startedAt/createdAtare immutable post-insert onexecution_entity— the applier mirrors n8n's ownupdateExistingExecutionsemantics and drops them from update payloads.- Workflow deletion removes synced executions first. Before applying
workflow.delete, the subscriber deletes mapped synced execution rows for that source/workflow so the target workflow delete does not fail on dependent execution rows.
Auth
- Auth modes do not cross-accept. A token-mode subscriber rejects hmac-signed requests and vice versa. Both sides must use the same
SYNC_AUTH_MODE. See Authentication. - Replay rejection is HMAC-only and process-local. Exact signed replays are rejected only in
hmacmode and only while this process's replay cache remembers the signature. The cache is not shared across OS processes and is cleared on restart.
Project assignment
- Workflow and credential ownership is best effort. When
SYNC_TARGET_PROJECT_IDis set, newly created workflows/credentials are linked to that project. When empty, the applier falls back to the target instance owner's personal project, resolved lazily and cached for the process lifetime including lookup misses. Owner-link failures are logged and are not currently retryable or transactional with the entity mutation. - Source ownership policy is provisional in production. Workflow and credential upserts, archives, and deletes still operate on source-provided target IDs after authentication and ordering checks. Native-row and cross-source collision risks remain until source-bound workflow/credential identity mappings are implemented.
Filtering
- Tag filtering is source-side only.
SYNC_FILTER_BY_TAGrewrites the publisher's DTOs and may turn an upsert into a delete; the subscriber never sees or honors tag fields. Tagging a workflow on the source does not propagate the tag itself to the target. See Tag-based Filtering.
Reference
- Architecture — the design that produces these behaviors.
- Wired Hooks — the hook surface selection rationale.
- Environment variables —
SYNC_APPLY_ACTIVE_STATE,SYNC_TARGET_PROJECT_ID,SYNC_ENTITIES. - Persistence & Readiness — state files, readiness, and recovery guidance.