MIGRATION

Migrate to Lampion

§ 01 — OVERVIEW

Export, create, restore, verify, switch

A migration to Lampion always follows the same pattern. Most migrations take less than 10 minutes for a database under 5 GB.

EXPORT
pg_dump from the source provider.
CREATE
Create a Lampion project (console or API).
RESTORE
pg_restore into Lampion.
SWITCH
Switch the connection string.
bashsetup
# PostgreSQL client tools — version ≥ 17 required
$ psql --version
psql (PostgreSQL) 17.2
# Debian / Ubuntu
$ apt install postgresql-client-17
# macOS
$ brew install postgresql@17

These tools (pg_dump, pg_restore, psql) must be version ≥ 17 to be compatible with Lampion’s PostgreSQL 17.

§ 02 — EXPORT

Dump from the source

Grab a full dump from your current provider. The custom format (-Fc) is compressed, supports parallel restore, and allows filtering at restore time.

--format=custom
Compressed, parallel restore, filterable at restore time.
--no-owner
Ignores the source ownership roles.
--no-privileges
Ignores GRANTs — avoids role "xxx" does not exist errors at restore time, because Lampion uses its own cloud_admin role.
bashpg_dump — custom format
$ pg_dump "postgresql://user:[email protected]:5432/mydb" \
  --format=custom \
  --no-owner \
  --no-privileges \
  --file=mydb.dump
-- Dump complete: mydb.dump (124 MB)
§ 03 — CREATE THE PROJECT

One Lampion project, one connection string

Create a project via the console or the API. You get a ready-to-use connection string immediately.

01
Create an account
02
Click New Project
03
Choose a name and a region
04
Copy the connection string
REST APIWeb console
$ curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"name":"my-app","region":"fr-par-1"}' \
  api.lampion.cloud/v1/projects
{"connection_string":"...",
 "pg_password":"..."}
§ 04 — RESTORE

pg_restore into Lampion

Use the Lampion connection string as the target. The --jobs flag parallelizes the restore and speeds up the process for large databases.

--jobs=4
Parallelizes the restore; clearly faster on large databases.
Databases > 10 GB
Temporarily resize the compute to 4-8 CU via the console before the restore, then scale back down to 0.25 CU. You save on restore time and cost.
bashpg_restore — into Lampion
$ pg_restore \
  --dbname="postgresql://cloud_admin:[email protected]:5432/ep-abc.postgres?sslmode=require" \
  --no-owner --no-privileges --jobs=4 --verbose \
  mydb.dump
pg_restore: creating TABLE "public.users"
pg_restore: processing data for table "public.users"
pg_restore: creating INDEX "users_email_key"
-- Restore completed in 47 seconds
§ 05 — VERIFY

Count tables, indexes, rows

Compare the number of tables, indexes and row counts for each critical table between the source and Lampion.

\dt · \di
Compare the number of tables and indexes.
n_live_tup
Compare row counts table by table.
ANALYZE
pg_restore does not run ANALYZE automatically: run VACUUM ANALYZE so the planner has fresh statistics on your migrated tables.
bashpsql — consistency checks
# Number of tables
$ psql "$LAMPION_URL" -c "\dt"
# Row count per table
$ psql "$LAMPION_URL" -c "
  SELECT schemaname, relname, n_live_tup
  FROM pg_stat_user_tables ORDER BY n_live_tup DESC;"
# Existing indexes
$ psql "$LAMPION_URL" -c "\di"
# Compare against the source
$ psql "$SOURCE_URL" -c "SELECT ... FROM pg_stat_user_tables;"
§ 06 — SWITCH

Switch traffic, minimal downtime

Update your applications’ DATABASE_URL. The connection string changes, nothing else. To minimize downtime, set the source to read-only during the switch.

Recommended procedureDATABASE_URL
01Full migration a first time (no cutover).
02Application tests against Lampion in parallel.
03Maintenance window: set the source to read-only.
04Incremental dump of the latest writes.
05Restore into Lampion.
06Update DATABASE_URL and redeploy.
07Keep the source on standby for 24-48h for an immediate rollback if needed.
§ 07 — PROVIDER GUIDES

Neon, Supabase, RDS, Heroku, Cloud SQL, self-hosted

Specifics per source provider. The logic stays the same everywhere: export, restore, switch.

Neon— Similar architecture, direct migration

Neon uses the same architecture (pageserver/safekeeper). The migration is direct.

# 1. Grab the Neon connection string (Dashboard → Connection Details)
$ pg_dump "postgresql://user:[email protected]/neondb?sslmode=require" \
    -Fc --no-owner --no-privileges -f neon.dump
# 2. Restore into Lampion
$ pg_restore -d "$LAMPION_URL" --no-owner --no-privileges -j 4 neon.dump
Supabase— Watch out for system schemas

Supabase adds system schemas (auth, storage, realtime). Filter on public only, unless you want to migrate everything.

# Grab the DB password (Settings → Database)
$ pg_dump "postgresql://postgres:[PASSWORD]@db.[REF].supabase.co:5432/postgres" \
    --schema=public -Fc --no-owner --no-privileges -f supabase.dump
$ pg_restore -d "$LAMPION_URL" --no-owner --no-privileges -j 4 supabase.dump
AWS RDS / Aurora PostgreSQL— Security group and transfer costs

Make sure your IP is in the RDS security group. For large instances, run the dump from an EC2 instance in the same VPC to avoid outbound transfer costs.

# From your machine (or an EC2 instance in the same VPC)
$ pg_dump "postgresql://admin:[email protected]:5432/myapp?sslmode=require" \
    -Fc --no-owner --no-privileges -f rds.dump
$ pg_restore -d "$LAMPION_URL" --no-owner --no-privileges -j 4 rds.dump
Heroku Postgres— Via the Heroku CLI

The Heroku CLI provides pg:backups to generate a downloadable compressed dump.

# 1. Capture a backup
$ heroku pg:backups:capture -a my-app
# 2. Download the dump
$ heroku pg:backups:download -a my-app
-- latest.dump (89 MB)
# 3. Restore into Lampion
$ pg_restore -d "$LAMPION_URL" --no-owner --no-privileges -j 4 latest.dump
GCP Cloud SQL— Public IP or Auth Proxy

Temporarily enable the public IP, or use the Cloud SQL Auth Proxy to connect locally.

# With Cloud SQL Auth Proxy
$ cloud-sql-proxy --port 5433 my-project:europe-west1:my-instance &
$ pg_dump "postgresql://postgres:[email protected]:5433/myapp" \
    -Fc --no-owner --no-privileges -f cloudsql.dump
$ pg_restore -d "$LAMPION_URL" --no-owner --no-privileges -j 4 cloudsql.dump
Self-hosted PostgreSQL— Bare metal, VM, Docker, Kubernetes

If you host your own PostgreSQL, run pg_dump directly on the host or over SSH. Advantage: no bandwidth limit imposed by a provider.

# On the source server
$ sudo -u postgres pg_dump myapp -Fc --no-owner --no-privileges -f /tmp/myapp.dump
# Transfer locally
$ scp [email protected]:/tmp/myapp.dump .
# Restore into Lampion
$ pg_restore -d "$LAMPION_URL" --no-owner --no-privileges -j 4 myapp.dump
§ 08 — COMMON GOTCHAS

Six frequent errors, six fixes

The most frequent issues and how to fix them.

EXTENSIONSMissing extension at restore time

If your source uses pgvector, postgis or others, install them on Lampion before the restore via the console (Settings → Extensions) or the API.

ROLESRole "xxx" does not exist

Always use --no-owner --no-privileges on both dump AND restore. If you need specific application roles, create them after the restore via the Roles section of the console or the API.

SEQUENCESOut-of-sync sequences

If you dumped and then wrote to the source before the cutover, sequences may be behind. Resync them after the switch:

SELECT setval(pg_get_serial_sequence('users', 'id'),
       (SELECT MAX(id) FROM users));
PERFORMANCEDatabases > 50 GB

For very large databases: (1) resize the Lampion compute to 8 CU before the restore, (2) use --jobs=8, (3) dump by schema or by table if possible so you can resume after a failure, (4) open a support ticket before the migration to get hands-on help.

TLSSSL connection required

Lampion requires TLS 1.3 on all connections. Always append ?sslmode=require to the connection string if your client does not do it automatically.

ENCODINGEncoding and collation

Lampion uses UTF8 and the en_US.utf8 collation by default. If your source uses a different collation, create the database manually with the right collation before the restore.

Migrate your database,
with no lock-in.

Create an account First pg_restore in a few minutes.