DEV Community

Cover image for PostgreSQL vs MySQL vs SQL Server: Enterprise Database Decision Guide
Philip McClarence
Philip McClarence

Posted on

PostgreSQL vs MySQL vs SQL Server: Enterprise Database Decision Guide

PostgreSQL vs MySQL vs SQL Server: The Enterprise Database Decision, Made on Technical Merit

Every enterprise database evaluation lands on the same shortlist: PostgreSQL, MySQL, and SQL Server. The problem is that the decision is usually made based on organizational inertia -- what a consultant recommended in 2015, or which database the senior architect used at their previous company -- rather than current technical merit.

The three databases have diverged significantly in recent years. PostgreSQL has added parallel query execution and a mature extension ecosystem, SQL Server has moved to Linux, and MySQL has closed long-standing feature gaps with version 8. The landscape is materially different from even three years ago.

This is the technical comparison I wish someone had handed me before my last procurement cycle. Concrete differences, real cost numbers, and clear guidance on when each database is the right choice.

Licensing and Cost: The Elephant in the Room

Before discussing any technical feature, let us talk about the number that dominates every enterprise database decision: licensing cost.

SQL Server licensing is complex and expensive. Enterprise Edition runs approximately $15,123 per two-core pack (retail). A typical 16-core production server requires 8 core packs: $120,984 in licensing alone. Standard Edition is cheaper at roughly $3,945 per two-core pack ($31,560 for 16 cores), but it caps memory at 128GB and limits many Enterprise features. Add Software Assurance (roughly 25% annually for updates and support), and you are paying $30,000-$40,000 per year just to keep the lights on for a single server. A primary plus two replicas? Triple those numbers.

PostgreSQL is free. Completely, irrevocably, no-strings-attached free under the PostgreSQL License. There is no Enterprise Edition with features held back. Every feature -- logical replication, parallel query, partitioning, full-text search -- is included. Your costs are hardware, hosting, and operational expertise. For that same 16-core server: $0 in licensing.

MySQL is also free under the GPL, but with an asterisk. Oracle owns MySQL and offers a commercial Enterprise Edition ($5,000-$10,000 per server per year) with additional monitoring tools, backup utilities, and security features. The Community Edition is fully functional, but Oracle's ownership creates strategic uncertainty that makes some enterprise procurement teams nervous. For that 16-core server: $0 for Community, $5,000-$10,000 for Enterprise.

Here is the concrete math for a modest production deployment (primary + 2 read replicas, 16 cores each):

Cost Component SQL Server Enterprise PostgreSQL MySQL Community
License (3 servers) $362,952 $0 $0
Annual maintenance/SA $90,738 $0 $0
Support contract Included in SA ~$15,000 (third-party) ~$10,000 (third-party)
Year 1 total $453,690 ~$15,000 ~$10,000
Year 2+ annual $90,738 ~$15,000 ~$10,000

SQL Server's total cost of ownership over five years approaches $800,000 for this configuration. The same hardware running PostgreSQL costs roughly $75,000 in support contracts. That delta funds a full-time DBA with budget left over.

SQL Standard Compliance

If you care about writing portable, standards-compliant SQL -- and you should, because it reduces vendor lock-in and makes hiring easier -- the three databases differ meaningfully.

PostgreSQL is the most SQL-standard-compliant relational database available. It implements the majority of SQL:2023, including advanced features like MERGE, lateral joins, GROUPING SETS, CUBE, and ROLLUP. When PostgreSQL deviates from the standard, it is typically to add functionality, not to omit it.

SQL Server implements T-SQL, Microsoft's proprietary extension of standard SQL. T-SQL adds useful features (variables, control flow, error handling via TRY...CATCH), but it also introduces non-standard behavior that creates lock-in. TOP instead of LIMIT, ISNULL() instead of COALESCE() (though it supports both), += assignment operators, and proprietary date functions are endemic in T-SQL codebases. The code works, but it only works on SQL Server.

MySQL has the most idiosyncratic SQL behavior of the three. Historically, its GROUP BY behavior was non-standard -- you could SELECT columns not in the GROUP BY clause without an aggregate function, and MySQL would silently return an arbitrary value from the group. MySQL 8 defaults to ONLY_FULL_GROUP_BY mode, but legacy applications may depend on the old behavior. Other surprises:

  • String comparisons are case-insensitive by default (collation utf8mb4_0900_ai_ci), which catches every developer migrating from PostgreSQL or SQL Server
  • TRUNCATE TABLE does an implicit commit and cannot be rolled back, even inside a transaction
  • Division by zero returns NULL instead of raising an error (unless strict mode is enabled)
  • TIMESTAMP columns auto-update on row modification unless explicitly told not to
-- MySQL's default case-insensitive comparison
SELECT * FROM users WHERE username = 'Admin';
-- Returns rows where username is 'admin', 'ADMIN', 'Admin', etc.

-- PostgreSQL: case-sensitive by default
SELECT * FROM users WHERE username = 'Admin';
-- Returns ONLY rows where username is exactly 'Admin'

-- SQL Server: depends on collation (default is case-insensitive)
SELECT * FROM users WHERE username = 'Admin';
-- Default collation: returns 'admin', 'ADMIN', 'Admin', etc.
Enter fullscreen mode Exit fullscreen mode

Advanced SQL Features

This is where the three databases diverge most sharply. The following table summarizes support for features that matter in real applications:

Feature PostgreSQL SQL Server MySQL
CTEs (WITH) Full optimization, materialized/not materialized hints Full support Supported (8.0+), less optimized
Recursive CTEs Yes, with cycle detection Yes Yes (8.0+)
Window functions Complete (GROUPS, EXCLUDE, FILTER) Complete (most features) Basic (no GROUPS, no EXCLUDE)
JSONB / JSON Binary JSONB with GIN indexing JSON with computed column indexing JSON with generated column indexing
Full-text search Built-in (tsvector, ranking, stemming) Built-in (excellent, with thesaurus) Basic (InnoDB FTS, no stemming)
Geospatial PostGIS (industry standard) Spatial types (basic) Spatial types (basic)
Array types Native No No
Range types Native with exclusion constraints No No
Lateral joins Yes CROSS APPLY / OUTER APPLY Yes (8.0.14+)
MERGE statement Yes (15+) Yes (mature) No (use INSERT...ON DUPLICATE KEY)
Partial indexes Yes Filtered indexes No
Generated columns Stored and virtual Computed columns (persisted/virtual) Stored and virtual (8.0+)
Table partitioning Declarative (range, list, hash) Partition functions/schemes Declarative (range, list, hash, key)
Parallel queries Full (scans, joins, aggregates) Full (extensive parallelism) Limited (COUNT, some reads)

PostgreSQL and SQL Server are roughly comparable in feature richness. Both handle complex analytical workloads well. MySQL lags behind in areas that matter for enterprise applications -- limited window functions, no array or range types, weaker JSON indexing, and minimal parallel query support.

Stored Procedures and Programmability

All three databases support stored procedures, but the languages differ meaningfully.

SQL Server (T-SQL) has the most mature procedural language. Variables, control flow, structured error handling (TRY...CATCH), and CLR integration for .NET code running inside the database. T-SQL is a complete programming environment:

-- T-SQL: Structured error handling
CREATE PROCEDURE CalculateAccountBalance @AccountId INT, @AsOfDate DATE
AS
BEGIN
    BEGIN TRY
        SELECT account_id, SUM(CASE WHEN transaction_type = 'credit'
            THEN amount ELSE -amount END) AS balance
        FROM transactions
        WHERE account_id = @AccountId AND transaction_date <= @AsOfDate
        GROUP BY account_id;
    END TRY
    BEGIN CATCH
        THROW;
    END CATCH
END;
Enter fullscreen mode Exit fullscreen mode

PostgreSQL (PL/pgSQL) is similarly capable, with the unique advantage of supporting multiple procedural languages -- PL/Python, PL/Perl, PL/V8 (JavaScript):

-- PL/pgSQL: Function returning a table
CREATE OR REPLACE FUNCTION calculate_account_balance(
    target_account_id INT, as_of_date DATE
) RETURNS TABLE(account_id INT, balance NUMERIC)
LANGUAGE plpgsql AS $$
BEGIN
    RETURN QUERY
    SELECT t.account_id, COALESCE(SUM(CASE WHEN t.transaction_type = 'credit'
        THEN t.amount ELSE -t.amount END), 0.00)
    FROM transactions t
    WHERE t.account_id = target_account_id AND t.transaction_date <= as_of_date
    GROUP BY t.account_id;
END; $$;
Enter fullscreen mode Exit fullscreen mode

MySQL stored procedures (since 5.0) are functional but less refined. Error handling is verbose, and there is no equivalent to PostgreSQL's multi-language support or SQL Server's CLR integration.

Replication and High Availability

High availability is where SQL Server's premium licensing starts to justify its cost -- for organizations that value turnkey HA over operational flexibility.

SQL Server Always On AG is the gold standard for turnkey HA. Synchronous or asynchronous replication, automatic failover (under 30 seconds), readable secondaries, and GUI-driven configuration through Management Studio. The catch: it requires Enterprise Edition. A three-node AG cluster on 16-core servers exceeds $360,000 in licensing.

PostgreSQL offers streaming replication (WAL-level, near-real-time) and logical replication (row-level, enabling selective table replication and zero-downtime major version upgrades). Failover is managed by external tools -- Patroni is the industry standard. The result is highly flexible and free, but requires more operational expertise than SQL Server's integrated approach.

MySQL Group Replication provides multi-primary or single-primary clustering with automatic failover. Combined with MySQL Router and MySQL Shell, InnoDB Cluster is relatively turnkey. The limitation: all tables must have primary keys, and only InnoDB is supported. Group Replication is newer and less battle-tested than the other two options.

Platform Support

SQL Server was Windows-only until 2017. SQL Server on Linux is now generally available and production-ready, but with gaps: SQL Server Agent (job scheduling), SSIS (ETL), SSRS (reporting), and SSAS (analysis services) do not run on Linux. If your organization depends on the BI stack, you still need Windows servers. SQL Server on containers (Docker/Kubernetes) works, but it is not yet the norm for production deployments.

PostgreSQL runs everywhere -- Linux, Windows, macOS, FreeBSD, and Solaris. It is the default relational database on every major cloud platform (AWS RDS/Aurora, GCP Cloud SQL/AlloyDB, Azure Database for PostgreSQL). The overwhelming majority of production deployments run on Linux. Container support is excellent and widely adopted.

MySQL also runs everywhere and is well-supported across all cloud platforms. Like PostgreSQL, most production deployments target Linux.

Extensions and Ecosystem

PostgreSQL Extensions

PostgreSQL's extension system is its strongest differentiator. Extensions run inside the database engine with full access to the query planner, index system, and storage layer:

  • PostGIS: The industry-standard spatial database. Used by government agencies, logistics companies, and mapping platforms. Supports 2D/3D geometries, raster data, topology, and geocoding
  • TimescaleDB: Hypertables, columnar compression, continuous aggregates, and retention policies for time-series data
  • pgvector: Vector similarity search for AI/ML embeddings alongside relational data
  • pg_cron: In-database job scheduling
  • pg_stat_statements: Normalized query performance tracking
  • pg_trgm: Fuzzy string matching with index support
  • Citus: Distributed PostgreSQL for horizontal scaling

These extensions are not wrappers or plugins. They extend the core engine. PostGIS adds new data types, index types, and hundreds of spatial functions that the query planner understands natively.

SQL Server Built-In Features

SQL Server takes a different approach: instead of extensions, Microsoft builds features directly into the product. SSIS (ETL), SSRS (reporting), SSAS (OLAP/data mining), Query Store, In-Memory OLTP, and built-in spatial types all ship with the product or as companion tools. The approach is "batteries included" -- everything comes from one vendor, integrates tightly, and is supported under one contract. The tradeoff is that you are locked into Microsoft's implementation and roadmap.

MySQL Extensibility

MySQL's plugin architecture is more limited. There are storage engine plugins (InnoDB, NDB for clustering), authentication plugins, and audit plugins, but nothing comparable to PostGIS or TimescaleDB. If you need spatial analytics, vector search, or time-series capabilities, MySQL requires a separate specialized database.

Monitoring and Observability

Monitoring is an area where SQL Server has a genuine, meaningful advantage that PostgreSQL's ecosystem is still catching up to.

SQL Server Query Store

Query Store is SQL Server's standout monitoring feature. It automatically captures query plans, tracks plan changes over time, identifies regressions, and can force a specific plan for a query that has regressed. This is built into the engine, enabled with a single toggle, and integrated with Management Studio. Combined with Dynamic Management Views (DMVs) for wait statistics, index usage, buffer pool contents, and lock analysis, SQL Server's observability comes out of the box with every edition.

PostgreSQL Monitoring

PostgreSQL exposes its internals through system catalog views -- pg_stat_statements for query performance, pg_stat_activity for live sessions, pg_stat_user_tables for table I/O and vacuum statistics, pg_locks for lock analysis. The auto_explain extension captures execution plans for slow queries automatically.

The raw data is excellent, but PostgreSQL lacks SQL Server's integrated tooling for plan regression detection and automated remediation. This is where ecosystem tools fill the gap. For PostgreSQL, tools like myDBA.dev provide the automated health checks, query plan analysis, and tuning recommendations that SQL Server's Query Store offers natively -- bridging the monitoring gap with EXPLAIN plan capture, plan regression detection, and index advisory across your PostgreSQL fleet.

myDBA.dev dashboard showing health score, active connections, query performance trends, and replication status

Query monitoring page showing EXPLAIN plans, performance trends, and plan regression detection

MySQL Monitoring

MySQL's Performance Schema provides query digests, wait event analysis, and memory instrumentation. It is functional but carries a measurable overhead (typically 5-10%) and the schema is more complex to query directly than either SQL Server's DMVs or PostgreSQL's pg_stat views.

Migration Considerations

The most common enterprise migration path today is SQL Server to PostgreSQL, driven by licensing cost reduction. Key tools:

  • pgLoader: Open-source, migrates from MySQL or SQL Server to PostgreSQL with schema translation and data type mapping
  • AWS DMS: Continuous replication from SQL Server or MySQL to PostgreSQL, including change data capture
  • AWS Babelfish for Aurora PostgreSQL: T-SQL compatibility layer that lets SQL Server applications connect to Aurora PostgreSQL and execute T-SQL natively. Not 100% compatible, but it covers a large T-SQL subset and can dramatically reduce migration effort
  • SQL Server Migration Assistant (SSMA): Microsoft's free tool for migrating from MySQL or Oracle to SQL Server

Babelfish is the most significant development here -- it allows organizations to migrate their database to PostgreSQL while deferring the T-SQL stored procedure rewrite, which is typically the most expensive part of the project.

When to Choose Each Database

Choose SQL Server When:

  • You are a Microsoft/.NET shop. The integration with Visual Studio, Azure, and Entity Framework is genuinely excellent
  • You need the BI suite. SSIS + SSRS + SSAS is a mature, integrated business intelligence stack with no PostgreSQL equivalent
  • Turnkey HA matters more than cost. Always On AG is the easiest enterprise HA to configure and operate
  • You have existing licenses. Software Assurance makes the marginal cost of additional instances lower than sticker price

Choose PostgreSQL When:

  • Cost matters. Deploying multiple production servers saves hundreds of thousands in licensing
  • You are cloud-native or Linux-first. PostgreSQL is the default on every major cloud platform
  • You need extensions. PostGIS, TimescaleDB, pgvector -- no other relational database handles geospatial, time-series, and vector search natively
  • Data integrity is non-negotiable. CHECK, EXCLUDE, partial indexes, deferrable foreign keys, and range types provide guardrails neither SQL Server nor MySQL can match
  • You want one database, not five. Extensions replace separate spatial, time-series, vector, and document databases

Choose MySQL When:

  • WordPress, Drupal, or legacy PHP. The ecosystem assumes MySQL
  • Simple CRUD at high concurrency. The thread model handles thousands of connections natively
  • Horizontal scaling with Vitess or PlanetScale. MySQL-compatible distributed databases are more mature for certain sharding patterns
  • Team expertise. A team that knows MySQL deeply will outperform during the learning curve

Comprehensive Comparison Table

Category PostgreSQL SQL Server MySQL
License PostgreSQL (free, permissive) Commercial ($15K+ per 2-core pack) GPL (free) / Commercial
Owner Community (PGDG) Microsoft Oracle
SQL compliance Most compliant T-SQL extensions Idiosyncratic defaults
Connection model Process-per-connection Thread-per-connection Thread-per-connection
Parallel queries Full (scans, joins, aggregates) Full (extensive) Limited
CTEs / recursive Full, optimized Full Supported (8.0+)
Window functions Complete Complete Basic
JSON support JSONB (binary, GIN indexed) JSON (computed columns) JSON (generated columns)
Geospatial PostGIS (industry standard) Built-in (basic) Built-in (basic)
Full-text search Built-in (stemming, ranking) Built-in (excellent) Basic
Vector search pgvector Preview (2025+) No
Time-series TimescaleDB Temporal tables No
Array / range types Native No No
Partial indexes Yes Filtered indexes No
Stored procedures PL/pgSQL + multi-language T-SQL + CLR MySQL procedures
Replication Streaming + logical Always On AG Group Replication
HA complexity External tools (Patroni) Integrated (WSFC) MySQL Router/Shell
Built-in monitoring pg_stat_* views DMVs + Query Store Performance Schema
Plan regression detection Ecosystem tools Query Store (built-in) No
Platform support All major OS Windows + Linux (gaps) All major OS
Extension ecosystem Rich (PostGIS, TimescaleDB, etc.) SSIS/SSRS/SSAS suite Limited plugins
Cloud managed options All major clouds Azure, AWS RDS All major clouds
Container support Excellent Supported (less common) Excellent

The Bottom Line

The enterprise database decision should not be difficult if you separate technical merit from organizational inertia.

SQL Server is the right choice when you are already invested in the Microsoft ecosystem, need the BI suite, and the licensing cost is acceptable. Its integrated tooling -- Query Store, Always On, SSRS -- is genuinely excellent and saves operational effort. Do not underestimate the value of a single vendor supporting your entire data stack.

PostgreSQL is the right choice when cost matters, when you need capabilities beyond basic relational storage, and when you want to avoid vendor lock-in. The extension ecosystem transforms it from a relational database into a platform -- spatial, time-series, vector search, and document storage in a single engine. The monitoring gap that existed five years ago has been largely closed by ecosystem tools.

MySQL is the right choice for simple web workloads, PHP ecosystems, and teams with deep MySQL expertise. It is not the right choice for new enterprise applications that will grow in complexity.

If you are starting a new enterprise project today with no existing constraints, PostgreSQL gives you the broadest capability at the lowest cost. If you choose it, invest the licensing savings in operational expertise and monitoring -- the database is free, but running it well requires the same rigor as any production system.

Top comments (0)