ENABLE MANAGED CONFIG FOR MULTI-INSTANCE SERVE
This guide shows you how to enable managed config so that multiple swamp serve
instances share configuration through the datastore. Config changes on one
instance — creating a model, pulling an extension, updating a vault — propagate
to every other instance automatically.
Prerequisites
- A shared datastore accessible by all instances (e.g., S3 or GCS)
- The datastore extension must support the
configRefreshsync capability:@swamp/s3-datastore>= 2026.08.27@swamp/gcs-datastore>= 2026.08.27
- A running multi-instance deployment — see Run a Multi-Instance Deployment
Check your extension version:
$ swamp extension list --json | grep s3-datastoreIf the version predates 2026.08.27, update the extension:
$ swamp extension pull @swamp/s3-datastore1. Seed pulled-extension sources into the datastore
Before migrating config, ensure that pulled-extension source files are present
in the remote datastore. config migrate copies from the local
.swamp/pulled-extensions/ directory, which may be empty if extensions were
installed on a different machine.
$ swamp extension install
$ swamp datastore sync --pushWarning
Without this step, config migrate may produce an incomplete
config/pulled-extensions/ tree in the remote datastore. Serve instances that
hydrate from it will log "N pulled extension(s) have missing source files"
and fail to load those extensions.
2. Run the migration on one instance
Pick one instance and run the config migration. This copies existing config
into the datastore and sets managedConfig: true in .swamp.yaml:
$ swamp datastore config migrateYou will see output like:
[INF] cli: Set managedConfig: true in .swamp.yaml
[INF] cli: Migrated "models, workflows, vaults, lockfile, pulled-extensions" into datastore config tier
[INF] cli: Pushed config to datastoreThe Pushed config to datastore line appears with a remote datastore.
The command is idempotent — running it again detects the migration sentinel and skips the copy:
$ swamp datastore config migrate --json{ "alreadyMigrated": true, "managedConfigSet": false }managedConfigSet is true when the run set managedConfig: true in this
repository's .swamp.yaml, and false when the flag was already set.
Migrate pulls the datastore's config before it checks whether the datastore is already migrated, so the datastore must be reachable even on a repository that is already migrated.
If the push fails, migrate exits non-zero and keeps the migration locally:
The migration is saved locally but was not published to the datastore: <reason>. Run 'swamp datastore config migrate' again to publish it.Run swamp datastore config migrate again once the datastore is reachable. The
re-run publishes the migration. Do not use swamp datastore sync --push to
recover: it would publish the migrated files without the migration sentinel.
Warning
Do not run config migrate on multiple instances concurrently. The migration
writes index entries to the datastore, and concurrent runs can clobber each
other's entries.
3. Configure other instances
Each additional instance needs managedConfig: true in its .swamp.yaml. Once
the flag is set, the instance stops reading its local models, workflows and
vaults and uses the ones in the datastore.
Either run the migration on the instance. It finds the datastore already migrated, skips the copy, and sets the flag:
$ swamp datastore config migrate[INF] swamp·datastore·managed-config-migration: Config migration already completed (sentinel exists)
[INF] cli: Set managedConfig: true in .swamp.yaml
[INF] cli: Config migration already completedOr copy the change from the first instance's .swamp.yaml:
datastore:
type: "@swamp/s3-datastore"
managedConfig: true
config:
bucket: my-bucket
region: us-east-1The .swamp.yaml file is the one piece of configuration that is not managed
in the datastore — it is the bootstrap file and must be distributed to each
instance manually (via your deployment pipeline, config management tool, or
container image).
4. Restart serve instances
Restart the other swamp serve instances. On startup, each instance performs an
early config pull from the datastore before loading extensions, so it starts
with the latest shared config:
$ swamp serve \
--host 0.0.0.0 \
--auth-mode token \
--cert-file /etc/swamp/tls/cert.pem \
--key-file /etc/swamp/tls/key.pemNo additional flags are needed — the ConfigPoller starts automatically when
managedConfig: true is set.
5. Verify config propagation
Create a model on one instance and verify it appears on another:
$ swamp model create test-model --server https://instance-a:9090
$ swamp model list --server https://instance-b:9090 --json | grep test-modelThe model should appear on instance B within ~30 seconds (the default ConfigPoller interval).
Clean up the test model:
$ swamp model delete test-model --server https://instance-a:9090How config changes propagate
Once managed config is enabled, config changes flow through two mechanisms:
- Immediate push. When an operative modifies config through a running instance (model create, extension pull, vault update), that instance pushes the change to the datastore immediately.
- ConfigPoller. Each instance polls the datastore every 30 seconds for
config changes. A
commitSeqfast-path skips the full pull when no changes have occurred, keeping the polling cost minimal.
The result is that config changes propagate to all instances within ~30 seconds under normal operation.
What stays local
The following are never stored in the managed config tier:
| Item | Reason |
|---|---|
.swamp.yaml |
Bootstrap config — manual per-instance setup |
Skills (.claude/skills/) |
Tool-specific, not shared across instances |
| Extension source dirs | User-authored code, versioned in git |
| Bundles | Derived artifacts, rebuilt from sources |
Related
- Datastore Configuration — Managed Config
— reference for the
managedConfigfield,configRefreshcapability, andconfig migratecommand - swamp serve — Config management — architectural decisions behind ConfigPoller and config propagation
- Run a Multi-Instance Deployment — prerequisite guide for multi-instance HA deployments