Deploying a Dedicated Synchronizer
This tutorial walks you through deploying a dedicated synchronizer (also called an extension synchronizer): configure sequencer and mediator nodes, start them, bootstrap topology, connect validators, and verify the deployment.
It is for operators who run their own synchronizer alongside — or instead of relying solely on — the Global Synchronizer. It is not the Super Validator / Global Synchronizer operator guide.
For concepts first, see Dedicated Synchronizers. For deep reference (all bootstrap variants, HA, pruning, and so on), use Synchronizer Operations — this page is the end-to-end walkthrough; that page is the reference.
Default path for this guide: one sequencer + one mediator, single owner, BFT sequencer backend (minimal single-node network). Background on the orderer is in BFT Orderer Architecture. API, backend, and TLS details are in Synchronizer Operations — configure.
For peers, endpoint authentication, dedicated BFT storage, external sequencers, and client authentication, use the operations reference — do not expand this tutorial into those variants.
This runs the sequencer and mediator in one process. To run them as separate processes, put each node’s block in its own file (each wrapped in
If you enabled TLS on the public API, add the matching client TLS settings to
This creates the synchronizer identity and registers the sequencer and mediator in the synchronizer topology. You should see a physical synchronizer id for
Or configure the connection in the validator’s Helm values:
Setup order
- Configure — APIs, sequencer backend, TLS, and storage
- Start — Deploy and start sequencer and mediator
- Bootstrap — Initialize synchronizer topology
- Connect — Attach validators / participants
- Verify — Health, topology, and a test transaction
- Harden (optional) — HA, monitoring, backups, and related ops
Who this guide is for
Use this guide when:- You need a dedicated synchronizer for privacy, performance, governance, or cost reasons
- A single organization will own and operate the sequencer and mediator (the default path below)
- You may later connect the same validators to the Global Synchronizer (hybrid pattern)
Choose your topology
| Choose… | When… | Then follow… |
|---|---|---|
| Centralized, single-operator (default) | One org owns sequencer and mediator | This tutorial |
| Decentralized / multi-owner | Distinct operators must co-sign topology | Decentralized bootstrap |
| HA / multi-sequencer | Production redundancy | Finish this tutorial, then High Availability |
| Hybrid (dedicated + Global Synchronizer) | Need CN connectivity as well | This tutorial, then hybrid pattern and linking validators |
The database sequencer backend is unsupported. Use the BFT sequencer backend for new dedicated synchronizers. Multi-node BFT peer networks and advanced backend options are covered under Configure Sequencer Backend.
Prerequisites
Before you begin:- Familiarity with Canton’s synchronizer architecture
- PostgreSQL 14+ — separate databases for sequencer and mediator; for production, a managed service with automated backups, at least 4 vCPUs / 16 GB memory, and SSD-backed storage
- TLS certificates for the sequencer public API (validators connect here)
- The Canton 3.5 release (
canton-open-source-3.5.<patch>.tar.gzfrom Canton releases) for the sequencer and mediator - Shell access to the host that runs the sequencer and mediator, for the Canton Console
1. Configure APIs, backend, and TLS
Write configuration before starting nodes. At minimum you need:- Sequencer and mediator APIs — public and admin ports/addresses (Configure Synchronizer APIs)
- Sequencer backend —
sequencer.type = BFTfor the default path (Configure Sequencer Backend) - TLS on the sequencer public API (Secure Synchronizer APIs)
- Storage — Postgres for each node (next section)
synchronizer.conf and fill in each node’s Postgres connection from step 2. The public API listens on 127.0.0.1 unless you set address, so validators on other hosts need address = "0.0.0.0" (or a specific interface):
canton {
sequencers {
sequencer1 {
storage.type = postgres
// ... postgres connection ...
public-api {
address = "0.0.0.0"
port = 5001
// TLS: see Secure Synchronizer APIs
}
admin-api.port = 5002
sequencer.type = BFT
}
}
mediators {
mediator1 {
storage.type = postgres
// ... postgres connection ...
admin-api.port = 5202
}
}
}
2. Set up databases
Create separate PostgreSQL databases and dedicated users, for examplesequencer_db / sequencer_user and mediator_db / mediator_user. Each node stores its own state independently.
Point the sequencer and mediator storage configuration at those databases before you start the nodes.
3. Deploy and start sequencer and mediator
Download the Canton 3.5 release (canton-open-source-3.5.<patch>.tar.gz) from Canton releases and unpack it. From the unpacked directory, start both nodes with the configuration from step 1:
./bin/canton daemon --config synchronizer.conf
canton { }) and start one daemon per file.
The published
canton-sequencer and canton-mediator Docker images ship with their own built-in configuration (node names, ports, manual identity initialization, and the database sequencer backend), so this guide’s configuration doesn’t apply to them unchanged. See Canton Docker Operations.Open a Canton Console
Bootstrap runs in a Canton Console that reaches the nodes’ admin APIs. The admin APIs insynchronizer.conf listen on 127.0.0.1 by default, so run the console on the same host. Save this as remote.conf:
canton {
remote-sequencers {
sequencer1 {
public-api {
address = "localhost"
port = 5001
}
admin-api {
address = "localhost"
port = 5002
}
}
}
remote-mediators {
mediator1 {
admin-api {
address = "localhost"
port = 5202
}
}
}
}
public-api in this file. Then start the console:
./bin/canton --config remote.conf
Confirm nodes are healthy
Before bootstrap:- The sequencer and mediator processes are running
- Sequencer health endpoint returns HTTP 200 (when exposed)
nodes.remote.foreach(_.health.wait_for_running())returns in the console
4. Bootstrap (initialize) the synchronizer
Nodes must be fresh (not previously initialized), started, and already configured with backend, APIs, TLS, and storage. In the console you opened in step 3 (default centralized bootstrap — single owner, threshold 1):@ bootstrap.synchronizer(synchronizerName = "my-private-sync", sequencers = Seq(sequencer1), mediators = Seq(mediator1), synchronizerOwners = Seq(sequencer1), synchronizerThreshold = PositiveInt.one, staticSynchronizerParameters = StaticSynchronizerParameters.defaultsWithoutKMS(ProtocolVersion.forSynchronizer))
res1: PhysicalSynchronizerId = PhysicalSynchronizerId(
logical = SynchronizerId(
uid = UniqueIdentifier(
identifier = String185(str = "my-private-sync"),
namespace = Namespace(fingerprint = 122032922613...)
)
),
serial = NonNegativeNumeric(value = 0),
protocolVersion = 36
)
my-private-sync (or the name you chose).
Other bootstrap flows (do not inline here):
- Decentralized synchronizer
- Decentralized with a subset of sequencers as owners
- Permissioned synchronizer
5. Connect validators
Once the synchronizer is initialized, connect each validator (participant). On the Canton Console:@ participant1.synchronizers.connect_local(sequencer1, "my-private-sync")
This command works when the same console manages the sequencer and the validator. A validator run by another organization connects by URL instead; see Connect to a Sequencer by URL.
extraDomains:
- alias: "my-private-sync"
url: "https://sequencer.example.com:5001"
extraDomains accepts only alias and url. If the sequencer’s TLS certificate isn’t signed by a CA the Java runtime trusts by default, connect from the console with connect(..., certificatesPath = ...) instead.
Use a stable alias (here my-private-sync) consistently in console and Helm. After changing connection config at runtime, disconnect and reconnect the synchronizer on the participant so the update takes effect.
For validators that also stay on the Global Synchronizer, see linking a validator to multiple synchronizers.
6. Verify the deployment
Work through this checklist:- Sequencer health — HTTP health endpoint returns 200
- Mediator in topology — Mediator is registered on the synchronizer
- Participant connected —
participant.synchronizers.list_connected()shows your alias - Ping — Participant can ping across the synchronizer (see bootstrap examples in Synchronizer Operations)
- Optional smoke test — Allocate a test party and create a contract assigned to the dedicated synchronizer
Production hardening and next steps
- TLS everywhere — Validators to sequencer public API; prefer TLS for peer and admin paths in production (Secure Synchronizer APIs)
- Network policies — Restrict sequencer endpoint access to known validator networks
- Monitoring — Synchronizer monitoring; reuse your validator metrics stack where possible
- Backups — Back up sequencer and mediator databases regularly (Backup and Restore)
- HA — High Availability in Synchronizer
- Traffic management — If you enable traffic controls on a dedicated synchronizer, see Sequencer Traffic Management
- Pruning — Synchronizer Pruning
Related reference
- Dedicated Synchronizers — Why and when to use them
- Hybrid Synchronizer Pattern — Dedicated + Global Synchronizer
- Linking Validators — Multi-synchronizer participants
- Synchronizer Operations — Configure, bootstrap variants, HA, traffic, pruning, backup
- BFT Orderer Architecture — Ordering backend background
- Synchronizer Monitoring — Observability