---
id: platform/migrate-from-render
title: Migrate from Render
description: Plan a Render-to-Bex migration, validate render.yaml, transfer configuration and data, and rehearse traffic cutover and recovery.
keywords: [bex, migrate, render, render.yaml, bex.yml, migration guide]
last_updated: 2026-09-23
---

Move a Render application to Bex by recreating its services, transferring its
configuration and data, and validating the result before changing traffic.
A compatible manifest does not migrate a database, disk, hostname, or account.

Bex remains in active development; its upstream project does not yet recommend
production workloads. Start with a rehearsal or non-production application.
Review [compatibility](./compatibility.md) before committing to a migration.
For a product-level evaluation first, see [Bex vs Render](/compare/render).
When you keep using the `bex` CLI after cutover, the
[CLI reference](./cli-reference.md) lists every command with its compatibility grade.

## 1. Inventory the application

Record services and process commands, runtime versions, repository/branch,
build paths, environment variables, secret files and groups, databases, queue
contents, persistent files, scheduled jobs, domains, and API integrations.
Identify any dependency on [unsupported Render features](./render-parity.md).

Choose a destination Bex workspace with the required capacity and platform
services configured. The [local operator quickstart](./quickstart.md) is an
exploration path; it does not by itself supply a complete hosted platform with
identity, builds, backups, and public routing.

## 2. Validate render.yaml

Keep the filename **`render.yaml`**. There is no need to rename it to `bex.yml`.
Bex supports the same broad `services:` and `databases:` structure, but validates
its own pinned schema and supported fields. Do not remove `runtime`,
`buildCommand`, or `startCommand` on the assumption they are ignored.

For example, this Bex Blueprint creates a Docker web service and database.
Replace the repository with your own Dockerfile-based application; it must
listen on `0.0.0.0:$PORT` and implement `/healthz`:

```yaml
services:
  - type: web
    name: shop
    runtime: docker
    repo: https://github.com/acme/shop
    branch: main
    plan: starter
    numInstances: 1
    healthCheckPath: /healthz
    autoDeployTrigger: off
    envVars:
      - key: DATABASE_URL
        fromDatabase:
          name: shop-db
          property: connectionString
databases:
  - name: shop-db
    plan: starter
    postgresMajorVersion: "16"
```

Choose a database version and plans appropriate to your source and available Bex
capacity; this is an illustrative configuration, not a sizing recommendation.
Keep production domains out of the rehearsal manifest.

Do not add `port` to a Blueprint service: the pinned schema rejects it. The
application should listen on Bex's injected `PORT` (default 3000). The direct
Kubernetes App resource's `spec.port` is a different configuration interface.

Check each service's type, runtime, port, health check, root directory, storage,
and scaling. Bex supports native builds, environment groups, generated values,
persistent disks, and pre-deploy commands within their documented constraints.
Unsupported fields fail validation; for example, CI-gated `checksPass` auto-deploy
is unavailable. Inspect every validation error instead of assuming an ignored
field will have Render behavior.

Use the authenticated dry-run/apply steps in the
[Blueprint guide](./app-resource.md) or the agent's `validate_bex_yml` and
`deploy` tools in [Connect an agent](./connect-an-agent.md). Validate first and
review the plan before applying. Provisioning remains asynchronous; inspect
all returned resources. Reapplying unchanged content is a no-op, and removing an
entry does not delete the old resource.

## 3. Transfer configuration and test the application

Populate [secrets](./secrets.md) before allowing real work. Replace source
connection strings with returned Bex connections or Blueprint references.
A generated secret is a new value: use an intentional transfer for signing keys
or credentials that must remain compatible during cutover.

Keep workers, schedulers, and external side effects disabled during rehearsal.
Starting both installations against the same queue can process work twice.
Use test accounts and a test hostname to verify builds, HTTP responses,
[private connections](./private-network.md), background work, and scheduled runs.

## 4. Rehearse the data transfer

### PostgreSQL

Create an empty destination database. Check major-version compatibility,
extensions, encoding, ownership, privileges, and storage capacity. Obtain
connections from each platform; use an allowed network path and preserve the
TLS settings returned by Bex. Do not weaken certificate verification to make a
migration command connect.

For a logical migration, the following transfers one database using PostgreSQL
client tools. Set `SOURCE_DATABASE_URL` and `TARGET_DATABASE_URL` securely to
your source and **empty destination**, respectively:

```bash
umask 077
pg_dump --format=custom --file=app.dump "$SOURCE_DATABASE_URL"
pg_restore --exit-on-error --no-owner --no-acl \
  --dbname="$TARGET_DATABASE_URL" app.dump
```

Stop if the dump fails; do not restore an incomplete archive. Choose a
`pg_dump` version that supports the source server and a destination version
compatible with its output. This example omits source ownership/ACLs; explicitly
recreate the roles and grants your application needs. It does not transfer all
cluster-global objects. Review [pg_dump](https://www.postgresql.org/docs/current/app-pgdump.html)
and [pg_restore](https://www.postgresql.org/docs/current/app-pgrestore.html)
for version and permission requirements.

A Bex physical export or disk snapshot is not interchangeable with this logical
archive. Verify row counts, important queries, sequences, permissions, and
application behavior after restoring. Measure the transfer duration to plan the
write-freeze window; large or continuously written databases need a separate,
rehearsed replication/cutover design. See [Postgres](./postgres.md) for Bex
recovery. Practice the dump/restore, grant recreation, and writer-handoff
sequence on disposable databases with the
[Postgres transfer rehearsal](./postgres-transfer.md).

### Queues, caches, and files

Decide whether each Key Value dataset is disposable cache, session state, or a
queue that must be preserved. Rebuilding a cache differs from draining work;
Bex does not expose a general tenant snapshot-import workflow for Key Value.
Choose and test a data-specific transfer strategy before cutover.

Copy persistent files through an application-appropriate export/import workflow.
Provision the destination [disk](./persistent-disks.md) and check mount paths,
permissions, and completeness. Creating a disk does not copy the Render disk.

## 5. Cut over traffic and writers

For the simple dump/restore approach, schedule a write freeze and repeat the
validated transfer after stopping **all** source writers: web requests, workers,
cron jobs, external integrations, and any administrative scripts. Prevent the
new installation from writing until that final restore is complete.

Add the production hostname in Bex and follow its returned
[ownership and routing instructions](./custom-domains.md). Review both apex and
www records if paired. Verify TLS and the application response; use the returned
routing target rather than constructing an `onbex.co` hostname. Account for DNS
caching during the transition.

Enable destination writers once, then monitor errors, latency, queue progress,
and data integrity. Keep source resources available for the agreed observation
period, with duplicate jobs and writes disabled.

## 6. Define recovery and retire the source

Before destination writes begin, recovery may be as simple as restoring source
routing and workers. After Bex accepts new writes, switching DNS back alone can
lose those changes. Decide how to reconcile or transfer them before reverting.
An [image rollback](./rollbacks.md) does not restore application data.

After validation and the observation period, retire source resources explicitly,
remove obsolete credentials, and check both platforms for remaining resources.
Enable Bex automatic deployments only after the desired Git workflow is verified.

## Pointing Render API tooling at Bex

Use the [Bex token exchange](./api.md), destination workspace,
and returned Bex resource IDs. Render API keys and resource IDs do not transfer.
Test every operation your scripts use, including pagination and errors; changing
the base URL is only one part of the migration. GraphQL and MCP also have their
own schemas and supported actions. See [Render parity](./render-parity.md).
