Migrate to Snowflake Postgres
Why Migrate?
Snowflake Postgres is fully managed, real Postgres. Your schemas, queries, functions, and extensions come along without rewrites, and you hand off the operational work.
Security covers the things enterprise reviews ask about: Private Link, VPC peering on AWS, customer-managed encryption keys, and Snowflake's access control.
High availability is a setting. Turn it on and you get a standby in a separate availability zone with automatic failover.
Backups (with a 10-day point-in-time recovery window), minor version upgrades, and monitoring are handled for you.
Once you're on the platform, Cortex AI, Streamlit, and the rest of Snowflake can work with your Postgres data through pg_lake and data mirroring.
Step 1: Assess Your Current Deployment
Before you move anything, take inventory.
Postgres Version and Extensions
SELECT version(); SELECT extname, extversion FROM pg_extension ORDER BY extname;
Snowflake Postgres instances run Postgres 16, 17, or 18. If you're coming from an older major version, plan on the migration doubling as your major version upgrade, and test accordingly. Check every extension in that list against the supported extensions in the Snowflake Postgres docs. An unsupported extension is the thing most likely to surprise you on cutover day.
Database Size and Storage
SELECT pg_size_pretty(pg_database_size(current_database())) AS db_size; SELECT schemaname, tablename, pg_size_pretty(pg_total_relation_size(schemaname || '.' || tablename)) AS total_size FROM pg_tables WHERE schemaname NOT IN ('pg_catalog', 'information_schema') ORDER BY pg_total_relation_size(schemaname || '.' || tablename) DESC LIMIT 20;
Total size tells you how long a dump and restore will take. The top 20 list tells you which tables will dominate that time.
Application Connections
Write down everything that connects to the database:
- Connection strings and hosts
- ORMs and database drivers
- Connection poolers (PgBouncer, pgpool)
- Scheduled jobs and cron tasks
- Monitoring and backup agents
The cron job nobody remembers is always the one that breaks.
Custom Configurations
Export any settings you've changed from the defaults:
SELECT name, setting, source FROM pg_settings WHERE source NOT IN ('default', 'override') ORDER BY name;
Many of these can be set on the new instance with POSTGRES_SETTINGS. Some won't apply in a managed service, and that's fine.
Step 2: Provision Snowflake Postgres
Create your target instance in Snowsight or with CREATE POSTGRES INSTANCE.
Cloud Region
Pick the cloud provider (AWS or Azure) and region closest to your application servers. Latency between the app and the database matters more than almost anything else here.
Instance Family and Size
Use your assessment to pick a size:
- Match or exceed your current CPU and memory.
- Standard instances fit most workloads. Memory-optimized (HIGHMEM) instances are for big working sets and large indexes. Burstable instances are fine for dev, but they top out at 100 GB of storage and don't support high availability or pg_lake.
- Start with a comparable size. You can resize later with
ALTER POSTGRES INSTANCE, which needs a brief reconnect, so make sure your app retries connections.
Networking
New instances don't accept any connections until you set up network access:
- Network policies with Postgres ingress rules to allow specific IP ranges
- Private Link for private connectivity from your cloud network (Business Critical edition and above)
- VPC peering for private connectivity to a VPC you own on AWS
Authentication
Instance creation gives you credentials for the snowflake_admin and application roles. From there, create users and roles with standard Postgres CREATE ROLE and GRANT to match your current access patterns.
Step 3: Migrate Your Data
Logical Backup with pg_dump / pg_restore
For most databases, start here. It's simple and it works:
# Export from source pg_dump -h <source-host> -U <source-user> -d <source-db> \ --format=custom --compress=9 \ -f backup.dump # Import to Snowflake Postgres pg_restore -h <snowflake-host> -U <snowflake-user> -d <target-db> \ --no-owner --no-privileges \ backup.dump
Use the newest pg_dump and pg_restore you can, at least as new as the target server version. Your application is down (or read-only) for the duration, so time a test run first. If that window is too long, use logical replication instead. The logical replication quickstart walks through it.
Large Tables with COPY
For very large tables, COPY can be faster than pg_dump:
# Export psql -h <source-host> -U <source-user> -d <source-db> \ -c "\COPY large_table TO 'large_table.csv' WITH CSV HEADER" # Import psql -h <snowflake-host> -U <snowflake-user> -d <target-db> \ -c "\COPY large_table FROM 'large_table.csv' WITH CSV HEADER"
Create the table first (a pg_dump --schema-only restore does that), load the data, and then build indexes. Loading into a table with indexes already in place is a lot slower.
Validate Data Integrity
After the load, check that everything made it:
-- Compare row counts SELECT 'customers' AS table_name, COUNT(*) AS row_count FROM customers UNION ALL SELECT 'orders', COUNT(*) FROM orders UNION ALL SELECT 'products', COUNT(*) FROM products; -- Verify constraints SELECT conname, contype, conrelid::regclass FROM pg_constraint WHERE connamespace = 'public'::regnamespace; -- Check indexes SELECT indexname, tablename, indexdef FROM pg_indexes WHERE schemaname = 'public';
Run the same queries on the source and compare. Row counts catch missing data, and the constraint and index lists catch anything that failed quietly during restore. Run ANALYZE afterward so the planner has fresh statistics before real traffic shows up.
Step 4: Update Application Connections
Update Connection Strings
Swap the source host for your Snowflake Postgres host. Everything else stays standard Postgres: port 5432, your database name, and SSL.
# Before postgresql://user:pass@old-host.example.com:5432/mydb?sslmode=require # After postgresql://user:pass@<snowflake-instance-host>:5432/mydb?sslmode=require
Test with Your ORM
Run your ORM migrations and test suite against the new instance:
# Django python manage.py migrate --run-syncdb python manage.py test # Rails bundle exec rails db:migrate bundle exec rails test # Node.js (Prisma) npx prisma migrate deploy npm test
Verify Queries and Transactions
- Run your full test suite against the new instance.
- Check that prepared statements, advisory locks, and LISTEN/NOTIFY behave the way your app expects, especially if you're going through a connection pooler.
- If your app depends on a specific transaction isolation level, test that explicitly.
Step 5: Enable Snowflake Integration
Once you're running on Snowflake Postgres, you can start using the rest of the platform.
pg_lake
pg_lake lets Postgres write Iceberg tables that Snowflake can query. Enable the extension (it needs a STANDARD or HIGHMEM instance):
CREATE EXTENSION IF NOT EXISTS pg_lake CASCADE;
Then create Iceberg tables in Postgres with USING iceberg, and in Snowflake create a catalog integration with CATALOG_SOURCE = SNOWFLAKE_POSTGRES to read them. The pg_lake guide covers the full setup, including incremental sync with pg_incremental. If you'd rather have Snowflake keep copies of your regular Postgres tables in sync, look at data mirroring.
Data Pipelines
Once your data is in Snowflake, you can:
- Join Postgres data with data from other Snowflake sources
- Build ELT pipelines with Snowflake Tasks and Dynamic Tables
- Share data across your organization with Snowflake data sharing
Cortex AI
Cortex AI functions can summarize, classify, and translate your Postgres data once it's in Snowflake, without sending it to an outside service.
Streamlit Dashboards
Streamlit in Snowflake lets you build apps on your Postgres data in Python, with no frontend framework or separate hosting. See Build Apps on Snowflake Postgres with Streamlit.
Conclusion
That's the whole path: assess, provision, move the data, repoint the app, and then start using the platform features you didn't have before.
Related Resources
Step-by-step guide to migrating with minimal downtime using logical replication.
Overview of Snowflake Postgres features and capabilities.
Connection methods and client configuration for Snowflake Postgres.
This content is provided as is, and is not maintained on an ongoing basis. It may be out of date with current Snowflake instances