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, last-write-wins. Sync is directional. Upserts carry the source monotonic timestamp (
updatedAtfor workflows/credentials,stoppedAtfor executions) and are skipped when the target row is already at or beyond it, so out-of-order or duplicate deliveries cannot regress state. Deletes and archives are applied unconditionally. - The delivery queue is in-memory. Events queued but not yet delivered when the source instance restarts are lost; state converges on the next event for that entity (or stays divergent until then).
- Active state is DB-only. With
SYNC_APPLY_ACTIVE_STATE=true, the target'sactiveflag is written to the database, but triggers/webhooks are not registered with the target's active workflow manager until restart or manual toggle. 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.
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 is summary-only.
SYNC_ENTITIES=…,executionsupserts a row in the target'sexecution_entitytable with the source ID and scalar lifecycle columns (id,workflowId,status,mode,finished,startedAt,stoppedAt, retry ids,workflowVersionId) plus 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.
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.
Project assignment
SYNC_TARGET_PROJECT_ID(default empty) — when 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 viaUserRepository+ProjectRepository.getPersonalProjectForUser, cached for the process lifetime including the negative case). The fallback makes synced entities visible through the target's Public API without explicit configuration. An explicitSYNC_TARGET_PROJECT_IDalways wins.
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.