What is pgLoader and Why Should You Care?

PostgreSQL Logo

Dimitri Fontaine built pgLoader because database migrations suck. If you've ever tried to move data from MySQL to PostgreSQL manually, you know what I'm talking about. The endless charset issues, the 0000-00-00 datetime values that PostgreSQL hates, the schema differences that make you want to cry.

Why pgLoader Actually Works (Unlike Most Migration Tools)

Uses PostgreSQL's COPY Protocol (Which is Actually Fast)
Instead of doing row-by-row INSERTs like an amateur, pgLoader uses PostgreSQL's native COPY command for bulk loading.

PostgreSQL COPY vs INSERT Performance Comparison

This leverages PostgreSQL's bulk loading capabilities and efficient data streaming protocols. We're talking about loading millions of rows without your terminal hanging for hours, unlike slower row-by-row INSERT methods.

Doesn't Die When Bad Data Shows Up
Here's the thing: your source database has shit data. MySQL lets you store 0000-00-00 dates and empty strings where they shouldn't be. Instead of failing completely, pgLoader saves the garbage to `.reject.dat` and `.reject.log` files so you can deal with it later.

Actually Converts Your Schema
pgLoader reads your MySQL/SQLite/Oracle schema and creates equivalent PostgreSQL tables automatically. It handles the type conversions, foreign keys, indexes - the stuff that would take you weeks to figure out manually. Check the MySQL type mapping documentation and PostgreSQL data types to see what it converts. It also handles character set conversions and collation mapping.

Continuous Migration That Doesn't Suck
You can run continuous migrations during development so you're not scrambling to figure out what broke when you finally migrate production. Test your migration script daily instead of praying it works on go-live day.

What Can This Thing Migrate?

pgLoader supports way more than just databases:

MySQL Logo

The current version is 3.6.9 (released October 24, 2022) and it's actively maintained. Not like those abandoned SourceForge projects from 2008. Check the release history and commit activity to see it's still being developed.

How Much Time Will This Actually Save?

Look, I've been through MySQL-to-PostgreSQL hell three times. First migration took 16 hours because we didn't know about the charset issues. Second time the migration 'succeeded' but half our datetime fields were fucked. Third time with pgLoader: estimated 4 hours, took 11 hours because MySQL kept timing out on large tables.

Our 'simple' 200GB migration turned into a 3-day nightmare when we discovered our source database had 15 different character encodings. The 0000-00-00 dates were just the beginning. We ended up with 47,000 rejected rows and had to manually clean data that should have been garbage 5 years ago.

But here's the thing - pgLoader at least tells you when shit breaks instead of silently corrupting your data like the custom scripts I wrote before. The parallel loading and optimized PostgreSQL configuration can turn a week-long manual migration into an afternoon. Just don't expect miracles if your source data is complete garbage.

pgLoader vs the Competition (What Actually Works vs What Doesn't)

Tool

Description

Best For

pgLoader

Handles MySQL→PostgreSQL without making you cry.

Config file syntax sucks but it works. The parallel processing is legit fast when your network doesn't shit the bed. Saved my ass on a 500GB migration that would've taken weeks manually. Supports MySQL, SQLite, Oracle, MSSQL

  • pretty much anything to Postgre

SQL.

Parallel loading is legit fast, and it won't shit the bed when your source data is garbage. The error handling saves bad rows to files instead of crashing.

Migrating from MySQL/Oracle/MSSQL to PostgreSQL. Covers 80% of real-world migration scenarios without vendor lock-in or Perl nightmares.

pg_dump/pg_restore

Boring but bulletproof for Postgre

SQL-to-PostgreSQL.

Slow as hell but won't break. I use this when I need exact replication and have time to kill. Zero transformation though

  • your MySQL data stays fucked. Perfect for PostgreSQL-to-PostgreSQL moves. Zero data transformation, but it's bulletproof reliable. If you need exact byte-for-byte replication, this is your tool. For everything else, it's useless.

PostgreSQL to PostgreSQL with zero changes. Exact byte-for-byte replication.

ora2pg

Written in Perl by someone who clearly hates other developers. Works but you'll spend more time reading scattered documentation than migrating. The Oracle-to-PostgreSQL conversion is solid if you can figure out the config syntax. If you're stuck migrating from Oracle and enjoy reading Perl code that makes you cry, knock yourself out. It works, but the documentation is scattered and you'll spend more time debugging the migration tool than your actual migration.

Complex Oracle with stored procedures (and lots of coffee). Migrating from Oracle (for the masochistic).

MySQL Workbench

Fine for toy databases. Anything real and you're better off with command line tools. The GUI is nice until it crashes on your 10GB table. Windows-centric and breaks on complex schemas. The MySQL Migration Wizard is fine if you're moving 10 tables and don't care about automation. Anything complex and you're better off writing SQL by hand.

Boss insists on GUI tools. Simple stuff only (e.g., moving 10 tables).

AWS DMS

Works if you have deep pockets and don't mind vendor lock-in. Good for enterprise migrations where downtime costs more than the tool. Support is decent when shit breaks.

Enterprise migrations where downtime costs more than the tool. When you have deep pockets and don't mind vendor lock-in.

DBConvert

Commercial tools like DBConvert work, but you're paying for a GUI and vendor support. If budget isn't a concern and you need hand-holding, go for it.

When your boss has deep pockets. If budget isn't a concern and you need hand-holding. Boss insists on GUI tools.

Installation and Getting Started (With Real Gotchas)

ETL Architecture Overview

Docker Logo

How to Actually Install This Thing

Docker (Just Use This One)

docker pull ghcr.io/dimitri/pgloader:latest

Seriously, just use Docker. The package manager versions are usually outdated, and compiling from source is a nightmare of Common Lisp dependencies that will make you question your life choices. Check the Docker installation guide if you need Docker first.

Package Managers (If You Hate Yourself)

## Debian/Ubuntu (probably an old version)
apt-get install pgloader

## macOS with Homebrew (might work, might not)
brew install pgloader

The Ubuntu package is typically 2-3 versions behind. The Homebrew version works better but still might have dependency issues on newer macOS versions. Check Debian package tracking and macOS compatibility first.

Test Your Installation:

docker run --rm -it ghcr.io/dimitri/pgloader:latest pgloader --version

Your First Migration (That Might Actually Work)

pgLoader Terminal Output

Dead Simple Database Migration:

pgloader mysql://user:pass@source-host/dbname postgresql://user:pass@target-host/dbname

This works about 60% of the time. When it doesn't, you'll need the config file approach below.

CSV File Migration:

pgloader ./data.csv postgresql://localhost/targetdb

Reality Check: Your CSV probably has encoding issues. UTF-8 BOM will break things. Excel exports often have hidden characters. Plan for 2x your estimated time.

When the Simple Approach Fails (Config Files)

Create a .load file because the one-liner approach broke:

LOAD DATABASE
    FROM mysql://source-user:password@source-host/source-db
    INTO postgresql://target-user:password@target-host/target-db

-- More workers = faster (until it doesn't)
WITH include drop, create tables, create indexes, reset sequences,
     workers = 8, concurrency = 2

-- PostgreSQL needs more RAM during migration
SET PostgreSQL PARAMETERS
    maintenance_work_mem to '1GB',
    work_mem to '256MB'

-- MySQL timeouts (because MySQL)
SET MySQL PARAMETERS
    net_read_timeout  = '31536000',
    net_write_timeout = '31536000';

Save this as migration.load and run:

pgloader migration.load

Check the configuration documentation for all the options you'll inevitably need.

Things That Will Break (And How to Fix Them)

Memory Issues: pgLoader will eat all your RAM. Set maintenance_work_mem appropriately - 1GB minimum for large databases. Check PostgreSQL memory settings and shared_buffers configuration before starting. Monitor with pg_stat_activity.

Network Timeouts: Remote migrations timeout constantly. Those MySQL timeout settings above aren't optional - they're survival. Set them to a year (31536000 seconds) and call it a day. Also check PostgreSQL connection settings and TCP keepalive parameters.

Character Encoding Hell: MySQL's latin1 charset will bite you. Add this to your config:

SET MySQL PARAMETERS
    mysql_charset = 'utf8mb4';

Bad Data: Your 0000-00-00 datetime values and empty strings in NOT NULL columns will create .reject.dat files. This is normal. Review the MySQL casting rules to understand what gets converted.

Performance Tuning: More workers isn't always better. Start with 2-4 workers and increase if your network and databases can handle it. Monitor with PostgreSQL stats and adjust accordingly.

The Horror Story Nobody Tells You: I spent an entire weekend figuring out that our MySQL server was using latin1 charset for 'UTF-8' data. Good times.

Data Migration Process Flow

The migration kept succeeding but produced garbage. By Monday morning I had to explain to the CEO why our 'successful' migration corrupted half the customer data.

Don't be the engineer who discovers data corruption in production 3 months after migration. Check those .reject.dat files. Set up monitoring. Test your app thoroughly. I've seen 'successful' migrations destroy businesses because nobody validated the results.

Reality check: Plan for at least 2x your estimated migration time. Something always breaks, usually at the worst possible moment.

Questions You'll Actually Ask (And Honest Answers)

Q

Why does my migration keep failing with cryptic errors?

A

Because your source data is garbage.

My

SQL lets you store 0000-00-00 dates, empty strings in NOT NULL columns, and other crap that PostgreSQL rightfully rejects. Check your `.reject.dat` files

  • that's where pgLoader dumps the bad data instead of crashing completely.
Q

How long will this migration actually take?

A

Your 100GB database? Plan for 6-12 hours, not the 2 hours you estimated. Network latency, bad data cleanup, and MySQL being MySQL will slow things down. We've done terabyte migrations but expect to babysit the process. Check the performance tuning guide for realistic expectations.

Q

What do I do when pgLoader eats all my RAM?

A

Set maintenance_work_mem to something reasonable before starting. pgLoader will use whatever RAM you give it. For large databases, allocate at least 1GB to maintenance_work_mem and work_mem to 256MB. Check PostgreSQL memory configuration first.

Q

Can I migrate stored procedures and triggers?

A

No. pg

Loader moves tables and data, not business logic. Your MySQL stored procedures, triggers, and functions need manual conversion. This isn't a bug

  • it's reality. Database-specific code doesn't magically translate. Budget time for rewriting this stuff in PostgreSQL.
Q

How do I handle charset encoding from hell?

A

Add this to your config and pray:

SET MySQL PARAMETERS
    mysql_charset = 'utf8mb4';

UTF-8 BOM in CSV files will break things. Excel exports often have hidden characters. Use hexdump -C yourfile.csv | head to see what encoding disasters you're dealing with. The MySQL charset documentation covers most scenarios.

Q

Why is the performance terrible compared to what the docs promise?

A

Network latency, bad indexes on source database, competing workloads, or your hardware sucks. The benchmarks assume ideal conditions. Start with 2-4 workers and increase slowly. More workers ≠ faster if your bottleneck is elsewhere.

Q

What happens when the migration dies halfway through?

A

Good news: pgLoader is transactional. Bad news: you start over from the beginning. There's no resume feature. This is why you test migrations on a copy first and run them during maintenance windows. Plan for failures.

Q

How do I migrate a 5TB database without losing my sanity?

A

Break it into smaller chunks by date ranges or partition. Migrate critical tables first, non-critical tables later. Use the continuous migration approach to test your process repeatedly. Consider cloud migration services if time is money.

Q

Can I use this in production without getting fired?

A

pgLoader is used in production, but test everything first. Your specific schema, data quality, and network setup are unique snowflakes. We've done migrations without downtime, but we also spent weeks testing. Don't cowboy this in production.

Q

Why does pgLoader hang on large tables?

A

Network timeouts. Set MySQL parameters to ridiculous values:

SET MySQL PARAMETERS
    net_read_timeout   = '31536000',
    net_write_timeout = '31536000';

That's a year in seconds. Also check if your source database is locked by other processes. The troubleshooting guide on GitHub Issues has common solutions.

Q

Should I use pgLoader or pay for a commercial tool?

A

Depends on your pain tolerance and budget. pgLoader is free but requires technical knowledge. Commercial tools like AWS DMS or DBConvert cost money but provide support. If downtime costs more than the tool, pay for support.

Q

Why did my 'successful' migration result in corrupted data?

A

Because MySQL lets you store 0000-00-00 dates and PostgreSQL doesn't. pgLoader dumps this garbage into .reject.dat files, but if you don't check them, you'll think everything worked fine until users start complaining about missing data.

Ask me how I know: spent 3 months chasing 'mysterious' application bugs that turned out to be silently dropped rows from the migration. 18,000 rejected records that we never validated. Had to rebuild half the database from backups. Check the MySQL casting rules and validate those reject files religiously.

Q

How do I know if my migration actually worked?

A

Row counts are a start, but not enough. Compare checksums, sample data validation, and test your application thoroughly. Write queries that verify referential integrity, check for data type issues, and validate business logic. Assume something broke until you prove it didn't.

Related Tools & Recommendations

howto
Similar content

MySQL to PostgreSQL Production Migration: Complete Guide with pgloader

Migrate MySQL to PostgreSQL without destroying your career (probably)

MySQL
/howto/migrate-mysql-to-postgresql-production/mysql-to-postgresql-production-migration
100%
compare
Similar content

PostgreSQL vs MySQL vs MongoDB vs Cassandra: In-Depth Comparison

Skip the bullshit. Here's what breaks in production.

PostgreSQL
/compare/postgresql/mysql/mongodb/cassandra/comprehensive-database-comparison
87%
compare
Similar content

PostgreSQL vs MySQL vs MariaDB vs SQLite vs CockroachDB

Compare PostgreSQL, MySQL, MariaDB, SQLite, and CockroachDB to pick the best database for your project. Understand performance, features, and team skill conside

/compare/postgresql-mysql-mariadb-sqlite-cockroachdb/database-decision-guide
72%
howto
Similar content

MongoDB to PostgreSQL Migration: The Complete Survival Guide

Four Months of Pain, 47k Lost Sessions, and What Actually Works

MongoDB
/howto/migrate-mongodb-to-postgresql/complete-migration-guide
65%
compare
Similar content

PostgreSQL vs MySQL vs MariaDB: Developer Ecosystem Analysis

PostgreSQL, MySQL, or MariaDB: Choose Your Database Nightmare Wisely

PostgreSQL
/compare/postgresql/mysql/mariadb/developer-ecosystem-analysis
44%
howto
Similar content

Zero Downtime Database Migration Strategies: AWS DMS Guide

How to Migrate Your Production Database Without Getting Fired (Or Losing Your Mind)

Blue-Green Deployment
/howto/database-migration-zero-downtime/zero-downtime-migration-strategies
41%
compare
Similar content

PostgreSQL, MySQL, MongoDB, Cassandra, DynamoDB: Cloud DBs

Most database comparisons are written by people who've never deployed shit in production at 3am

PostgreSQL
/compare/postgresql/mysql/mongodb/cassandra/dynamodb/serverless-cloud-native-comparison
39%
tool
Similar content

CDC Database Platform Guide: PostgreSQL, MySQL, MongoDB Setup

Stop wasting weeks debugging database-specific CDC setups that the vendor docs completely fuck up

Change Data Capture (CDC)
/tool/change-data-capture/database-platform-implementations
39%
howto
Similar content

Zero Downtime Database Migration: 2025 Tools That Actually Work

Stop Breaking Production - New Tools That Don't Suck

AWS Database Migration Service (DMS)
/howto/database-migration-zero-downtime/modern-tools-2025
39%
tool
Similar content

ClickHouse Overview: Analytics Database Performance & SQL Guide

When your PostgreSQL queries take forever and you're tired of waiting

ClickHouse
/tool/clickhouse/overview
38%
tool
Similar content

Change Data Capture (CDC) Troubleshooting Guide: Fix Common Issues

I've debugged CDC disasters at three different companies. Here's what actually breaks and how to fix it.

Change Data Capture (CDC)
/tool/change-data-capture/troubleshooting-guide
38%
compare
Similar content

PostgreSQL vs MySQL vs MariaDB - Performance Analysis 2025

Which Database Will Actually Survive Your Production Load?

PostgreSQL
/compare/postgresql/mysql/mariadb/performance-analysis-2025
38%
compare
Similar content

PostgreSQL vs. MySQL vs. MongoDB: Enterprise Scaling Reality

When Your Database Needs to Handle Enterprise Load Without Breaking Your Team's Sanity

PostgreSQL
/compare/postgresql/mysql/mongodb/redis/cassandra/enterprise-scaling-reality-check
36%
tool
Similar content

Neon Production Troubleshooting Guide: Fix Database Errors

When your serverless PostgreSQL breaks at 2AM - fixes that actually work

Neon
/tool/neon/production-troubleshooting
34%
tool
Similar content

Neon Serverless PostgreSQL: An Honest Review & Production Insights

PostgreSQL hosting that costs less when you're not using it

Neon
/tool/neon/overview
34%
alternatives
Similar content

MySQL Alternatives & Migration: Escape Oracle Licensing & Scaling Walls

Oracle's 2025 Licensing Squeeze and MySQL's Scaling Walls Are Forcing Your Hand

MySQL
/alternatives/mysql/migration-focused-alternatives
33%
tool
Similar content

PostgreSQL: Why It Excels & Production Troubleshooting Guide

Explore PostgreSQL's advantages over other databases, dive into real-world production horror stories, solutions for common issues, and expert debugging tips.

PostgreSQL
/tool/postgresql/overview
32%
tool
Similar content

Supabase Overview: PostgreSQL with Bells & Whistles

Explore Supabase, the open-source Firebase alternative powered by PostgreSQL. Understand its architecture, features, and how it compares to Firebase for your ba

Supabase
/tool/supabase/overview
32%
review
Similar content

Database Benchmark 2025: PostgreSQL, MySQL, MongoDB Review

Real-World Testing of PostgreSQL 17, MySQL 9.0, MongoDB 8.0 and Why Most Benchmarks Are Bullshit

/review/database-performance-benchmark/comprehensive-analysis
32%
tool
Similar content

PostgreSQL Logical Replication: When Streaming Isn't Enough

Unlock PostgreSQL Logical Replication. Discover its purpose, how it differs from streaming replication, and a practical guide to setting it up, including tips f

PostgreSQL
/tool/postgresql/logical-replication
32%

Recommendations combine user behavior, content similarity, research intelligence, and SEO optimization