On this page
- What Transfers Without Changes
- What Needs an Alternative
- Pre-Migration Checklist
- Step 1: Export Environment Variables
- Step 2: Migrate Your Database
- Export from Render Postgres
- Set Up the New Database
- Restore Your Data
- Step 3: Handle Persistent Disks
- Step 4: Set Up Cron Jobs
- Step 5: Install Temps and Deploy
- Step 6: Cut Over DNS
- Rollback Plan
- Next Steps
Migrate from Render to Self-Hosted
Render and Temps share a similar deployment model — connect a Git repo, push to deploy, get a URL. The main differences are that Render manages the infrastructure for you while Temps runs on a VPS you control, and Temps replaces Render's add-ons (databases, disks, cron jobs) with self-hosted equivalents.
What Transfers Without Changes
| Feature | Render | Temps |
|---|---|---|
| Web services | Auto-deploy from Git | Same — auto-deploy from Git |
| Build command | Detected or manual | Same — detected or set in project settings |
| Start command | node server.js, gunicorn, etc. | Same — set in project settings |
| Environment variables | Dashboard or render.yaml | Temps dashboard or CLI |
| Health checks | /healthz path | Same — configurable health check path |
| HTTPS | Automatic | Same — Let's Encrypt, auto-renewed |
| Preview environments | Pull request previews | Same — every PR gets a URL |
What Needs an Alternative
| Render feature | Temps equivalent |
|---|---|
| Render Postgres | Temps managed Postgres or external (Neon, Supabase) |
| Render Redis | Temps managed Redis |
| Persistent Disks | Project volumes (VPS-mounted directories) |
| Render Cron Jobs | Temps Cron Jobs |
| Render Static Sites | Static site deployment |
| Render Private Services | Temps internal networking (services on the same server communicate over localhost) |
Pre-Migration Checklist
- SSH access to a VPS running Ubuntu 22.04+ (choosing a server)
- Domain name with DNS access (or use a Temps subdomain while testing)
- Render environment variables exported (see Step 1)
- Database backup exported if you are migrating data
Step 1: Export Environment Variables
In Render, go to your service → Environment → copy all key-value pairs. You can also use the Render CLI:
render env list --service YOUR_SERVICE_NAME
Note which variables are Render-specific and need to be changed:
| Render variable | Action |
|---|---|
DATABASE_URL | Replace with your new database URL after migration |
REDIS_URL | Replace with your new Redis URL after migration |
PORT | Remove — Temps sets this automatically |
RENDER_SERVICE_NAME | Remove — Render-specific |
RENDER_EXTERNAL_URL | Remove or replace with your Temps URL |
RENDER_INTERNAL_HOSTNAME | Remove — use localhost or Temps service names |
Step 2: Migrate Your Database
Export from Render Postgres
In Render, go to your database → Info → copy the External Connection String.
pg_dump "$RENDER_DATABASE_URL" \
--no-acl \
--no-owner \
-Fc \
-f render_backup.dump
Set Up the New Database
Create a managed Postgres service
- 1
In the Temps dashboard, go to Managed Services, then New Service, then PostgreSQL.
- 2
Give the service a name (e.g. my-app-db) and create it.
- 3
Temps creates a Postgres instance on your server accessible at localhost:16432.
Checkpoint: Open the service detail page and confirm the connection string is shown before restoring data into it.
Option A — Temps managed Postgres (same server):
- In the Temps dashboard, go to Managed Services → New Service → PostgreSQL
- Temps creates a Postgres instance on your server accessible at
localhost:16432 - The connection string is shown in the service detail page
Option B — External Postgres (Neon, Supabase, etc.): Create a database with your chosen provider and copy the connection string.
Restore Your Data
# Test on a copy first
pg_restore \
--clean \
--if-exists \
-d "$NEW_DATABASE_URL" \
render_backup.dump
# Verify row counts match
psql "$NEW_DATABASE_URL" -c "SELECT schemaname, tablename, n_live_tup FROM pg_stat_user_tables ORDER BY n_live_tup DESC;"
Step 3: Handle Persistent Disks
Add a project volume
- 1
Open your project and go to Settings, then Volumes.
- 2
Click Add Volume.
- 3
Set the Container path to match what you used in Render (e.g. /var/data).
- 4
Temps mounts a directory from your VPS at that path.
Checkpoint: Confirm the volume appears in the Volumes list with the expected container path, then migrate existing data from the Render disk with rsync or scp before cutting over.
Render persistent disks mount a directory that survives deployments. On Temps, use project volumes:
- Go to Project → Settings → Volumes
- Click Add Volume
- Set the Container path to match what you used in Render (e.g.
/var/data) - Temps mounts a directory from your VPS at that path
To migrate existing data from a Render disk, use rsync or scp via the Render shell before you cut over.
Step 4: Set Up Cron Jobs
Add a cron job
- 1
Open your project and go to Settings, then Cron Jobs.
- 2
Click Add Cron Job.
- 3
Set the schedule (e.g. 0 2 * * *) and the command (e.g. node scripts/cleanup.js).
- 4
Save the cron job. See the Cron Jobs guide for details.
Checkpoint: Run bunx @temps-sdk/cli environments crons list -p my-app -e production to confirm the cron job is registered.
Render cron jobs (schedule: in render.yaml) become Temps cron jobs:
# render.yaml (what you had)
services:
- type: cron
name: daily-cleanup
schedule: "0 2 * * *"
buildCommand: npm run build
startCommand: node scripts/cleanup.js
In Temps, go to Project → Settings → Cron Jobs → Add Cron Job and set the schedule and command. See the Cron Jobs guide for details.
Step 5: Install Temps and Deploy
Create a project and deploy
- 1
In the Temps dashboard, go to Projects, then New Project.
- 2
Connect your Git repository.
- 3
Add your environment variables, updating DATABASE_URL to your new database connection string.
- 4
Click Deploy. Your app gets a preview URL at https://your-project.yourdomain.com.
Checkpoint: Open the preview URL and test the app thoroughly before cutting over DNS.
Install Temps on your server:
curl -fsSL https://temps.sh/deploy.sh | bash
Then:
- Go to Projects → New Project in the Temps dashboard
- Connect your Git repository
- Add your environment variables (update
DATABASE_URLto your new database) - Click Deploy
Your app gets a preview URL at https://your-project.yourdomain.com. Test it thoroughly before cutting over DNS.
Step 6: Cut Over DNS
Add your custom domain
- 1
In your project, go to Settings, then Domains, and click Add Domain.
- 2
Enter your domain (e.g. app.yourdomain.com). Temps shows you the DNS records to add.
- 3
At your DNS provider, add an A record for app pointing to YOUR_SERVER_IP, and lower the TTL to 60 seconds before the cutover.
Checkpoint: Run dig +short app.yourdomain.com and confirm it returns your server's IP, then confirm the domain status shows active in Temps.
- 4
Keep your Render services running for 48 hours as a fallback in case you need to revert.
Once your app works on the Temps preview URL:
- In Project → Settings → Domains, click Add Domain
- Enter your domain (e.g.
app.yourdomain.com) - Temps shows you the DNS records to add
In your DNS provider:
| Type | Name | Value |
|---|---|---|
| A | app | YOUR_SERVER_IP |
Lower your TTL to 60 seconds before the cutover so you can revert quickly if needed.
Keep your Render services running for 48 hours as a fallback. DNS changes can take up to 48 hours to propagate everywhere, though most resolvers pick up changes within minutes.
Rollback Plan
If you encounter problems after cutting over:
- Update your DNS A record back to Render's IP
- Wait for propagation (fast if you lowered TTL)
- Your Render service is still running and receives traffic again