Skip to content

Journal/ Databases/ PostgreSQL/ MySQL

PostgreSQL vs MySQL for web applications

Comparing PostgreSQL and MySQL for Laravel and web apps — data types, JSON, constraints, search, hosting and when to choose each.

Published
Reading time
3 min read

I work with both MySQL and PostgreSQL, and the honest answer to “which is better?” is that both are excellent for typical web applications. The differences matter at the edges — and it helps to know where those edges are before you start.

The short version

  • Choose MySQL when you need the widest hosting compatibility, your team already knows it well, and your data is conventional relational data.
  • Choose PostgreSQL when you want stricter data integrity, richer data types, advanced querying, or you expect complex reporting.

For a standard Laravel CRUD application, either will serve you well for years.

Availability and hosting

MySQL (and its fork MariaDB) is available on almost every shared hosting plan, which still matters for many small business projects. PostgreSQL is standard on VPS setups and managed database services, but less common on cheap shared hosting.

If a client’s project must run on existing shared hosting, that often decides the question before anything else.

Strictness and data integrity

PostgreSQL is strict by default. Insert a string that’s too long, or an invalid date, and it rejects the write.

Modern MySQL (8.x) is much stricter than older versions when STRICT_TRANS_TABLES is enabled, which it is by default — but it’s worth checking, because some hosts turn strict mode off. Without it, MySQL may silently truncate values.

PostgreSQL also has features that help keep data correct:

  • CHECK constraints that have long been enforced (MySQL only enforces them from 8.0.16).
  • Partial indexes, such as a unique constraint only for active records:
CREATE UNIQUE INDEX users_email_active
    ON users (email)
    WHERE deleted_at IS NULL;

That’s useful with Laravel soft deletes, where you want an email to be unique only among non-deleted users.

Data types

PostgreSQL has a richer type system: native UUID, arrays, ranges, INET for IP addresses, JSONB and proper BOOLEAN. MySQL covers the common cases (and has a JSON type), but with fewer specialised options.

JSON

Both support JSON columns, and Laravel’s query builder works with both:

User::where('preferences->notifications->email', true)->get();

PostgreSQL’s JSONB is stored in a binary format and can be indexed with GIN indexes, which makes querying inside JSON documents fast. MySQL can index JSON through generated columns. If you rely heavily on semi-structured data, PostgreSQL has the edge.

Both have built-in full-text search. PostgreSQL’s (tsvector, tsquery) is more configurable, with ranking and language-aware stemming. MySQL’s FULLTEXT indexes are simpler to set up.

For serious product search in an e-commerce store, though, I’d look at a dedicated tool (Meilisearch, Typesense or similar via Laravel Scout) rather than either database.

Reporting and complex queries

Both databases support window functions and common table expressions (MySQL since 8.0). PostgreSQL’s query planner tends to handle complex analytical queries — many joins, subqueries, aggregates — very well, and features like FILTER clauses make reports cleaner:

SELECT
    date_trunc('day', created_at) AS day,
    count(*) FILTER (WHERE status = 'completed') AS completed,
    count(*) FILTER (WHERE status = 'cancelled') AS cancelled
FROM orders
GROUP BY 1
ORDER BY 1;

For business systems with heavy reporting — POS, inventory, MIS — that’s a real advantage.

Case sensitivity: a Laravel gotcha

String comparison in MySQL is usually case-insensitive with default collations; in PostgreSQL it’s case-sensitive. So this query behaves differently:

User::where('email', '[email protected]')->first();

When moving an app from MySQL to PostgreSQL, normalise values (for example, lower-case emails on save) or use ILIKE / lower() comparisons.

Migrating between them

Laravel’s schema builder hides most differences, but watch for raw SQL, MySQL-specific functions, ENUM columns, zero dates (0000-00-00) and case-sensitivity assumptions. Run the full test suite against the target database before switching.

My default

For a new application on infrastructure I control, especially one with complex data or reporting, I lean towards PostgreSQL. For projects that must run on standard shared hosting, or teams deeply familiar with MySQL, MySQL 8 is a perfectly solid choice.

The bigger decision is good schema design — clear relationships, proper constraints and sensible indexes. A well-designed schema on either database beats a poorly designed one on the “right” database every time.

Related projects

Technologies

  • Databases
  • PostgreSQL
  • MySQL
rupesh@np
--:-- NPT
Esc