Migrating a Self-Hosted AI Agent: The One Thing You Can't Run in Parallel

Axel Grubba, October 02, 2026
Start selling digital products with Crevio
Crevio E-Commerce Platforms logo
Crevio
Sponsored
5.0
(1)
Free plan available
Crevio is an AI-powered platform that runs your business while you sleep. Describe what you want to se... Learn more about Crevio
Get an AI summary of this post on:

Every migration guide gives you the same shape: build the new server, run both in parallel, lower your DNS TTL, flip the record, decommission the old one. It’s good advice for a website.

For an AI agent it will lose you messages, and the reason is structural rather than a matter of care.

An agent isn’t a thing users connect to. It’s a thing that connects out — to Telegram, to WhatsApp, to Slack — and holds those connections open. Those channels permit exactly one consumer at a time. Two instances holding the same Telegram bot token or the same WhatsApp linked session don’t share the load; they fight, and messages fall through the gap.

So the correct pattern is narrower than the usual one: parallel-build, exclusive cutover.

Timeline showing the old server serving with channels connected while the new server is built and validated with channels switched off, which is safe to run in parallel because the new box holds no channel session; then a handover window where the old server must stop before the new one starts, because both connected means dropped messages; then the new server serving with channels connected

First, work out whether DNS matters at all

Before lowering any TTLs, ask what actually points at the server’s IP address. For a lot of agent deployments, the answer is nothing.

  • Telegram — OpenClaw uses long polling by default, and the docs are explicit that “long polling is the default transport; webhook mode is optional.” The agent dials out to Telegram. Your IP is irrelevant to it.
  • WhatsApp via Baileys — an outbound WhatsApp Web connection. Also dials out.
  • A dashboard you reach over Tailscale — no public DNS involved.

DNS only matters if something inbound points at the box: a public dashboard on a domain, a Telegram webhook if you deliberately enabled that mode, or third-party services POSTing to you. If that’s you, lower the TTL to 300 seconds a day ahead. If it isn’t, skip the DNS choreography entirely — it’s ceremony borrowed from web migrations that doesn’t apply here.

Build the new box with channels switched off

This is the part you can safely do in parallel, and it’s where the time goes anyway.

Provision, harden, and install — with every messaging channel disabled in config. A new gateway with channels off can run for days beside the old one without conflicting, because it holds no channel session.

Validate what you can without channels:

openclaw doctor
openclaw gateway status
curl -fsS http://127.0.0.1:18789/healthz

If you’re reaching a dashboard by hostname, test it before DNS moves by overriding resolution locally rather than changing the record:

# /etc/hosts on your laptop
203.0.113.10   agent.example.com

That gives you the real hostname pointed at the new server for your machine only. Remove the line afterwards — a stale hosts entry is a genuinely confusing thing to debug two weeks later.

Sync the state

Two rsync passes: a bulk one while the old server is still live, and a delta during the handover window.

# bulk pass, old server still serving
rsync -aHAX --numeric-ids --info=progress2 \
  ~/.openclaw/ user@new-server:~/.openclaw/

-a preserves permissions and timestamps, -H hard links, -AX ACLs and extended attributes, --numeric-ids avoids remapping ownership through mismatched user tables.

Know which directories you’re moving, because agents keep secrets in more than one place. For OpenClaw specifically:

  • the config directory — openclaw.json, stored provider auth profiles, and the .env holding your gateway token
  • the auth-profile secret directory, which is deliberately stored separately and holds the encryption key for OAuth-backed token material
  • WhatsApp credentials at ~/.openclaw/credentials/whatsapp/<accountId>/creds.json

Copy the config directory without the secret directory and your stored provider auth arrives as material you can no longer decrypt. That’s the migration that appears to succeed and then quietly can’t authenticate to anything.

If you run in Docker, the equivalent is the mounted host paths rather than the container — what persists where covers the mapping.

The handover window

Now the part that has to be sequential. Keep it short — a couple of minutes is normal.

1. Stop the old agent. Stop the whole gateway, not just the container’s web port. The goal is that no process anywhere still holds a channel connection.

# old server
sudo systemctl stop openclaw     # or: docker compose down

For WhatsApp there’s a cleaner option than a hard stop, because OpenClaw’s logout “stops the live listener for that account first, so the linked session stops receiving messages before the next restart.” Use it when you want a definite release rather than hoping the process died tidily.

2. Final delta sync. Same command as before; it now moves only what changed, which is seconds.

3. Enable channels on the new box and start it.

# new server
sudo systemctl start openclaw
openclaw channels status --probe

4. Send a real message on each channel and confirm a reply. Not status output — an actual message, because status can look healthy while delivery isn’t. For WhatsApp in particular, a reply only counts as delivered once the transport returns an outbound message ID.

5. Leave the old server switched off but not destroyed for a week. It costs a few pounds and it’s the only rollback you have.

Channel by channel

Telegram (polling — the default). Nothing to re-point. The bot token is in your config, it moved with the sync, and the new instance starts polling. The one failure to know: if the old instance is still polling, the new one gets a getUpdates conflict, because Telegram permits one consumer of that token. If you see that, something on the old box is still running.

Telegram (webhook mode — only if you chose it). Update webhookUrl to the new host and restart. Note the listener reserves /healthz, so webhookPath must be a different route. Also worth knowing: a webhook left registered from the old host will conflict with polling on the new one, which surfaces as the same getUpdates conflict rather than an obvious webhook error.

WhatsApp. The linked session lives in that credentials directory and is tied to the linked device, not to an IP — so if you synced it, the session should resume without a new QR scan. If it does ask for a QR, the credentials didn’t arrive intact; restore them rather than re-linking, because re-linking on the new box invalidates the old link and removes your rollback. Never run both instances with the same WhatsApp credentials — that’s the single most damaging thing you can do during this migration.

Slack, Discord and webhook-driven integrations. These are the ones that genuinely need re-pointing, because they hold a URL you own. Update event subscription and webhook URLs in each third-party service after DNS has moved, and test each one. This is the step people forget, and it fails silently — the agent looks fine and simply never hears from the service again.

Then verify properly

openclaw doctor
openclaw channels status --probe
openclaw logs --follow

And check the new box’s exposure before you relax, because a fresh server is a fresh set of defaults: confirm nothing is listening publicly that shouldn’t be. If you moved to a Docker-based deployment, remember ufw does not filter Docker-published ports.

Watch memory for the first day too. A new host with a different RAM allocation is where OOM kills show up — and they present as the agent dying mid-task with an empty log, which during a migration you’ll be tempted to blame on the migration.

Where to move to

If you’re migrating because the current box is too small, size for the workload rather than the current bill: 4GB is the floor for a text-only agent and 8GB the moment browser automation is involved, since a single headless Chromium wants 1–2GB by itself.

Hostinger is the easiest landing spot — generous RAM per tier and a one-click OpenClaw path if you’d rather not rebuild by hand. Hetzner is the cheapest per gigabyte when its CX tier is in stock — worth checking before you commit, because that tier was showing as unavailable when we last looked, and the CPX line you’d fall back to is several times dearer. In stock, it is the better answer if you’re comfortable administering a plain box, which you evidently are if you’re reading a migration runbook.

Our best VPS for OpenClaw guide prices the comparison, and self-hosting OpenClaw on a VPS covers building the new box with hardening done first.

How we checked this

The channel behaviours here are from OpenClaw’s own documentation, read in August 2026: that long polling is the default Telegram transport and webhook mode optional, that a competing consumer surfaces as a getUpdates conflict, that WhatsApp auth lives at ~/.openclaw/credentials/whatsapp/<accountId>/creds.json, that logout stops the live listener before the next restart, and that the auth-profile secret directory is stored separately from the config directory. The single-consumer constraint is why this runbook departs from the usual parallel-run advice.

What we did not do: we did not perform this migration end to end for this article. The sequence is built from documented behaviour and standard practice rather than a timed run, and the step we’d most encourage you to treat as mandatory is the one that costs nothing — keeping the old server switched off rather than destroyed for a week, so that “it didn’t work” has a remedy.

We’ve also deliberately not given a total downtime figure. It depends on how much state you’re syncing and how many third-party integrations need re-pointing, and a number here would be a guess dressed as a benchmark.

The two hosting links above are affiliate links, and they’re only relevant if you’re moving because you need a different machine. Nothing in the runbook requires changing provider.

FAQ

Can I run the old and new agent at the same time during migration?

Only with the new instance’s messaging channels disabled. Two instances holding the same Telegram bot token or WhatsApp session conflict rather than share — Telegram permits one consumer of a token, and a WhatsApp linked session belongs to one client. Build in parallel, hand over exclusively.

Do I need to change DNS to migrate an AI agent?

Often not. Agents connect outward to messaging platforms, so no inbound record points at them. DNS matters only if you host a public dashboard, use Telegram webhook mode, or receive webhooks from third-party services.

Will I have to scan the WhatsApp QR code again?

Not if the credentials directory syncs intact — the session is tied to the linked device rather than the server’s IP. If it does prompt for a QR, restore the credentials rather than re-linking, because re-linking invalidates the old session and destroys your rollback.

Why is my new agent getting a getUpdates conflict?

Something else is still consuming that Telegram token — usually the old instance still running, occasionally a webhook registered from the previous host. Stop the old gateway completely, and clear any webhook if you’d enabled webhook mode.

What do I actually need to copy?

The config directory (config, provider auth profiles, environment secrets), the separately-stored auth-profile secret directory that holds the encryption key for OAuth token material, and channel credentials such as the WhatsApp auth directory. Copying config without the secret directory produces stored auth you can’t decrypt.

How long should I keep the old server?

A week, powered off rather than deleted. It’s the cheapest rollback available, and integration failures — a Slack subscription that was never re-pointed — often surface days later rather than at cutover.

Which order should I do this in?

Build and validate the new box with channels off, bulk rsync, stop the old gateway, delta rsync, start the new one with channels on, send a real message on each channel, then re-point third-party webhooks. Sequential only where it has to be.

Founder & Software Review Editor
Axel Grubba is the founder of Findstack, a B2B software comparison platform, with his background spanning management consulting and venture capital where he invested in software. Recently, Axel has developed a passion for coding and enjoys traveling when he is not building and improving Findstack.
Business Software Reviews SaaS Product Evaluation CRM Software
Subscribe, get software deals straight to your inbox.
Join 8,500+ other entrepreneurs staying up-to-date on all the latest deals.
Zero spam. Unsubscribe at any time.