SQL Server is licensed per core (with a four-core-per-VM minimum), usually layered with Software Assurance, and its edition ceilings push expensive upgrades as you scale, and it drags Windows Server licensing along with it. PostgreSQL is the most common open-source destination: a mature relational engine with strong SQL support, rich extensions, and no license fee. The data movement is the easy part; the work is T-SQL and application SQL, and that is what this guide walks through.
The economics
SQL Server cost is driven by the cores of the database VM, and the higher-end features live behind Enterprise edition. PostgreSQL removes the license entirely, leaving infrastructure plus optional commercial support (EDB, Percona, Crunchy Data). For most workloads the three-year TCO falls sharply, so the decision hinges on conversion effort, not on whether it saves money.
What converts cleanly, and what doesn’t
Schema and data migrate well. The friction is dialect:
- T-SQL procedures, functions, and triggers → PL/pgSQL. Simple logic converts; heavy T-SQL (temp tables,
MERGEquirks, error handling, table-valued parameters) needs rework. - Datatypes.
DATETIME/DATETIME2→timestamp,MONEY→numeric,UNIQUEIDENTIFIER→uuid,NVARCHAR→text/varchar, andIDENTITY→GENERATED ... AS IDENTITYor sequences. - Dialect habits. Bracketed
[identifiers],TOPvsLIMIT,ISNULLvsCOALESCE,GETDATE()vsnow(), thedbodefault schema, and case-folding all differ. - Application SQL. This is usually the largest hidden cost, every embedded query and ORM mapping that assumed T-SQL has to be validated.
Babelfish: skipping most of the app rewrite
If the application rewrite is the blocker, Babelfish for PostgreSQL is the lever. Babelfish adds a TDS endpoint and a T-SQL dialect layer so existing SQL Server clients and much of their T-SQL connect to PostgreSQL with little or no change. It runs in Amazon Aurora and as the open-source Babelfish for PostgreSQL you can self-host. It won’t cover 100% of T-SQL, but it can turn a rewrite project into a compatibility-gap project, a very different cost.
Tooling
pgloader handles schema-plus-data for straightforward databases in one pass. AWS Schema Conversion Tool (SCT) assesses complexity and converts schema and code, flagging what needs manual work, and pairs with AWS DMS for change-data-capture so the target stays current with low cutover downtime. The open-source sqlserver2pgsql is an alternative schema/converter.
For a small or straightforward database where a maintenance window is acceptable, a single pgloader run is often enough and is the fastest path. For a large database that needs low downtime, lean on SCT for the schema and code conversion and DMS for full-load plus CDC. Whichever you pick, generate an assessment first (an SCT report or a pgloader dry run) and let it, rather than optimism, size the procedural conversion work.
The procedural code that needs hands
The schema and data move well; the friction is dialect and procedural code. Beyond the datatype and habit differences above, watch these:
MERGEand temp tables. T-SQLMERGEhas quirks that do not map one-to-one to PostgreSQL’sINSERT ... ON CONFLICT, and#temptables becomeCREATE TEMP TABLEor CTEs. Review each usage.- Error handling.
TRY/CATCHand@@ERRORpatterns become PL/pgSQLBEGIN ... EXCEPTIONblocks, which have different scoping and rollback semantics. - Built-in functions.
ISNULLbecomesCOALESCE,GETDATE()becomesnow(),TOPbecomesLIMIT, and string/date functions differ enough that each needs checking. dboand schemas. The defaultdboschema and cross-database three-part names do not exist in PostgreSQL; plan a schema layout up front.
Application SQL changes
The application SQL is usually the largest hidden cost, and Babelfish is the lever that can shrink it. Without Babelfish, every embedded query, ORM mapping, reporting query, and ETL job that assumed T-SQL has to be validated and often edited: bracketed identifiers, TOP, ISNULL, GETDATE(), and SCOPE_IDENTITY() all change. With Babelfish, much of that T-SQL continues to run against PostgreSQL through the TDS endpoint, so the work becomes finding and fixing the compatibility gaps rather than rewriting everything. Either way, inventory every place SQL is written before you commit to a scope, because the code you cannot see is what slips the schedule.
Sequencing the migration
- Assess with SCT (or a pgloader dry run); triage objects by conversion difficulty, and decide Babelfish vs native PostgreSQL.
- Provision a primary plus replicas, sized on vCPU, with backups and tuning.
- Convert schema, review the action items, load into PostgreSQL.
- Migrate data, a bulk load for the rehearsal, then CDC replication to keep the target current.
- Convert procedures and application SQL in parallel with data work.
- Validate with row counts, checksums/data-diffs, an application regression suite, and query-plan comparisons against the SQL Server baseline.
- Cut over in a window: quiesce writes, drain CDC to zero lag, run a final diff, repoint connection strings, smoke-test, and keep SQL Server recoverable through hypercare.
Where the schedule lives or dies
The biggest predictor of a clean cutover is the depth of the parallel-run and validation phase. Replay representative workloads against both databases, compare results and plans, and only promote when documented acceptance criteria, correctness, performance, and failover, are met.
What it comes down to
SQL Server → PostgreSQL reliably cuts licensing cost; the effort is T-SQL and application-SQL conversion plus rigorous validation, not the data movement. Babelfish can remove most of the application rewrite if you accept its compatibility gaps. Model your per-core savings in the calculator above, and treat the figures as illustrative until a support vendor or distributor quotes your environment.