Skip to main content

Deploy to Mastra platform

mastra deploy is the single command for releasing a Mastra application to the Mastra platform.

One command builds your project and validates it before deploying, plus creates the platform project and environment on your first run, deploys, streams build logs, and prints your public URL once the deploy is serving traffic.

mastra deploy
note

This page covers the unified deploy flow. The earlier split commands, mastra server deploy and mastra studio deploy, still work but mastra deploy is the recommended path.

Before you begin
Direct link to Before you begin

You'll need a Mastra application and a Mastra platform account. If you're not authenticated, the CLI prompts you to log in on first use.

A local .env file is optional. Environment variables stored on the platform are used as-is at deploy time, and managed resources like hosted databases inject their own variables. Pass --env-file only when you want to layer local values on top.

Your first deploy
Direct link to Your first deploy

  1. From your project directory, run:

    mastra deploy

    On the first run the CLI prompts you to create the platform project (named after your package.json) and the production environment. Accept the prompts, or pass --yes to accept defaults without confirmation.

  2. The CLI runs a preflight check before every deploy. Storage that would fall back to a local file path (which doesn't survive on the platform's ephemeral filesystem) would normally block the deploy:

    file:./mastra.db will be used at runtime because TURSO_DATABASE_URL is not set

    Instead of erroring out, the CLI offers to fix it inline for you:

    Preflight needs TURSO_DATABASE_URL for the production environment. Create a managed turso database now and attach it? (Y/n)

    Accept the prompt, and provisioning takes a few seconds. The database's connection variables are injected into your deploys automatically, so you don't need to copy them into an .env file. If you decline the prompt or use a non-interactive shell (CI, --yes), the CLI falls back to printing the exact command for you to run.

    mastra env db create production --kind turso

    The environment slug (production above) matches the environment the CLI would have deployed to. The mastra env db create command requires an environment argument in non-interactive shells when the project has more than one environment.

    Preflight also catches database URLs that point at your local machine. A .env file with REDIS_URL=redis://localhost:6379 works during development, but the deployed server can't reach your laptop. The CLI therefore warns and offers the same managed provisioning. If you decline, the deploy continues with your value as-is; if you accept, the managed database's connection variables take precedence at deploy time while your local .env keeps working for development.

    note

    If preflight reports a hard-coded local path instead (Build contains a host-local storage URL), it can't offer the inline fix. Guard the path with an environment variable first so the file is only used during local development:

    src/mastra/index.ts
    new LibSQLStore({
    id: 'mastra-storage',
    // Uses the hosted database when deployed, a local file during development
    url: process.env.TURSO_DATABASE_URL ?? 'file:./mastra.db',
    authToken: process.env.TURSO_AUTH_TOKEN,
    })

    If the build statically finds backgroundTasks.enabled: true, the deploy artifact includes a worker manifest. Mastra Cloud automatically provisions or updates a dedicated worker service from the same artifact. No separate toggle or add-on is required.

    Removing backgroundTasks or setting enabled: false in a later deploy removes the manifest and spins down the existing worker service. Values that can't be determined statically are omitted from the manifest display, but the worker process still reads the complete configuration from your bundled code.

  3. Run mastra deploy again. Preflight passes, the build uploads, and the CLI streams build logs until the deploy is live. Expect the full build and deploy to take between 30 seconds and a few minutes. The success message prints only when the new version is serving traffic.

  4. Verify your deployment at the URL printed by the CLI. Append /api/agents to confirm it returns a JSON list of your agents.

    warning

    Set up authentication before exposing your endpoints publicly.

Replacing the running server process during each deploy can interrupt agent turns that are still streaming when the new version goes live because Mastra Platform doesn't currently let you configure or rely on guaranteed extra time before termination. Don't rely on a raised server.drainTimeout for turns that may outlast the default drain window. Use durable agents with persistent storage and cache when turns must survive a deploy, or handle an interrupted stream in the client. The available strategies are documented in graceful shutdown and rolling deploys.

The first deploy writes a .mastra-project.json file linking your directory to the platform project. Commit it so later deploys, CI runs, and mastra env commands target the same project without extra flags.

Deploy to another environment
Direct link to Deploy to another environment

mastra deploy targets the production environment by default. Pass --env to target a different one. If the environment doesn't exist yet, the CLI offers to create it:

mastra deploy --env staging

Each environment gets a separate URL and environment variables. It can also have its own hosted database.

See Environments for the full model.

Choose a region
Direct link to Choose a region

When a deploy creates an environment interactively, select the United States or Europe from the region prompt. To skip the prompt, pass --region with the us or eu shorthand:

mastra deploy --env production --region eu

The region is fixed when the environment is created. Databases attached to an environment are placed near that environment's region automatically, and observability data is routed to the ingest region that matches the environment's residency zone. See Regions for the full list of supported regions and database placement, along with observability co-location.

Preflight checks
Direct link to Preflight checks

Preflight validates the built output before the deploy uploads and only flags issues in your own code:

  • Local storage paths: A hard block. File-backed storage (for example file:./mastra.db) is lost on every deploy. Preflight passes when the path is guarded by an environment variable that's set locally or stored on the platform, including values provided by a managed database:

    src/mastra/storage.ts
    import { LibSQLStore } from '@mastra/libsql'

    export const storage = new LibSQLStore({
    id: 'mastra-storage',
    // Uses the hosted database when deployed, a local file during development
    url: process.env.TURSO_DATABASE_URL ?? 'file:./mastra.db',
    authToken: process.env.TURSO_AUTH_TOKEN,
    })
  • Missing environment variables: A warning for variables your code reads but no source provides. Variables referenced only by library code are excluded.

The recommended response to a preflight block is to fix the cause, usually by attaching a hosted database or storing the variable on the platform. --skip-preflight exists as an escape hatch but skips the checks that prevent broken deploys.

Run the checks without deploying:

mastra lint --preflight

mastra lint only sees your local env files. Variables stored on the platform or injected by managed databases aren't visible to it, so a deploy can pass preflight where lint still reports an error.

Environment variables
Direct link to Environment variables

Deploys resolve environment variables from three sources:

  • Managed variables: Injected by platform resources like hosted databases (for example TURSO_DATABASE_URL). The platform defines these, and you can't edit them.
  • Stored variables: Saved on the project or environment through the dashboard. Used as-is on every deploy with no local file needed.
  • Local env files: Deployments layer an explicit --env-file or the ambient .env and .env.local files on top.
mastra deploy --env staging --env-file .env.staging

To change variables on a running service without a redeploy, update them in the dashboard and run mastra env restart.

Private npm packages
Direct link to Private npm packages

Projects that depend on packages from a private registry install them during the deploy using the standard NPM_TOKEN contract.

  1. Store a read-only registry token as NPM_TOKEN on the project or environment through the dashboard.

  2. Commit a token-free .npmrc that points your scope at the registry and reads the token from the environment:

    .npmrc
    @your-org:registry=https://npm.pkg.github.com
    //npm.pkg.github.com/:_authToken=${NPM_TOKEN}

    Keep the ${NPM_TOKEN} reference literal. The package manager resolves it at install time, so the token itself is never written to your repository.

  3. Deploy as usual:

    mastra deploy

In a monorepo, a .npmrc in your project directory takes precedence over one at the repository root.

NPM_TOKEN is available during dependency installation. Mastra redacts its value from the Mastra source-build logs that it streams. The generated Dockerfile receives it as a build argument, so the runtime image stays free of the token. NPM_TOKEN is also injected into the running service as a regular environment variable, so treat it as a secret your application can read.

Projects without a private-registry .npmrc need no changes. When your .npmrc references ${NPM_TOKEN}, set the variable or the dependency install fails.

Project resolution
Direct link to Project resolution

Every deploy resolves its target project in this order:

  1. The MASTRA_PROJECT_ID environment variable
  2. The --project <name|slug|id> flag
  3. The .mastra-project.json file in the current directory

In CI, set MASTRA_PROJECT_ID and MASTRA_API_TOKEN and pass --yes:

mastra deploy --env production --yes

Migrating from server and studio deploys
Direct link to Migrating from server and studio deploys

mastra server deploy and mastra studio deploy are deprecated. They'll be removed in the next major version. Once removed, both commands will fail and legacy-pipeline projects can't deploy a new build until they migrate.

Existing deployed services keep running. This only affects your ability to publish new deploys.

Who this affects
Direct link to Who this affects

You are on the legacy pipeline if any of these are true:

  • Your last deploy went out with mastra server deploy or mastra studio deploy and the deploy log printed a Deprecated banner.
  • Your project's most recent successful deploy used @mastra/core older than 1.44.
  • Your organization hasn't been opted in to environment deploys.

The deploy log is the source of truth: the legacy pipeline prints a deprecation banner on every deploy.

Migrate
Direct link to Migrate

  1. Upgrade @mastra/core in your project. The environment pipeline calls setStudio on the built artifact, which requires @mastra/core >= 1.44.

    npm install @mastra/core@latest

    If you are jumping several minor versions, paste the following into a coding agent (Claude Code, Cursor, etc.) to catch breaking changes in APIs you actually use:

    Check whether this project is ready for the Mastra Platform environment pipeline.

    1. Find the installed version of `@mastra/core` (check package.json and the
    lockfile for the version that actually resolved, rather than only the range).
    2. If it's >= 1.44.0, tell me I'm good. No further action is needed.
    3. If it's < 1.44.0:
    a. Fetch the `@mastra/core` changelog from
    https://github.com/mastra-ai/mastra/blob/main/packages/core/CHANGELOG.md
    and read every entry between my installed version and the latest release.
    b. Scan my project (agents, workflows, tools, memory, storage, deployers,
    telemetry, anywhere `@mastra/core`, `@mastra/*`, or `mastra` is imported)
    and list every Mastra API surface I actually use.
    c. For each used API, cross-reference the changelog and produce a table of:
    API I use → breaking change → severity (breaks build / breaks runtime /
    behavior change / none).
    d. For each "breaks build" or "breaks runtime" row, implement the fix in my
    codebase. For "behavior change" rows, leave a comment at the call site
    explaining what changed so I can decide.
    e. Bump `@mastra/core` (and any `@mastra/*` peers) to the latest matching
    versions, then run typecheck and tests. Report anything still failing.
    4. Search my scripts, package.json, Dockerfiles, and CI config for
    `mastra server deploy` and `mastra studio deploy`. Replace each
    occurrence with `mastra deploy`. This is the unified command required
    by the environment pipeline.

    don't restructure my CI, provision new infra, or change my environment
    variable values. Change only the Mastra usage in my code and the deploy command
    itself.
  2. Replace the split command in your scripts and CI with the unified command:

    - mastra server deploy
    - mastra studio deploy
    + mastra deploy

    mastra deploy builds once and deploys both the server and the Studio UI shell for the target environment. It's supported by every recent mastra CLI; otherwise, upgrade with npm install -g mastra@latest.

  3. Deploy once. Your project is auto-adopted onto the environment pipeline and the production environment is created on first deploy. See Environments for the full model.

  4. Move any project-level environment variables to the environment that needs them, in the dashboard under Environments → <env> → Variables. See Environment variables.

FAQ
Direct link to FAQ

My deploy fails with MASTRA_CORE_TOO_OLD. The environment pipeline requires @mastra/core >= 1.44. Upgrade @mastra/core and redeploy.

My organization isn't opted in yet. Contact support. Opt-in will be automatic before the next major version.

Can I roll back? Yes. Environments retain deploy history and you can redeploy any prior successful artifact from the dashboard.