# Move from Render to Naijacloud

Source: https://naijacloud.com/guides/migrate-from-render

Your web service, Postgres database, environment variables and domain running on Naijacloud, with the old service kept as a rollback.

_60 min · Intermediate · Last verified 2026-10-07 · Stack: postgres, dns_

## What things are called here

| On Render | On Naijacloud |
| --- | --- |
| Web Service | Web service |
| Static Site | Static site |
| Cron Job | Cron job, in UTC, up to 1 hour per run |
| Render Postgres | Postgres database |
| Render Key Value | Cache (Redis or Valkey) |
| Docker image deploys | Web service from a Docker image |
| Background Worker | (none) No worker type. Run it as a web service that also listens on PORT, or as a cron job |
| render.yaml (Blueprint) | (none) No config file. Service settings in the dashboard or the CLI |
| Environment Group | (none) No shared groups. Set variables on each service |
| Persistent Disk | (none) No attached disks. Use object storage |
| Custom Domains | Domains, with the certificate issued for you |
| Regions | af-west · Port Harcourt, eu-west · Europe |

## Before you move: what Render has that we don't

- Point-in-time recovery for Postgres.
- Read replicas for Postgres.
- A SOC 2 report.
- Autoscaling.
- Background workers as their own service type.
- Persistent disks attached to a service.
- Regions outside Africa and Europe.

If your app depends on one of these, stay on Render for now.

## The cutover, in order

1. **Lower DNS TTL**: 48 hours before. Set the record to 60 seconds.
2. **Deploy here and add the domain**: Traffic still goes to Render.
3. **Certificate issued**: Wait for it before you touch DNS, where you can.
4. **Copy the data**: Dump, restore, compare the counts.
5. **Switch DNS**: Point the record at Naijacloud.
6. **Keep the old service 7 days**: Going back is one DNS change.

## Lower the DNS TTL, 48 hours before

At your DNS provider, set the TTL on your domain’s record to 60 seconds. Then wait at least as long as the old TTL, which is often 24 to 48 hours, so resolvers stop holding the old answer.

Nothing else changes yet. Your visitors are still on Render.

## Deploy here and add the domain

In the dashboard, create a project in the region closest to your users: af-west · Port Harcourt or eu-west · Europe. Add a **Database** first (**Postgres**, the same size class you use on Render) and copy its **Internal URL** from the **is ready.** screen.

Then add a **Web service** from the same GitHub repository and branch. Naijacloud detects the framework and fills in build and start commands; compare them with your Render service’s **Build Command** and **Start Command** and copy Render’s over where they differ. If you have a `render.yaml`, those two lines are in it.

For variables, open your Render service → **Environment** and copy the values. On the new service, open **Variables** → **Bulk edit** and paste them, one `KEY=value` per line, then **Save variables**. Set `DATABASE_URL` to the new database’s Internal URL, not Render’s. If you have the CLI and a `.env` file, `naijacloud env import .env --service <name>` does the same in one command.

```sh
$ npm install -g @naijacloud/cli
$ naijacloud login
$ naijacloud env import .env --service my-app
$ naijacloud redeploy my-app
```

Open the app on its naijacloud.app address. It runs against an empty database for now; step 4 fills it. Then open **Domains**, enter your domain in **Custom domain** and click **Add domain**. Add the records it lists that prove ownership and issue the certificate. Don’t change the record that routes traffic yet.

## Wait for the certificate

Where the **Domains** table lists ownership and HTTPS records, the certificate is issued while your traffic is still on Render. Wait until the domain shows **Verified · HTTPS ready**.

> **Warning: Never move DNS before the certificate is issued here**
>
> If the record points at us while we hold no certificate for the domain, every request fails TLS — a hard browser error, not a slow page — until issuance finishes.

If the table lists only one routing record (an **A** record, as it does for a root domain and in some regions), there’s nothing to publish ahead of time: the certificate is issued in the minutes after the record points here. Plan the switch in step 5 for a quiet hour.

## Copy the data

Use PostgreSQL 18 client tools (`pg_dump`, `pg_restore` and `psql` 18), which read Render’s older Postgres and write ours.

In Render, copy the **External Database URL** from the database’s **Info** page. Render accepts outside connections only from addresses on its access list, so add your IP there first. On Naijacloud, open the database’s **Overview**, add your IP under **External access** → **Specific IPs** and click **Save**, then switch the **Connection** card to **External · TLS** and copy the **Connection URL**.

```sh
$ export RENDER_DATABASE_URL="postgresql://…render.com/app"
$ export NAIJACLOUD_DATABASE_URL="postgresql://…naijacloud.app:5432/app?sslmode=require"
$ pg_dump --format=custom --no-owner --no-acl \
    "$RENDER_DATABASE_URL" -f app.dump
$ pg_restore --clean --if-exists --no-owner --no-acl \
    --dbname "$NAIJACLOUD_DATABASE_URL" app.dump
```

`--clean --if-exists` replaces the empty tables your app’s migrations created in step 2. `--no-owner --no-acl` stops the restore assigning objects to Render’s roles, which don’t exist here.

**How to know the restore is complete.** Run `analyze;` on both databases first — `n_live_tup` is only an estimate until you do. Then compare the table list, exact counts on your two or three largest tables, the sequence values, and the extension list. Matching row counts with a sequence still sitting at 1 means the next insert will collide.

```sql title="verify.sql · run on both, compare line for line"
analyze;
select relname, n_live_tup from pg_stat_user_tables order by relname;
select count(*) from orders;                    -- your largest table
select last_value from orders_id_seq;           -- sequences advanced
select extname from pg_extension order by 1;    -- extensions present
```

```sh
$ psql "$RENDER_DATABASE_URL" -f verify.sql
$ psql "$NAIJACLOUD_DATABASE_URL" -f verify.sql
```

Then test the app on its naijacloud.app address: sign in, save something, and open a page that reads from the database.

> **Warning: Check the restore before you switch DNS**
>
> Compare the output from both databases. If it differs, or pg_restore printed errors, fix it now. Once DNS moves, new writes go to the new database and the two copies drift apart. If Render is still taking writes, take a fresh dump just before step 5 and run the restore and the checks again.

## Switch DNS

At your DNS provider, change your domain’s routing record to the value shown in **Domains**, replacing Render’s. With a 60-second TTL, most visitors follow within a few minutes, and the domain reads **Verified · HTTPS ready** once its certificate is in place.

For a short time both platforms serve requests. Watch the logs on both until Render’s go quiet, and leave the domain attached on Render.

## Keep the old service for 7 days

Suspend the Render web service instead of deleting it, and keep the Render database. If something goes wrong, point the record back at Render and resume the service.

> **Warning: Don’t delete the old service yet**
>
> Deleting the Render service or database removes your way back. After 7 days, check that nothing still calls the old address, then delete them and raise the TTL back to what it was.

## Rollback: keep these for 7 days

- The Render web service, suspended, not deleted
- The Render database
- The app.dump file
- The 60-second TTL on your record

To go back: point the record at Render again and resume the service.

All guides: https://naijacloud.com/guides · Index for agents: https://naijacloud.com/llms.txt
