Labels are tags that you can add to changesets to control which changeset will be executed in any migration run. Labels control whether a changeset is executed depending on runtime settings. Any string can be used for the label name, and it is case-insensitive.

Labels allow you to choose a subset of changesets to execute at runtime and represent a simple list on each changeset and complex expressions that are supplied at runtime. This means that changesets are tagged with a list of labels (not expressions), and during runtime, you can pass a labelFilter expression to choose the changesets which matches the expression.

Labels work best when the changeset author can simply enumerate or describe what a changeset is used for, such as a particular feature or version. There may be greater complexity at runtime to determine what label expression should be used to perform the deployment, but that control is left to the deployment manager or person executing the changesets. Labels are best if you want to determine any complex filtering logic at runtime, rather than by the changeset author.

In Liquibase Pro 4.23.1+, you can easily set labels in bulk from your command line with the set-labels command instead of specifying them manually in your changelog.


You can typically use labels to:

  • Manage and track your deployments.
  • Apply complex logic to your deployments.
  • Mark changesets based on features and then selectively apply those features at the execution time instead of using version control branches.
  • Use different languages for marking changesets. For example, you can mark your changesets both with Spanish and English.
  • Assign ticket numbers to particular changesets to track and identify their purpose, such as JIRA ticket numbers

labelFilter runtime syntax

In Liquibase 4.23+, you can specify a label using @ in addition to AND, OR, !, and parentheses in the changesets. The @ is used for labels only at run time and forces any specific labeled changeset to execute.

Example: If a changeset is labeled as label=test, only this changeset will be forced to execute if at runtime we specify --labels=@test.

Note: If you have a changeset marked with a labelFilter that starts with @ and you run Liquibase without specifying the --labels attribute, the changeset will not be executed. If label filters (--labels=) are specified as @test at runtime as described in the example above, no changeset will be executed if there are not any labeled titled test.

Label filters can be specified using @, AND, OR, !, and () (parentheses that are used for grouping). For example:

  • --labelFilter="@test"
  • --labelFilter="!v.0.1"
  • --labelFilter="v.1.0 and v.1.1"
  • --labelFilter="v.1.0 or v.1.1"
  • --labelFilter="!v.1.0 and !v.1.1"

Using "," to separate labels works like an OR operation (a comma is an alias for OR). For example:

  • --labelFilter="v.1.0, v.1.1" is the same as --labelFilter="v.1.0 OR v.1.1"
  • --labelFilter="v.0.1, v.1.0 and v.1.1" is the same as --labelFilter="(v.0.1) OR (v.1.0 and v.1.1)"

You can run the --labelFilter attribute to determine which changesets in the changelog to evaluate based on its label. Learn more about the labelFilter logic at this blog post.

Note: If you want to control the filter logic in your changesets, use Contexts instead of labels.

  • In your changelog, you can specify only a simple list of labels to apply to the changeset. For example, labels="v.0.1, v.1.0".
  • At runtime, you can specify a complex expression with the labels that you want to execute. For example, --labelFilter="!v.0.1" or --labelFilter="v.1.0 or (v.1.1 and v.1.2)".

Note: Prior to version 4.16.0, the CLI argument was --labels rather than --labelFilter. In 4.16.0 and beyond, --labels is a supported alias for --labelFilter.


It is best practice to enumerate your changesets or describe what a changeset is used for. An example of labels indicating the version or a specific feature can be "1.0" or "shopping_cart". In this case, labels will allow you to run changes with:

  • --labelFilter=1.0 to deploy the 1.0 changesets or --labelFilter=shopping_cart to deploy the changesets related to the shopping cart.
  • --labelFilter="1.0 or (1.1 and shopping_cart)" to deploy the 1.0 changesets and only the 1.1 features related to the shopping cart.
  • --labelFilter="1.0 or (1.1 and !shopping_cart)" to deploy the 1.0 changesets and the 1.1 features that are not related to the shopping cart.

You can see an example of running the update command with complex labelFilter statements:

liquibase --output-file=update.txt update --changelog-file=changelog.xml --labelFilter="1.0 or (1.1 and !shopping_cart)"

If a changeset doesn't have a label, it will always run. If you make a deployment without specifying any labels in the label filter, all changesets will run.

Example: If you run the liquibase update --labelFilter=1.0 command, it will deploy all changesets with the label 1.0 and all changesets without any label. If you run liquibase update, it will deploy all changesets, whether they have labels or not.

include and includeAll labels

You can specify the labels attribute in <include> or <includeAll> tags. If specified, the given label is added to all changesets in the included file(s).