Migrating from v1
Move a v1 installation to v2: convert the config, import jobs from Redis, update clients and switch over.
Version 2 changes the config format, the store and the API. The migration tool handles the data; the rest is a short list of renames. Plan for an hour, with a few minutes of paused scheduling.
What changed
| v1 | v2 |
|---|---|
sextant.yaml |
sextant.toml |
sextant start (server and worker in one) |
sextant server and sextant worker |
| Redis only | SQLite or Postgres |
/api/v1/... with X-Sextant-Key |
/v2/... with Authorization: Bearer |
retries, retry_delay |
max_attempts, backoff.* |
callback_url on each job |
Webhooks |
| Node and Python SDKs | Node, Python and Go |
Steps
-
Convert the config
Shellsextant migrate config --from sextant.yaml --to sextant.tomlThe tool prints what it could not map. Most often that is
retry_delay, which becomesbackoff.base, withstrategy = "fixed"to keep the old behaviour. -
Pick the new store and start v2 beside v1
sextant.tomlTOML[store] driver = "postgres" dsn = "postgres://sextant@db:5432/sextant"Start
sextant serveron a different port. v1 keeps running. -
Pause scheduling in v1
Stop v1 from creating jobs:
sextant pause --allin v1, or stop the v1 scheduler process. -
Import
Shellsextant migrate from-v1 --redis redis://localhost:6379/0 --dry-run sextant migrate from-v1 --redis redis://localhost:6379/0Pending jobs, delayed jobs and cron entries are imported. Finished jobs are not; v1’s history stays in Redis.
-
Switch the clients
Replace the API key header and the base path, or upgrade the SDKs. Until you do, you can run the compatibility layer, which serves the old routes on top of the new server:
sextant.tomlTOML[compat] v1_api = true -
Move workers and retire v1
Start
sextant worker(or your SDK workers) against v2, watchsextant_queue_wait_seconds, then stop v1.
Code changes
// v1
import Sextant from 'sextant';
const client = new Sextant({ key: process.env.SEXTANT_KEY });
await client.enqueue('send-receipt', { orderId }, { retries: 3, delay: 600 });
// v2
import { Sextant } from '@sextant/node';
const sextant = new Sextant({ token: process.env.SEXTANT_TOKEN });
await sextant.jobs.create({ queue: 'emails', handler: 'send-receipt', payload: { orderId }, maxAttempts: 4, runAt: new Date(Date.now() + 600_000) });# v1
client = sextant.Client(key=os.environ["SEXTANT_KEY"])
client.enqueue("send-receipt", {"order_id": order_id}, retries=3, delay=600)
# v2
from sextant import Sextant
client = Sextant(token=os.environ["SEXTANT_TOKEN"])
client.jobs.create(queue="emails", handler="send-receipt", payload={"order_id": order_id},
max_attempts=4, run_at=datetime.now(timezone.utc) + timedelta(seconds=600))Note that retries counted retries and max_attempts counts attempts: retries=3 is max_attempts=4.
After the switch
Run sextant queues list and sextant schedules list and compare them with v1’s dashboard. Keep the compatibility layer on for one release cycle, then turn it off and watch the logs for compat.v1 lines to find clients you forgot.