#Run batch migrations with the Management SDK
With batch migrations, you can apply multiple schema updates to an environment in a single operation.
This workflow uses the Client.getEnvironmentDiff method to get the diff, then submits all required schema changes at once. The migration either succeeds completely or fails entirely. If any step fails, no changes are applied. This reduces the risk of partial or inconsistent updates.
While supported and commonly used, submitting schema changes directly to production does not guarantee zero risk, especially when content already exists.
#How it works
Submitting batch changes is a two-step process:
-
Generate a diff: The Management SDK compares the source environment with a target environment using
getEnvironmentDiffand produces a list of schema operations required to make the target match the source. -
Submit the diff as a single batch: The generated diff is submitted using
applySchemaChanges, which applies all operations together in a single action.
The batch either succeeds completely or fails entirely. If any operation fails validation or execution, the entire batch is rolled back.
This workflow is commonly recommended for customers, who have two environments by default, such as those on the Pro plan. It works on any plan where you have at least two environments.
#Supported schema elements
The following schema elements are supported for batch changes submissions:
- Models
- Components
- Locales
- Simple fields
- Conditional visibility in fields
- Relational fields
- Enumerations
- Enumerable fields
- Initial values in enumeration fields
- Stages
- Union fields
- Apps
- Custom renderers and app fields
- Sidebar elements
- Remote fields
- Remote type definitions
- Remote sources
#Get the environment name
First, you need the environment name. For this query, you need to provide the project ID. You can find the Project ID in Project settings or in the project URL - https://app.hygraph.com/<projectId>/<environmentId>/.
- Navigate to the API Playground in your Hygraph project.
- In the API selector dropdown, select the Management API.
- Run the following query to get the environment names:
query MyQuery {viewer {project(id: "<your-project-id>") {environments {nameid}}}}
#Create a Management SDK client
Create a new file, for example submit-batch-changes.ts, and initialize the client with the following parameters:
import { Client } from '@hygraph/management-sdk';const client = new Client({authToken,endpoint,name, // optional});
| Option | Description |
|---|---|
authToken | Permanent auth token for your project. This can be retrieved from your Hygraph project in Project Settings > Permanent Auth Tokens > Token. Make sure the token has proper Management API permissions depending on what you plan to execute via the SDK. |
endpoint | Endpoint of the High Performance Content API that belongs to the environment that you will work with. The URL can be retrieved from your Hygraph project in Project Settings > Endpoints > High Performance Content API. |
name | Optional identifier used for logging and debugging. Every migration has a unique name within an environment. If unspecified, a name will be generated and will be part of the response of a successful migration. Subsequent migrations with the same name in the same environment will fail. |
For more information, read this document.
#Generate a diff
Use the getEnvironmentDiff method to generate a list of operations required to make the target environment match the specified source environment.
In this example:
- The client is initialized with the
masterenvironment's auth token and endpoint. This is the target environment where changes will be applied. - In the
getEnvironmentDiffmethod, we passdevelopmentas the parameter. This is the source environment where changes come from. - The result is a list of operations that will make
master(target) matchdevelopment(source).
const diff = await client.getEnvironmentDiff("development");
This returns operations to sync schema changes from development (source) to master (target).
#Required fields in diffs
When you make a field required in the source environment (development), existing content in the target environment (master) may contain null values for that field. To apply this change successfully, you must provide a migration value that replaces null for existing entries.
Migration value in field validations
When generating a diff, the Management SDK suggests updating the field to required, but it does not automatically include a migration value. If you apply the diff without adding one, the operation will fail.
Before applying the diff, you must manually add a migrationValue to the corresponding change.
For boolean fields, use true or false as the migration value instead of a string.
{"changes": [{"createSimpleField": {"apiId": "newField","parentApiId": "Post","type": "STRING","displayName": "NewField","description": null,"initialValue": null,"tableRenderer": "GCMS_SINGLE_LINE","formRenderer": "GCMS_SINGLE_LINE","tableExtension": null,"formExtension": null,"formConfig": {},"tableConfig": {},"isList": false,"isLocalized": false,"isRequired": true,"isUnique": false,"isHidden": false,"embeddableModels": [],"visibility": "READ_WRITE","isTitle": false,"position": 3,"validations": null,"embedsEnabled": null,"migrationValue": "value"}}]}
The provided migrationValue replaces existing null values when batch changes are applied.
#Apply schema changes
Use the following method to schedule the generated diff for the target environment:
client.applySchemaChanges(diff);
This schedules all operations from the diff.
#Dry run a migration
You can dry run your migration to preview what changes would be applied.
const changes = client.dryRun();console.log(changes);
Inspect the changes array and validate the list of operations that will be applied to the target environment.
#Run a migration in production
The run() method executes the applied schema changes, making the target environment (master) match the source environment (development).
const result = await client.run(true);if (result.errors) {console.log(result.errors);} else {console.log(result.name);}
#Full example
Here's a complete workflow showing source/target relationships. All schema changes from development (source) are applied to master (target), making master identical to development.
import { Client } from '@hygraph/management-sdk';async function syncEnvironments() {// Create client for TARGET environment (where changes will be applied)const targetClient = new Client({authToken: '',endpoint: '',name: 'sync-dev-to-master'});// Generate diff from SOURCE environment (where changes come from)const diff = await targetClient.getEnvironmentDiff("development");// Apply schema changes to TARGETtry {targetClient.applySchemaChanges(diff);const result = await targetClient.run(true);if (result.errors) {console.error('Migration failed with errors:', result.errors);return;}console.log('Successfully synced master to match development');console.log(`Migration name: ${result.name}`);console.log(`Finished at: ${result.finishedAt}`);} catch (error) {console.error('Migration failed:', error);}}syncEnvironments();
#How schema changes affect the target environment
Batch changes submitted with the Management SDK do not merge schemas. Instead, the target schema is replaced so that it exactly matches the source schema.
The SDK first generates a diff using getEnvironmentDiff, which lists the operations required to transform the target environment (master) into the source environment (development). When this diff is applied, schema elements are added, modified, or deleted as needed to achieve an exact match. Any schema elements present in master but missing or different in development, including models, fields, and sidebar elements, may be overwritten or deleted.
If a schema change exists only in master, the diff will include operations to remove or overwrite that change. To reduce the risk of unintended deletions or content loss:
- Freeze schema changes in
masterwhile working indevelopment - Keep schema changes mirrored across environments as you go
- Always review the generated diff before applying it
#Example scenarios
-
You clone
masterto createdevelopment, make schema changes indevelopment, and later make additional schema changes directly inmaster. When you generate and apply the diff, the SDK will suggest deleting the changes that exist only inmaster, because they are not present indevelopment. -
A field named Title Field exists in both environments, but you rename it to Title only in
master. The diff will suggest deleting Title and recreating Title Field, which aligns the schemas but results in content loss. -
You delete a field in
developmentand then create a new field with the same name. The diff may not detect this as a deletion and recreation, even though the underlying field identity has changed.