How to migrate a model

Model migration is the movement of a model from one controller to another. The same configuration of machines, units, and their relations will be replicated on the destination controller, while your applications continue uninterrupted. Note that a controller model cannot be migrated.

Model migrations can be used to simulate a controller upgrade where models are migrated to a newly-created controller (running with a more recent Juju version).

Migration is equally useful for load balancing. If a controller hosting multiple models reaches capacity, you can move the busiest models to a new controller, reducing load without affecting your applications.

For migration to work:

  • The source and destination controllers need to be in the same cloud environment.
  • The destination controller needs to be running on the same cloud substrate as the source controller.
  • Destination controllers on different regions or VPCs need direct connectivity to the source controller.
  • The version of Juju running on the destination controller needs to be the same or newer than the version on the source controller.
  • A model intended to be migrated must have all of its users set up on the destination controller. The operation will be aborted, and an advisory message displayed, if this is not the case.



To start a migration, the client must be aware of the destination controller (i.e., it must show up in juju controllers).

While the migration process is robust, a backup of the source controller before performing a migration is recommended. See Controller backups for assistance.

To migrate a model on the current controller to a destination controller:

juju migrate <model-name> <destination-controller>

A model with the same name as the migrated model cannot exist on the destination controller

You can monitor progress from the output of the status command run against the source model. You may want to use a command such as watch to automatically refresh the status output, rather than manually running status each time:

watch --color -n 1 juju status --color

In the output, a ‘Notes’ column is appended to the model overview line at the top of the output. The migration will step through various states, from ‘starting’ to ‘successful’.

The ‘status’ section in the output from the show-model command also includes details on the current or most recently run migration. It adds extra information too, such as the migration start time, and is a good place to start if you need to determine why a migration has failed.

This section will look similar to the following after starting a migration:


current: available

since: 23 hours ago

migration: uploading model binaries into destination controller

migration-start: 21 seconds ago

Migration time depends on the complexity of the model, the resources it uses, and the capabilities of the backing cloud.

If failure occurs during the migration process, the model, in its original state, will be reverted to the original controller.


When the migration has completed successfully, the model will no longer reside on the source controller. It, and its applications, machines and units, will be running on the destination controller.

Inspect the migrated model with the status command:

juju status -m <destination-controller>:<model>

On v.2.6.0 (both client and source controller) if the model is accessed using the old/source controller the operator is guided to the new controller:

juju status -m <source-controller>:<model>

In this case, the following responses are possible:

a) if the controller is known to the client:

ERROR Model "migrate" has been migrated to controller "dst".

To access it run 'juju switch dst:migrate'.

b) if the controller is unknown to the client:

ERROR Model "migrate" has been migrated to another controller.

To access it run one of the following commands (you can replace the -c argument with your own preferred controller name):

'juju login -c dst'

New controller fingerprint [93:73:88:C9:9A:AA:EC:C8:85:AE:D1:33:E5:92:CE:95:0F:B6:00:82:21:CB:8C:A0:42:16:29:77:CF:6D:B6:D4]

See Log in to a controller for background information.

Migrating large models

When a model is migrated, the agents running for each machine and unit need to reestablish a connection to the new controller. If the model is large, it may be that the number and frequency of incoming connections is enough to overload the controller. There are 2 controller config settings which can be used to throttle the agent reconnection rate.

  • agent-ratelimit-max - the number of agents allowed to connect before rate limiting kicks in
  • agent-ratelimit-rate - the minimum time interval between connections when rate limiting is active

The default values for these config attributes are:

  • agent-ratelimit-max = 10
  • agent-ratelimit-rate = 250ms

When migrating large models, with high performing controllers, these values may be better, in order to address pre- or post- check errors that may be reported:

  • agent-ratelimit-max = 100
  • agent-ratelimit-rate = 50ms

For example:

juju controller-config agent-ratelimit-rate=50ms
juju controller-config agent-ratelimit-max=100

Last updated 2 months ago.