ZEKTOR.IO Docs

Migration Guide

How to migrate your existing PostgreSQL or Valkey database to Zektor.io — step-by-step instructions for common providers and tools.

Overview

Migrating your existing database to Zektor.io is straightforward using standard PostgreSQL and Valkey tools. This guide covers the most common migration scenarios.

Before You Migrate

Pre-migration checklist

  1. Check your PostgreSQL version — Zektor.io supports PostgreSQL v17 and v18. If you're on an older version, you may need to address compatibility.
  2. Review extensions — Check which extensions your database uses and verify they're supported on Zektor.io.
  3. Estimate storage needs — Choose a cluster tier with enough storage for your data. Storage auto-scales, but start with a tier that fits comfortably.
  4. Plan for downtime — Depending on your database size, migration may take minutes to hours. Plan a maintenance window if needed.
  5. Prepare connection strings — After migration, you'll need to update your application's connection strings.

Check your database size

SELECT pg_size_pretty(pg_database_size(current_database())) AS db_size;

List installed extensions

SELECT extname, extversion FROM pg_extension ORDER BY extname;

Migrating PostgreSQL

Using pg_dump and pg_restore

The most reliable migration method for PostgreSQL databases of any size.

Step 1: Export from your current database

# For databases under 1GB — plain SQL format
pg_dump -h <source-host> -U <source-user> -d <source-db> \
  --no-owner --no-privileges \
  -f backup.sql

# For larger databases — custom format with compression
pg_dump -h <source-host> -U <source-user> -d <source-db> \
  --no-owner --no-privileges \
  -Fc -f backup.dump

Flags explained:

  • --no-owner — Skips ownership commands (Zektor.io assigns its own user)
  • --no-privileges — Skips permission grants that may not apply
  • -Fc — Custom format, enables compression and parallel restore

Step 2: Create your Zektor.io instance

  1. Deploy a new PostgreSQL instance with a tier that has enough storage
  2. Note your connection credentials from the Settings tab

Step 3: Install extensions first

If your source database uses extensions, install them on Zektor.io before restoring data:

-- Connect to your Zektor.io instance
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- Add other extensions as needed

Step 4: Import into Zektor.io

# For plain SQL dumps
psql 'postgresql://<username>:<password>@<zektor-host>:5432/<database>?sslmode=require' \
  -f backup.sql

# For custom format dumps
pg_restore -h <zektor-host> -U <username> -d <database> \
  --no-owner --no-privileges \
  backup.dump

Step 5: Verify the migration

-- Check table counts
SELECT schemaname, tablename,
  (xpath('/row/cnt/text()',
    query_to_xml('SELECT count(*) AS cnt FROM ' || schemaname || '.' || tablename, false, true, ''))
  )[1]::text::int AS row_count
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY tablename;

-- Check database size
SELECT pg_size_pretty(pg_database_size(current_database()));

Step 6: Update your application

Replace your old connection string with the Zektor.io connection string from your instance Settings tab. See Connecting for client-specific instructions.

Using COPY for individual tables

For migrating specific tables or incremental data:

# Export a table to CSV
psql -h <source-host> -U <source-user> -d <source-db> \
  -c "\COPY my_table TO 'my_table.csv' WITH CSV HEADER"

# Import into Zektor.io
psql 'postgresql://<username>:<password>@<zektor-host>:5432/<database>?sslmode=require' \
  -c "\COPY my_table FROM 'my_table.csv' WITH CSV HEADER"

Migrating from Specific Providers

From Heroku Postgres

# 1. Get your Heroku database URL
heroku config:get DATABASE_URL -a your-app

# 2. Create a dump from Heroku
pg_dump <heroku-database-url> --no-owner --no-privileges -Fc -f heroku_backup.dump

# 3. Restore into Zektor.io
pg_restore -h <zektor-host> -U <username> -d <database> \
  --no-owner --no-privileges heroku_backup.dump

From Supabase

# 1. Find your Supabase connection string in Project Settings > Database
# 2. Dump from Supabase (exclude Supabase-specific schemas)
pg_dump <supabase-connection-string> \
  --no-owner --no-privileges \
  -N supabase_migrations -N _supabase -N supabase_functions \
  -Fc -f supabase_backup.dump

# 3. Restore into Zektor.io
pg_restore -h <zektor-host> -U <username> -d <database> \
  --no-owner --no-privileges supabase_backup.dump

From Neon

# 1. Get your Neon connection string from the Neon dashboard
# 2. Dump from Neon
pg_dump <neon-connection-string> \
  --no-owner --no-privileges \
  -Fc -f neon_backup.dump

# 3. Restore into Zektor.io
pg_restore -h <zektor-host> -U <username> -d <database> \
  --no-owner --no-privileges neon_backup.dump

From AWS RDS / Aurora

# 1. Dump from RDS (ensure your IP is in the security group)
pg_dump -h <rds-endpoint> -U <rds-user> -d <rds-database> \
  --no-owner --no-privileges \
  -Fc -f rds_backup.dump

# 2. Restore into Zektor.io
pg_restore -h <zektor-host> -U <username> -d <database> \
  --no-owner --no-privileges rds_backup.dump

Tip: For large RDS databases, consider running pg_dump from an EC2 instance in the same region as your RDS instance to speed up the export.

Migrating Valkey / Redis

Using redis-cli

# 1. Dump from your existing Redis/Valkey instance
redis-cli -h <source-host> -p <source-port> -a <source-password> --rdb dump.rdb

# 2. Convert RDB to Redis protocol format
# Use redis-rdb-tools or rdb-cli to convert
rdb --command protocol dump.rdb | \
  redis-cli -h <zektor-host> -p 6379 -a <password> --tls --pipe

Using RIOT (Redis Input/Output Tool)

For live migrations with minimal downtime:

# Install RIOT: https://github.com/redis/riot
riot replicate \
  redis://<source-password>@<source-host>:6379 \
  rediss://<password>@<zektor-host>:6379

Manual key migration

For small datasets or selective migration:

# Export keys from source
redis-cli -h <source-host> -a <source-password> --scan --pattern '*' | while read key; do
  redis-cli -h <source-host> -a <source-password> DUMP "$key" | \
  redis-cli -h <zektor-host> -a <password> --tls RESTORE "$key" 0
done

Post-Migration Steps

  1. Verify data integrity — Compare row counts, check critical tables, run application smoke tests
  2. Update connection strings — Point your applications to the new Zektor.io endpoints
  3. Set up backups — Configure backup schedules for your new instance
  4. Enable monitoring — Install pg_stat_statements and check your monitoring dashboard
  5. Test performance — Run your typical queries and compare response times
  6. Decommission the old database — Once you've verified everything works, shut down the source database

Troubleshooting

Extension not available

If pg_restore fails because of a missing extension, check the supported extensions list. You may need to remove the extension from your dump or find an alternative.

Permission errors

Use --no-owner --no-privileges flags with pg_dump and pg_restore to avoid permission-related failures.

Large object errors

If your database uses PostgreSQL large objects:

pg_dump ... --no-blobs -f backup_no_blobs.dump

Timeout during restore

For very large databases, increase client-side timeouts:

psql "postgresql://...?sslmode=require&statement_timeout=0" -f backup.sql

Next Steps

  • Connecting — Update your application connection strings
  • Backups — Set up automated backups
  • Monitoring — Monitor your migrated database

On this page