SQL Server
PostgreSQL

SQL Server to PostgreSQL Migration Tool

Schema conversion, type mapping, and optional two-way sync between on-prem and cloud Postgres.

Version
5.0.42
Release Date
Sept. 12, 2026
Size
24.3 MB

Copy a SQL Server database into PostgreSQL without writing the target schema by hand. DBConvert connects to both servers, proposes a PostgreSQL type for every column, and creates the tables, indexes, and foreign keys before it moves a row.

  • Reads SQL Server on-prem, SQL Server Express, Azure SQL, or Amazon RDS for SQL Server.
  • Writes to PostgreSQL on your own server, Amazon RDS / Aurora, Azure Database for PostgreSQL, Google Cloud SQL, or Supabase.
  • Converts the database once, or keeps SQL Server and PostgreSQL synchronized on a schedule, in one direction or both.
  • Runs on Windows as a desktop application - nothing is uploaded to a web service.
How it runs

A Windows application that talks to both servers

You install it, point it at a live SQL Server instance and a live PostgreSQL server, and it does the work in place.

Windows desktop

A native Windows application with a wizard, installed on your own machine. Your credentials and your data never pass through a third-party service.

Live connections, not files

Both ends are database connections. There is no .bak file to restore and no bcp extract to feed into COPY - the tool reads the SQL Server instance directly and writes to PostgreSQL, over Windows Authentication or a SQL login.

Saved and repeatable

A job stores both connections, the table selection, and the options. Run it again from the interface, or start it by name from a batch file or Task Scheduler with --run-job.

Two modes, one download

Convert once, or keep SQL Server and PostgreSQL connected

One download covers both. You choose the mode when you set up the job.

One-time conversion

Schema, indexes, foreign keys and rows in one pass, with the type mapping you reviewed.

  • A large table is split into ranges and copied by several threads at once.
  • The run reports rows received per table - compare them against the source before you switch the application over to PostgreSQL.

Repeat synchronization

Keep both databases in use while you cut over.

  • Run the job on a schedule, in one direction or in both.
  • Only the rows that changed since the last run move.
  • Each synchronized table needs a primary key or a unique non-composite index, so the two sides can be matched.
Why move

When PostgreSQL is the right target

Licensing cost

SQL Server Standard and Enterprise are licensed per core, with Software Assurance on top. PostgreSQL carries no per-core, per-user, or per-database fee on any build.

No Express ceiling

SQL Server Express is free but capped at 10 GB per database, one socket or four cores, and a 1.4 GB buffer pool. PostgreSQL has no edition tiers - the free build is the build everyone runs in production.

The types survive the move

PostgreSQL has a real equivalent for most of what SQL Server stores: UUID, BOOLEAN, XML, and a timestamp that keeps its time zone. Fewer columns have to be approximated than on any other target.

Extensions instead of editions

PostGIS, pgvector and TimescaleDB install into an ordinary PostgreSQL build. Geospatial, vector search, and time-series work does not push you up an edition ladder.

What needs attention

How DBConvert handles the SQL Server → PostgreSQL differences

Every mapping below is a default you can review or override per column before the run.

In SQL Server Why it does not carry over What DBConvert does
Keys and identity
IDENTITY PostgreSQL generates keys from a sequence the table owns, not from a property on the column. Created as GENERATED ... AS IDENTITY, or SERIAL on older targets, and the sequence is set past the highest loaded value so the next insert does not hit a duplicate key.
UNIQUEIDENTIFIER Nothing to reconcile here - both engines have a native GUID type. Becomes UUID, stored as 16 bytes and comparable as a GUID rather than as text.
Numbers
BIT SQL Server's BIT is a one-bit integer column; PostgreSQL has a real boolean. Becomes BOOLEAN, so the column reads as true/false instead of 1/0.
MONEY, SMALLMONEY PostgreSQL's own money type depends on the server's locale setting, which makes it the wrong place to land an amount that has to stay exact. Both go to fixed-point NUMERIC - MONEY as NUMERIC(19,4) and SMALLMONEY as NUMERIC(10,4) - keeping the four decimal places and the full range of each.
Date and time
DATETIME2, TIME Both engines store fractional seconds, but SQL Server goes to 100 ns and PostgreSQL stops at microseconds. The declared scale comes across, capped at the six digits PostgreSQL supports: DATETIME2(7) becomes TIMESTAMP(6) and TIME(7) becomes TIME(6).
DATETIMEOFFSET The value carries a UTC offset with it, and most targets have nowhere to put one. Becomes TIMESTAMPTZ, which keeps the instant rather than the wall-clock reading. This is the one target where the zone does not have to be dropped or moved into a second column.
Text and XML
NVARCHAR, NCHAR SQL Server keeps Unicode in the N types and everything else in the database's code page, where anything outside it was already lost before the migration started. Land on VARCHAR and CHAR in a UTF8 database, so Cyrillic, CJK and emoji arrive intact. PostgreSQL has one text encoding per database, so there is no second, narrower type to fall into.
NVARCHAR(max), VARCHAR(max) The max forms hold up to 2 GB, and PostgreSQL does not declare a length for unbounded text. Created as TEXT, which has no length limit and is stored out of line automatically when a value is large.
XML Nothing to reconcile - PostgreSQL has an xml type of its own. Stays XML, transcoded into the database encoding, so xpath() and the rest of PostgreSQL's XML functions work on it.
Binary
VARBINARY, ROWVERSION SQL Server's TIMESTAMP / ROWVERSION is a row-change counter, not a date - a name that has misled more than one migration. Both become BYTEA. The row-version column arrives as the bytes it was; it stops advancing, because the counter belonged to the source server.
Structure
Identifier case PostgreSQL folds unquoted names to lower case, so OrderHeader becomes orderheader unless every reference to it is quoted forever after. Mixed-case names are normalised to lower case by default, or the quoting is preserved as it was - you pick the policy in the wizard rather than discovering it at application boot.
Index names SQL Server index names only have to be unique within their table; PostgreSQL requires them to be unique across the whole schema. Colliding names are disambiguated on the way in, so two tables that each had an IX_Name both keep their index.

Procedural code stays behind

The migration covers tables - their fields, types, defaults, and indexes - the views, and the foreign keys. T-SQL stored procedures, functions, triggers, and table-valued parameters stay in the source and are rewritten by hand in PL/pgSQL: MERGE, GOTO, and table-valued parameters have no direct equivalent. The SQL Server to PostgreSQL migration guide covers those rewrites in depth. On most schemas this is a small share of the work, and it is rewrite work on any route.

If you need continuous replication instead

Scheduled synchronization is enough for a staged cut-over that runs for days or weeks. When the source has to stay live and every change must land within seconds, that is log-based change data capture, and it is a different product: DBConvert Streams replicates continuously and runs anywhere.

Supported versions and services

SQL Server

  • SQL Server 2008-2022, including Express editions
  • Azure SQL Database and Amazon RDS for SQL Server
  • SQL Server schemas (dbo, custom schemas)
  • Windows authentication or SQL authentication

PostgreSQL

  • PostgreSQL 8.x through 17.x
  • Amazon RDS / Aurora for PostgreSQL, Azure Database for PostgreSQL, Google Cloud SQL, Supabase
  • PostgreSQL schemas (public, custom schemas)

How to migrate SQL Server to PostgreSQL

DBConvert opens in GUI mode and walks the job from connection to commit:

1

Connect to SQL Server source database

Specify the username/password and host/port parameters if your source database requires login credentials.

Connect to SQL Server source database from DBConvert

SQL Server source

Connect by TCP/IP or Named Pipes, use Azure SQL, or read from Amazon RDS for SQL Server.

2

Connect to PostgreSQL destination database

Specify parameters for the destination database similar to the source, defining connection settings and username/password pairs.

Connect to PostgreSQL target database from DBConvert

PostgreSQL target

Connect to self-hosted PostgreSQL, Amazon RDS / Aurora for PostgreSQL, Azure Database for PostgreSQL, Google Cloud SQL, or Supabase.

Steps 3-6: the same for every database pair

Source and target are connected - steps 1 and 2 above. What follows is identical whichever two databases you picked, so it lives in one place. Each step below opens at its own section.

Open the full guide

All four steps in one page, plus software features, command-line mode, scheduler, and system requirements.

See all features

More guides for SQL Server ↔ PostgreSQL

Move SQL Server data into PostgreSQL

Download the current build and run the first job against your own database.

Windows Windows 10 or later · 24.3 MB