Understanding the Liquibase Changelog

All database changes are specified in the Liquibase changelog file. A change is contained in a changeset and changesets are added to the changelog in the order they need to be deployed.

Simply stated – a changelog contains an ordered list of changesets, and a changeset contains a change.

Developers specify database changes in one of four different changelog formats: SQL, XML, JSON, or YAML. You can even mix and match different types of changelogs if desired.

After creating a changelog, run liquibase update to deploy any undeployed changes to a target database.

  • Don’t worry, Liquibase keeps track of what’s deployed and what’s not deployed in the DATABASECHANGELOG table.
  • When you run the liquibase update command, it brings the target database up-to-date without any need to intervene.
  • When all of the changes have been deployed, subsequent calls to liquibase update return successfully without doing anything (since there’s nothing to do).

Changelog Components in Detail

changelog files

Developers store database changes in text-based files on their local development machines and apply them to their local databases. These changelog files are stored in source control to enable collaboration. The changelog can be used to update all the different database environments that a team uses — from local development databases, to test, staging, and production. Changelog files can be arbitrarily nested for better management.

See the changelog documentation for more information.


changeSets are the units of change that Liquibase tracks execution of. The author, id, and filename attributes uniquely identify each changeSet. When Liquibase runs, it queries the DATABASECHANGELOG table for the changeSets marked as executed and then executes all undeployed changeSets from the changelog file.

See the changeset documentation for more information.

Change Types

Each changeset contains one or more Change Types that describe a type of change or action you want to apply to the database. Liquibase supports both descriptive Change Types that generate SQL for supported databases and raw SQL. Generally, there should only be one Change Type per changeset to avoid failed auto-commit statements that can leave the database in an unexpected state.

See the Change Type documentation for a list of available Change Types.

Advanced Changelog Capabilities


Preconditions can be applied to either the changelog as a whole or to individual changesets. Preconditions control the execution of an update based on the state of the database and can halt the update, skip a changeset, mark a changeset as run, or show a warning.

See the Preconditions documentation for more information.


Contexts can be applied to changeSets to control whether they are run in different environments. For example, some changeSets can be tagged as “production” and others as “test”. If no context is specified, the changeSet will run regardless of the execution context. Contexts can be specified as logical expressions in the changeSet to more precisely control execution.

See Contexts documentation for more information.


Similar to contexts, labels can also be applied to changesets to control which changesets are executed. In contrast to contexts that can be complex expressions, labels are a simple list on each changeset. For labels though, complex expressions can be supplied at runtime. The combination of contexts and labels gives fine-grained control over which changesets are executed.

See Labels documentation for more information.

See the Understanding Context vs. Labels blog post for more details regarding their differences, similarities, and use cases.