Skip to content

Migrating a Railway database to Layerbase

7 min readRailwayPostgreSQLDatabasesDeveloper Tools

Short version: Railway runs plain Postgres, MySQL, and Redis, so moving one is a data copy plus a connection-string change, and nothing about your queries or your client library changes. Paste a Railway account or team token into the wizard at layerbase.com/migrate/railway, pick the service from the list it returns, and it provisions a matching Layerbase database and copies the data across server-side; by hand it is pg_dump, mysqldump, or a Redis scan and restore. The one Railway-specific step is networking: Railway databases sit behind private networking, so you turn on the TCP proxy for the source long enough for the copy to reach it, then turn it back off. What does not come with you is the Railway platform wiring, meaning the injected DATABASE_URL and the private hostname, which you replace with the Layerbase string. Your app can stay on Railway; only the database moves.

Railway is a genuinely nice place to deploy an app: push, and your service, database, and networking come up together. The friction shows up on the database side as you grow, in two ways. The bill is usage-metered (you pay for resource-minutes, which is hard to forecast), and your data lives inside Railway's networking, which is convenient until you want it somewhere else.

If you want a database with flat per-instance pricing that isn't tied to where your app deploys, Layerbase Cloud hosts Postgres, MySQL, and Redis/Valkey as managed instances. Railway uses standard engines, so moving is a data copy and a connection-string change, and Layerbase can pull the database across from a single Railway token. You can keep deploying your app on Railway and just move the data; nothing forces an all-or-nothing switch.

Just want it done? Start at layerbase.com/migrate/railway. You sign in, the wizard opens with Railway already selected, lists your Postgres, MySQL, and Redis services so you pick one, and copies it into a matching Layerbase database: read-once, nothing written back to Railway. The rest of this post is that same migration explained step by step, plus the manual path.

Contents

What Actually Changes

Railway's databases are plain Postgres, MySQL, and Redis, so the engines themselves don't change. Two things do:

  • Pricing. Railway meters resource usage (per minute) on top of a plan minimum. Layerbase is flat per instance: predictable regardless of how busy the database is.
  • Networking. Railway databases default to private networking inside your project. To copy the data out (whether by the wizard or by hand), you enable Railway's TCP proxy / public networking on the database service so it's reachable, then turn it back off after. That's the one extra step compared to a database that's already public.

Everything else is standard. Your tables, keys, queries, and client libraries work the same; you change a connection string.

Set Up the Engine Locally with the Layerbase CLI

Stand up the matching engine locally first so you can copy into it and verify. The Layerbase CLI (formerly SpinDB) does it with one CLI, no Docker. (What is the Layerbase CLI?)

bash
npm i -g layerbase    # npm
pnpm add -g layerbase # pnpm

Create whichever engine your Railway database is (Postgres shown; use -e mysql or -e valkey for the others):

bash
lbase create railway-migration -e postgresql --start
lbase url railway-migration
text
postgresql://layerbase:<password>@127.0.0.1:5432/railway-migration

Copy Your Data

The managed wizard (one token)

On Layerbase Cloud, choose Migrating from another platform, pick Railway, and paste a Railway account or team token (Railway, then Account Settings, then Tokens). It lists your Postgres, MySQL, and Redis services; pick one and it provisions a matching Layerbase database and copies the data across server-side. The source must have public networking enabled so the copy can reach it (Railway, your database service, then Settings, enable the TCP proxy); you can disable it again afterward.

By hand

Enable the TCP proxy on the Railway database (above) to get an external connection string, then use the engine's standard dump tool into your local instance or a managed Layerbase database:

bash
# Postgres
pg_dump "$RAILWAY_DATABASE_URL" | psql "postgresql://layerbase:<pw>@<host>:5432/app?sslmode=require"

# MySQL
mysqldump --single-transaction --set-gtid-purged=OFF -h <host> -u <user> -p<pw> <db> | \
  mysql -h <layerbase-host> -P <port> -u layerbase -p<pw> --ssl <db>

# Redis (scan + DUMP/RESTORE; see the Upstash guide for the full loop)
redis-cli -u "$RAILWAY_REDIS_URL" --scan | ...

Repoint Your App

Railway injects connection variables (DATABASE_URL, REDIS_URL, and the per-engine PG*/MYSQL* vars). Point them at the Layerbase connection string from your Quick Connect panel:

bash
# Before (Railway-provided)
DATABASE_URL=postgresql://postgres:...@containers-us-west-x.railway.app:1234/railway

# After (Layerbase)
DATABASE_URL=postgresql://layerbase:...@your-host.cloud.layerbase.dev:5432/app?sslmode=require

Your client library doesn't change; these are standard engines on both sides. If your app still deploys on Railway, set the new DATABASE_URL in the Railway service's variables and remove the reference to the Railway-managed database.

What to Test

  • Run your suite against the local copy before cutting production over; standard engines behave identically.
  • Confirm SSL settings. Layerbase endpoints use TLS; make sure your connection string requests it (sslmode=require for Postgres, --ssl for MySQL, rediss:// for Redis).
  • Re-disable Railway public networking once the copy is verified, so the source isn't left exposed.
  • Check connection pooling if you were relying on Railway's defaults; set a sane pool size against the new endpoint.

The Managed Path: Layerbase Cloud

Run the manual copy once to see what moves; when you want it managed, Layerbase Cloud provisions Postgres, MySQL, or Valkey with TLS, backups, and flat pricing, and the Migrating from another platform wizard does the copy from your Railway token. Your app can keep living on Railway, or move; the database is now independent of where you deploy.

FAQ

Do I have to move my app off Railway as well?

No, and most people should not bother at first. Railway is good at deploying services; the thing you are changing is where the data lives. Set the new DATABASE_URL in the Railway service's variables, remove the reference to the Railway-managed database, and your deploy pipeline carries on exactly as before.

Which Railway services can the wizard copy?

Postgres, MySQL, and Redis. It lists the ones on your account from the token, you pick one, and it provisions the matching engine on the Layerbase side: a Railway Postgres lands on Layerbase Postgres, a Railway Redis lands on Layerbase Redis. Anything else running as a service in your project, an app container or a queue worker, is not a database and is not part of this.

Do I really have to expose the database publicly?

Temporarily, yes, and it is the only genuinely awkward step. Railway databases default to private networking inside the project, so neither the wizard nor a pg_dump on your laptop can reach one until you enable the TCP proxy on that service. Turn it on, run the copy, verify, then turn it off. Leaving it on afterward is the mistake to avoid, which is why it is on the test list above.

How much downtime does the cutover need?

The copy itself is read-only against a live Railway database, so nothing stops while it runs. The gap to plan for is between the copy finishing and your app picking up the new connection string, because writes in that window land on the old database. For a low-traffic app, deploy the variable change and move on. For anything busier, pause writes, run the copy, then flip.

Does the bill actually get more predictable?

That is the main reason people do this. Railway meters resource usage by the minute on top of a plan minimum, so a busy month and a quiet month cost different amounts and neither is easy to forecast. Layerbase charges per instance at a flat rate, so the database line on the bill stops depending on how much traffic your app saw.

Wrapping Up

Moving a Railway database off Railway is mechanical: the engines are standard, so it's a dump-and-restore (or one token through the wizard) plus a connection-string change. The only Railway-specific step is enabling public networking on the source long enough to copy it.

Manage your local instance with the Layerbase CLI:

bash
lbase stop railway-migration    # Stop the server
lbase start railway-migration   # Start it again
lbase url railway-migration     # Print the connection URL
lbase list                      # See all your instances

The Layerbase CLI handles 20+ database engines, so you can run Postgres, MySQL, and Valkey side by side while you verify each move. Layerbase Desktop wraps it in a GUI on macOS.