Migrating from SQL Server to PostgreSQL: what moves cleanly and what you rewrite
pgloader can discover and load tables, indexes and keys from a SQL Server source into PostgreSQL, so the schema copy is the part of this migration most teams can automate. The work that sets the effort sits elsewhere: T-SQL stored procedures, functions and triggers that must be rewritten in PL/pgSQL, application queries written against SQL Server behavior, and the cutover design that decides how writes stop on the old system and resume on the new one. A team that runs SQL Server for licensed databases, stored procedures and applications should treat the schema load as the short step and the code and cutover as the long ones. Build the inventory before anyone discusses a timeline.
The PostgreSQL License is permissive, similar in spirit to the BSD and MIT licenses, so the database software itself carries no license fee to plan around. The savings case therefore depends on what you still pay for after the move: backup tooling, high availability components, connection pooling, monitoring, support contracts and the engineers who run the platform. Those costs recur, while assessment, code conversion, data validation, parallel running and cutover are one-time. When you request a quote, ask each line to state whether it is one-time or recurring, who performs it, and which items depend on how many procedures you rewrite. Confirm your own SQL Server licensing position with your licensing advisor, because licenses may be tied to other products you keep.
The inventory decides the scope, so collect it before the first design meeting. List every database with its size and table count, and every stored procedure, scalar and table-valued function, trigger and SQL Server Agent job, with its owner and callers. Note linked servers, CLR assemblies, cross-database queries, identity columns, computed columns, and data type choices such as datetime variants and money. On the application side, record whether queries come from an ORM, a data access layer or hand-written SQL, since generated SQL is easier to port than strings embedded in code. Tag each module as simple, needs rewriting, or should move into application code. That tagging is the input the assessment uses to size the rewrite.
DeployOpen does not give a duration until the inventory and assessment are complete, because the same database count can mean a few weeks of conversion or months of rewriting depending on the code it holds. After the assessment, the scope, deliverables and timelines are written down and agreed before work starts, and that written scope is the basis for the quote. Ask for it to name the migration method, the rewrite list, the validation approach for row counts and data types, the parallel running period, the cutover window and the rollback path. A rollback path that depends on writes flowing back to SQL Server needs its own design, and that design should appear in the scope itself.
Which SQL Server features map to PostgreSQL and which need rewriting
This table compares common SQL Server features with their PostgreSQL equivalents and marks each one as automatic, partly automatic or manual. Use the mode column to size the work: automatic items still need verification after the load, while manual items need design and code changes. Confirm type and collation mappings against the pgloader documentation for the SQL Server and PostgreSQL versions in use.
| SQL Server feature | PostgreSQL equivalent | Migration mode | Migration notes |
|---|---|---|---|
| Tables, primary keys, foreign keys and identity columns | Tables, primary and foreign keys, GENERATED AS IDENTITY columns | Partly automatic | pgloader creates tables and keys from catalog metadata. Reset identity sequences to the maximum loaded value before cutover. |
| Indexes, including clustered and filtered indexes | B-tree and partial indexes, with CLUSTER for one-time reordering | Partly automatic | Standard indexes are recreated on load. Review filtered index predicates and clustered index intent, which PostgreSQL does not maintain automatically. |
| Common data types and collations | Native types with ICU or libc collations | Partly automatic | Confirm mappings for datetime2, money and uniqueidentifier in the pgloader documentation. Test sort order and case sensitivity, which depend on collation. |
| Views and computed columns | Views and generated columns, with virtual generated columns as the default in PostgreSQL 18 | Manual | Views are usually recreated by hand from their definitions. Check computed column expressions for T-SQL functions before rebuilding them. |
| Triggers | PL/pgSQL trigger functions attached with CREATE TRIGGER | Manual | Trigger bodies must be rewritten. Review DML triggers for implicit behavior, since PostgreSQL triggers fire per row or per statement. |
| Stored procedures and T-SQL functions | PL/pgSQL functions and procedures created with CREATE PROCEDURE | Manual | T-SQL control flow, temporary tables, error handling and cursors need rewriting. Keep a test suite that compares results with the SQL Server originals. |
| SQL Server Agent jobs | An external scheduler, cron, or pg_cron where it fits the design | Manual | Jobs do not migrate. Inventory schedules, owners and failure alerts, then rebuild them in a scheduler your operations team already runs. |
| Linked servers and cross-database queries | postgres_fdw foreign tables, or schemas within one database | Manual | A PostgreSQL statement cannot span databases. Consolidate into schemas or use postgres_fdw, and confirm its fit with your network and security design. |
| Windows authentication | SSPI or GSSAPI authentication with role mapping | Manual | PostgreSQL documents SSPI and GSSAPI methods. Map Windows logins to database roles and confirm the setup against your domain and client drivers. |
Which T-SQL code must be rewritten by hand in PL/pgSQL
pgloader moves tables, indexes and keys automatically, but the procedural layer of a SQL Server database must be rewritten by hand. Stored procedures, scalar and table-valued functions, triggers, cursors, dynamic SQL, TRY and CATCH error handling and transaction logic all depend on T-SQL behavior that PL/pgSQL and standard SQL express differently. A tool can translate a fragment of syntax, but it cannot reproduce how an error inside a transaction behaves, how nested transactions are counted, or how a batch continues after a failed statement. Each object in this layer needs a reviewed conversion and a test that compares its results with the original. Several T-SQL constructs have direct but different equivalents. Bracket identifiers such as [Order Details] become double-quoted identifiers, TOP becomes LIMIT or FETCH FIRST, and TRY and CATCH become BEGIN and EXCEPTION blocks, which PostgreSQL implements with subtransactions. Dynamic SQL built with sp_executesql should be rewritten with EXECUTE and USING or with format() for identifiers. Cursors may be replaced by set-based statements where the logic allows it. Decide these patterns once, document them, and apply them consistently so reviewers can check each object against the same rules. Identifier case needs an early decision. PostgreSQL folds unquoted names to lowercase, while SQL Server with a default case-insensitive collation lets applications refer to Customer and customer interchangeably. A mixed-case name created in SQL Server and quoted in PostgreSQL must then be quoted everywhere, including in application SQL and reporting tools. Choose a naming convention, usually lowercase snake_case, before converting code, and confirm with your application teams how they reference identifiers. Computed columns can map to generated columns. PostgreSQL 18 creates virtual generated columns by default, while earlier supported versions offer only stored generated columns, so confirm which behavior your queries and indexes need in the version you deploy. Before anyone estimates effort, inventory the code. Count objects by type (procedures, functions, triggers, views, jobs), measure their size, and mark dependencies on linked servers, CLR assemblies, SQL Agent jobs and cross-database references. Then classify each object as simple, moderate or complex based on cursors, dynamic SQL, error handling and transaction scope. Ask any partner or internal team to show this inventory and its classification rules in writing, because the quote and schedule should follow from it. Finally, plan verification before conversion begins. Build a test set with representative data, run the original and converted objects side by side, and compare row counts, outputs and error behavior. Record each deliberate difference in behavior and get the application owner to accept it. Keep the original database available until these comparisons pass, so that any defect found after cutover has a documented rollback path.
Documented import paths and supporting tools for the move
Each card covers one tool or method the migration depends on, from loading data through authentication, connection pooling and rollback. Confirm the SQL Server export utilities against your SQL Server version before you choose an import path, because the export format determines how much of the load can be automated.
pgloader for discovery and loading
pgloader connects to SQL Server, discovers tables, indexes and keys, and loads the data into PostgreSQL in one run. That discovery gives you a schema inventory to review, but it does not rewrite T-SQL, stored procedures or application queries, which still need hand work. Check pgloader's SQL Server source support and its default casting rules against the SQL Server version you run, then review every mapped type, including dates, money, unique identifiers and text encodings, on a test copy before any production load.
COPY and psql for scripted loads
PostgreSQL COPY loads delimited files exported from SQL Server, and psql runs the scripted loads and the validation queries that compare row counts, checksums and sampled values between the two systems. Keep these scripts in version control so the rehearsal and the production run execute identical steps. Confirm the export format and encoding your SQL Server export utility produces, because field delimiters, quoting and null markers must match what COPY expects.
SSPI and GSSAPI for Windows-integrated access
PostgreSQL's SSPI method lets Windows clients authenticate with their domain identity, and GSSAPI provides Kerberos authentication on Linux and Unix hosts. Migration jobs and application services often run under service accounts, so decide which accounts map to which database roles, and where keytabs or service principals are stored, before cutover. Confirm the exact configuration in the client authentication documentation for your PostgreSQL version and directory service.
SCRAM as the password method
SCRAM is the password method to use for new roles and for roles carried over from SQL Server logins. PostgreSQL 18 deprecated MD5 password authentication in favor of SCRAM, so any role or host-based authentication entry still set to MD5 should be found and replaced during the build. Verify that every connecting driver, including older ODBC, JDBC and .NET providers, supports SCRAM before the application switches to PostgreSQL.
PgBouncer for the parallel run
PgBouncer pools client connections in front of PostgreSQL, which matters during the parallel run when the existing SQL Server application and the new PostgreSQL path may both be connected. Agree the pool mode with the application team, because session-level features such as prepared statements and session variables can behave differently under transaction pooling. Plan the PgBouncer version against current security releases: version 1.26.1 was released on October 14, 2026, with security fixes.
Continuous archiving for a rollback baseline
Continuous archiving keeps a base backup and archived WAL files so the database can be restored to a chosen point in time. Use it to hold a rollback baseline before cutover, so that if validation fails after go-live the team can return to a known state. Test the restore itself, not only the backup job, and confirm that archive storage and retention meet your recovery policy.
What licensing savings depend on and what replaces them
PostgreSQL is released under the PostgreSQL License, a liberal open source license similar to the BSD or MIT licenses, so there is no per-core or per-user license fee to pay for the database software itself. The savings from this migration come from retiring SQL Server licenses, and the size of that saving depends on your own agreement. Before you model it, confirm which SQL Server edition each instance runs, how cores are licensed under your agreement, whether licenses are perpetual or subscription-based, and what Software Assurance or support contract covers them and when it renews. Those terms, not list prices, determine how much of the license spend you can actually retire and when.
Retiring licenses does not remove all database costs. Infrastructure remains, and you still need servers or virtual machines, storage, network capacity and the operating system for every PostgreSQL node, including standbys, a backup target and any test or staging environments you keep during the migration. Backup and high availability tooling also has to be chosen and run. PostgreSQL provides continuous archiving, point-in-time recovery and streaming replication, but it does not detect a failed primary and promote a standby on its own, so an external failover tool and a connection pooler such as PgBouncer are normally part of the design. Each of these is a cost to plan, whether it is open source, a commercial product or staff time.
Some costs appear only during the migration and are mostly labor. Your team or a partner will rewrite T-SQL that pgloader cannot convert, including stored procedures, triggers, functions and SQL Server-specific features, and then test the application against PostgreSQL behavior. Testing covers data validation, query performance and cutover rehearsal. Your developers and database administrators need training on PostgreSQL administration, the planner, vacuum behavior and backup tooling. These are one-time costs, but they can exceed the licensing you retire in the first year if the application has heavy procedural code, so estimate them from a code inventory rather than from the number of tables.
When you request a quote from DeployOpen, ask for the written scope to name the SQL Server objects in scope, the T-SQL to be rewritten, the test cycles, the cutover rehearsals and the handover documentation. Ask which costs are one-time and which recur, such as an optional support retainer for patching, upgrades and continuous testing. Ask what the quote excludes, including your infrastructure, licenses for any commercial tools you choose, and your internal staff time. The quote should let you compare your current SQL Server spend, net of retired licenses, against the new recurring and one-time costs over the period you plan to run the system.
How the migration runs from inventory to decommission
The migration moves through seven controlled stages, each closing with a written output that the next one depends on. Inventory and assessment set the scope, while pilot conversion, code rewrite, rehearsals and parallel running prove the target before production traffic moves. Decommission happens only after the agreed retention window ends.
Inventory databases, objects, jobs and applications
Your team and DeployOpen list every SQL Server instance, database, schema, table, view, stored procedure, function, trigger, SQL Agent job, linked server and the applications that connect to each one. The inventory records data volumes, collation and encryption settings, and which objects use T-SQL features with no direct PostgreSQL equivalent. Each object gets a conversion category: automatic, assisted or manual rewrite. The step closes when the business owner signs off the inventory and the list of applications in the first migration wave.
Run pilot schema conversion into a test instance
A pilot conversion with pgloader runs against a copy of one representative database and loads the schema, data and keys into a non-production PostgreSQL instance on a supported major version, such as 17 or 18. The team reviews the discovered tables, indexes, primary and foreign keys, and the type mappings pgloader applied, then records every object it could not convert automatically. Output: a conversion report, a list of objects needing hand-written changes, and a test instance that matches the agreed PostgreSQL version and configuration.
Rewrite T-SQL code and run regression tests
Procedures, functions, triggers and jobs that pgloader cannot translate are rewritten by hand in PL/pgSQL or moved into the application layer, depending on what the inventory recommends. Each rewritten object gets a regression test that runs the same inputs against SQL Server and PostgreSQL and compares results, including null handling, date arithmetic, string collation and transaction behavior. The step closes when the test suite passes on the pilot instance and each rewritten object is traced back to its inventory entry.
Rehearse full data loads until results match
The team runs full data loads from a fresh SQL Server snapshot into a clean PostgreSQL instance several times, recording each run's timing, row counts, checksums on key tables and any rejected rows. Each rehearsal addresses one class of problem, such as a type mapping, a sequence value or a failing constraint, before the next run begins. Ask for the reconciliation report from the most recent rehearsal before approving the load. The step closes when consecutive rehearsals reconcile with no unexplained differences and the load runbook is approved.
Verify application behavior in a parallel run
The application keeps using SQL Server as the system of record while the same reads and writes are replayed or mirrored to PostgreSQL through a method chosen in the design. Result sets, row counts and business totals are compared on a schedule, and each mismatch is logged with the query, the input and the application version. Drivers, connection pooling settings and ORM behavior are tuned during this period. The step closes when agreed mismatch categories are resolved or explained and the business owner accepts the comparison report.
Cut over in phases with a rollback point
Cutover moves one application or database group at a time, starting with the least critical group agreed in the inventory. Before each phase, the team freezes schema and data changes, runs a final delta load, reconciles the data, and records a rollback point with a tested path back to SQL Server. Connection strings, scheduled jobs and monitoring are switched together, and a named owner watches the first full business cycle. The step closes when the phase passes reconciliation and the owner confirms the application is stable.
Decommission SQL Server after the retention window
After the agreed retention window ends, SQL Server is decommissioned in stages: write access is removed first, final backups are taken and stored under your retention policy, and licenses are reviewed against the instances still in use. Instances are then shut down and removed from monitoring and backup schedules. The retention window is set by your data retention and recovery requirements, so confirm it with compliance before the first cutover. The step closes with a signed decommission record listing what was removed, where final backups are stored, and who approved the removal.
What drives SQL Server migration cost and duration
This table compares the drivers that change the effort and calendar time of a SQL Server to PostgreSQL move, with what raises each one and what keeps it down. Use it to see which parts of your inventory will move the estimate most, and treat the inventory, not this table, as the source of any figure. The main takeaway is that converting schema objects is rarely the largest cost, while application access, downtime limits and audit evidence often are.
| Driver | What increases effort | What reduces effort |
|---|---|---|
| T-SQL objects | Many stored procedures, triggers, views and functions that use SQL Server-specific features such as cursors, MERGE, dynamic SQL or CLR code | Clean schema with few procedural objects, and a decision early on which logic moves into the application or stays in the database |
| Data volume and downtime tolerance | Large tables, binary columns, and a cutover window too short for a full offline load | Smaller data sets, an initial bulk load followed by change capture, and an agreed maximum cutover window written into the scope |
| Application query patterns and ORM use | Hand-written T-SQL in application code, SQL Server hints, and ORM settings tied to SQL Server dialect behavior | Queries that go through one data access layer, ORM dialect support confirmed for PostgreSQL, and a shortlist of queries to test first |
| Applications sharing one database | Several applications reading and writing the same schemas, with cross-schema joins and shared logins | Clear ownership of schemas, separate roles per application, and a sequence that moves one application at a time |
| Windows authentication and SSO | Integrated Windows logins, Active Directory groups mapped to database roles, and SSO flows that depend on Kerberos or SSPI | An inventory of every login and group, a chosen PostgreSQL authentication method (such as GSSAPI, SSPI or LDAP) tested against your directory, and a role model agreed beforehand |
| High availability and backup targets | Availability groups or log shipping that must be matched, stricter recovery point and recovery time targets, and several backup tiers | A written target for each tier, and a design that uses PostgreSQL replication and point-in-time recovery with an external failover tool where automatic failover is required |
| Parallel run length | Long periods where both databases accept writes, reconciliation across two systems, and unclear rules for which system is authoritative | A short parallel run with read-only verification, automated row and checksum comparisons, and a named decision owner for each cutover step |
| Compliance evidence | Audit requests for change records, access reviews, backup restore tests and logging on the new platform before go-live | Evidence collected during the build (test results, configuration baselines, access lists and restore logs), agreed with your assessor before work starts |
What usually goes wrong in SQL Server migrations and how to prevent it
Most SQL Server to PostgreSQL migrations fail after the schema loads without errors. The problems below tend to surface during reconciliation, application testing or cutover, when they are most expensive to fix. Each card names the check that catches the problem before production traffic moves.
Silent type and collation drift
pgloader maps SQL Server data types to PostgreSQL types automatically, but some mappings can lose precision or change how text sorts and compares, and neither change raises an error on load. Date and time precision, money values and collation-sensitive text columns are the usual places for this to appear. Reconcile row counts and checksums on sample rows for every column type in scope, compare sorted query results, and confirm the collation chosen for each database against what the application expects.
Application queries that behave differently
PostgreSQL folds unquoted identifiers to lowercase and treats quoted identifiers as case-sensitive, so queries that ran against SQL Server can fail or return no rows after the move. Transaction behavior also differs: in PostgreSQL, an error aborts the whole transaction until it ends, so code that catches an error and keeps going will misbehave, and locking under concurrent writes follows different rules. Test rewritten procedures and ORM queries under concurrent load, and review every error handling path.
SQL Server Agent jobs missed
Agent jobs often run backups, ETL steps, index maintenance and report extracts, and they live in the msdb database rather than in the schema that discovery tools inspect. Build the inventory from job, step and schedule metadata, then record each job's owner, purpose and downstream consumers. Decide per job whether it moves to cron, a workflow scheduler or retires, and confirm the list with the teams that depend on each output before cutover.
Authentication gaps after cutover
Windows logins and Active Directory groups that connected to SQL Server have no direct one-to-one equivalent in PostgreSQL. PostgreSQL offers methods such as GSSAPI, SSPI, LDAP and certificate authentication, and access is granted through database roles. Map each login and group to a role, decide how service accounts authenticate, and use SCRAM password authentication for any password-based access, since PostgreSQL 18 deprecates MD5. Confirm the chosen method with your identity team.
Unrehearsed rollback and backup gaps
A cutover plan without a tested way back is effectively a one-way move. Rehearse the rollback at least once on a copy of production, including switching application connection strings and deciding how writes made on PostgreSQL are reconciled. Point-in-time recovery depends on a base backup and archived WAL files, so confirm archiving is running and time a full restore before the cutover window.
Connection spikes at cutover
At cutover, the application, batch jobs and reporting tools often open connections at the same moment, and PostgreSQL starts a separate server process for each connection. Place PgBouncer in front of the database, choose a pool mode that matches how the application uses transactions, and set limits per application. Keep the pooler patched: PgBouncer 1.26.1, released October 14, 2026, includes security fixes, so schedule that upgrade into the cutover runbook.
What changes for your teams and what we need from you before work starts
The largest change for your DBAs and developers is the database language itself. T-SQL stored procedures, functions and triggers do not run unchanged on PostgreSQL, so each one needs a decision: convert it to PL/pgSQL, move the logic into the application, or retire it. DBAs will work with psql, pg_dump and pg_restore in place of SSMS, and they will need to decide where SQL Server Agent jobs run after cutover, whether that is cron, a scheduler or an orchestration tool. Developers should expect unquoted identifiers to fold to lowercase, identity columns to be defined differently, and string handling, date arithmetic and paging syntax to vary. Ask your team which of these patterns appear most often in your code, because that frequency drives the rewrite effort.
Application owners see the change at the connection boundary. Each application needs a PostgreSQL driver, a revised connection string, and a review of how its ORM or data access layer generates SQL. Default transaction isolation, error codes and the way a failed statement ends an open transaction can change application behavior in ways that SQL Server test suites may not have exercised. If you plan to use PgBouncer for connection pooling, agree the pooling mode with each owner, because session-level features behave differently under transaction pooling. Each application needs one named owner who approves functional results, performance expectations and the rollback path, and who answers for that application's SQL during testing and cutover.
Security and operations teams will set up access control and monitoring largely from scratch. PostgreSQL client authentication is configured in pg_hba.conf and supports methods such as password, certificate, GSSAPI, SSPI, LDAP and PAM, so confirm which method matches your directory and how existing SQL Server logins map to database roles. Windows integrated authentication maps to SSPI or GSSAPI depending on the host platform, so confirm the method for each server. Operations will own base backups with archived WAL files for point-in-time recovery, the standby design, alert thresholds and log retention. Review audit logging requirements now, because PostgreSQL logging and extensions differ from SQL Server Audit, and agree the approved extension list with your security team before the build starts.
Before work starts, we need read access to SQL Server metadata, including the catalog views for schemas, tables, indexes, keys, constraints, routines, triggers and agent jobs, so the assessment covers every schema in scope. We also need sample data that reflects real production patterns, test data that exercises your business logic, and reconciliation data such as row counts, checksums and control totals that prove the migrated data matches the source. Name one owner for each application, with authority to approve test results. Provide the change windows in which downtime is permitted, the rollback point you can accept, and the security requirements that apply to data in transit, data at rest and privileged access.
Cutover sign-off criteria shape the written scope as much as the code does. Ask your change board to define what counts as a pass, including reconciliation thresholds, acceptable performance and the conditions for rollback. Those answers decide whether cutover is a single offline window or a phased move with replication running, and that choice changes build, test and support effort. We use these inputs to write the scope, deliverables and timeline before any migration work begins, and we ask you to confirm them in writing. Gaps found during scoping are usually cheaper to close than gaps found after the first test cycle, so treat this list as a gating step rather than paperwork.
Questions buyers ask before hiring help with a SQL Server migration
How much does a SQL Server to PostgreSQL migration cost?
The cost depends on the written scope, so a quote follows once that scope is agreed. The main drivers are the number of databases, their size, and the number of stored procedures, functions, triggers and views that need manual rewriting from T-SQL to PL/pgSQL. Application query changes, the number of environments, test effort and the cutover plan also add work. Most of the cost is one-time: assessment, conversion, data loading, testing and cutover. Recurring costs begin after go-live and include the staff, backup, monitoring and any support retainer needed to run PostgreSQL. Ask each quote to separate one-time work from recurring work and to state which application changes are included.
How long does a SQL Server migration to PostgreSQL take?
Duration is set mainly by the amount of code to rewrite and the testing needed to prove it works, not by row count alone. Data copy time matters for large databases, but it is usually shorter than the time spent on object conversion and validation. A phased cutover, where databases or applications move in groups, takes longer to plan but limits the risk of one large switch. Dependencies on application teams, change freeze windows and approval cycles also set the timeline. Ask for milestones tied to scope items, the named dependencies on your side, and the test exit criteria that close each phase.
What does our team need to provide before a migration starts?
The work needs access and decisions from your side before the first conversion run. Expect to provide read access to the SQL Server instances, a schema export or inventory of databases, and a list of applications and their database connections. You will also need sample workloads, named business owners who can sign off test results, and a network path between the source and the target. Your team should confirm the target environment, the PostgreSQL version, change windows, and the security approvals required for new servers. Missing items usually show up as delays during testing, so list them in the statement of work and assign an owner to each one.
Can our internal database team migrate SQL Server to PostgreSQL alone?
Yes, an internal team can do the migration alone if it has PostgreSQL operating experience, time for the code rewrite, and enough testing capacity. The team must understand the differences between T-SQL and PL/pgSQL, how data types, collations and identity columns map, and how the applications use the database. The largest risks are usually incomplete testing and unplanned cutover steps, not the tooling. Many teams hire a partner for the assessment, the rewrite plan or the cutover rehearsal, and keep application and business testing in-house. Compare the internal estimate with a quote built from the same written scope so the two options are measured on equal terms.
Does pgloader convert every SQL Server object automatically?
No. pgloader discovers and migrates tables, indexes, keys and the table data, which covers a large part of the schema work. Stored procedures, functions, triggers, views with T-SQL-specific logic and other procedural code must be rewritten by hand. Some data types, collations and default expressions also need checking after load. Plan validation as a separate step: compare row counts, sample key values, constraints and checksums, then run the application test suite against the target. Confirm the exact object types in your source database during assessment, because a single unsupported construct can block a cutover.
Which PostgreSQL version should we target for a migration?
Target a major version that is still supported on the planned go-live date. According to the PostgreSQL versioning policy, version 18 was first released on September 25, 2025 and is supported until November 14, 2030, with version 17 supported until November 8, 2029, version 16 until November 9, 2028, and version 15 until November 11, 2027. Version 14 is supported until November 12, 2026, so choosing it means planning an upgrade soon after go-live. Versions 13 and earlier are unsupported. Also check that your drivers, extensions and client libraries support the chosen version, and factor in how long your application will stay on that release.
How much SQL Server licensing will we save by moving?
PostgreSQL is released under the PostgreSQL License, a liberal open source license similar to the BSD and MIT licenses, so there is no per-core database license fee to pay. The savings you actually realize depend on your current Microsoft agreement, the SQL Server editions you run, whether licenses are perpetual or under Software Assurance, and when those agreements renew. Offset those savings against the cost of running PostgreSQL yourself, including staff time, high availability, backup testing, monitoring and any support retainer. Confirm the licensing position with your Microsoft licensing advisor or procurement team before you set a business case.
How is compliance evidence produced during a migration?
DeployOpen prepares systems, controls and evidence for compliance assessments, but it does not issue audit reports, attestations or certifications. Independent auditors and certification bodies perform those assessments. During a migration, evidence usually includes access control configuration, audit logging settings, change records, backup and restore test results, and records of data validation after each load. Agree early which control framework and assessor apply, because they decide which evidence the auditor expects. Confirm with your assessor how they want the evidence packaged and retained before the cutover, so the records are collected as the work happens.
How DeployOpen scopes, delivers and supports the migration
DeployOpen plans, implements, tests and documents SQL Server to PostgreSQL migrations inside your own cloud accounts, data centers or air-gapped networks. Work is agreed as a fixed-scope engagement, with the scope, deliverables and timeline set in writing before any migration work starts, so the scope is clear to both sides.
How we scope
- Inventory of SQL Server databases, schemas, tables, indexes, keys and the T-SQL objects each application calls.
- Written scope naming the databases that move, the T-SQL objects rewritten by hand and exclusions.
- Fixed-scope agreement, with ongoing support available as a retainer after cutover if you want it.
How we build
- pgloader-based schema and data load, with type mapping reviewed against each SQL Server column type before the first run.
- T-SQL stored procedures, functions, triggers and views rewritten by hand into PL/pgSQL and tested against the same inputs.
- Row counts, checksums and sample-based comparisons run between SQL Server and PostgreSQL after each load rehearsal.
How we hand over
- Runbook for the phased cutover: order of table loads, freeze window, sequence resets and rollback steps.
- Migration report listing converted objects, manual rewrites, open issues and the data validation results.
- Application connection, driver and query changes documented for your developers, including differences in SQL behavior.
How we support
- Post-cutover monitoring plan covering PostgreSQL logs, slow query review and connection pool sizing with PgBouncer.
- Backup and point-in-time recovery set up and tested on the new PostgreSQL cluster before SQL Server is retired.
- Optional retainer for patching, minor-version updates and planned major upgrades after the migration is complete.

