SQLite vs PostgreSQL vs MySQL

Use SQLite when one process owns modest writes, PostgreSQL for concurrent writers and extensions, MySQL or MariaDB for online schema changes, and DuckDB for analytics.

Providers
5
Fields compared
26
Source confidence
62%
Last verified
2026-07-01 (2mo ago)
Re-verified
every 30 days
Data confidence0% of 126 figures verified in the last 30d
98sourced of 126126stale, oldest 2mo ago
5 tools · verified 2mo ago
DuckDB logoDuckDBIn-process columnar analytics engine, SQLite's shape, a warehouse's execution model.

Engine & SQL

Embedded or server
Embedded (in-process)
Concurrency model
MVCC (single process)
Write concurrency
Single writer
Isolation levels
Snapshot
JSON support
Text functions only
Full-text search
Extension
Vector search
Extension
Type strictness
Static, strict
ALTER TABLE
Moderate
Max database size

Operations

Replication
None
PITR
No
Online schema change
No
Connection model
In-process (no connections)
Default max conns
Managed options
MotherDuck
Ops burden
1

Ecosystem

Extension ecosystem
4
Client libraries
3
Migration tooling
2
GitHub stars
33,000
Positioning
DuckDB is a fast in-process analytical database.

Licence & governance

Licence
MIT
Embed in closed source
Yes
Governance
Foundation

History

First release
2019-06-26
MariaDB logoMariaDBGPL-only MySQL fork under a foundation, with Galera clustering and native vectors.

Engine & SQL

Embedded or server
Both
Concurrency model
MVCC (undo log)
Write concurrency
Concurrent writers (row-level)
Isolation levels
Read uncommittedRead committed+2
JSON support
Text functions only
Full-text search
Built-in
Vector search
Native type + ANN index
Type strictness
Static, coercing
ALTER TABLE
Moderate
Max database size
64TB

Operations

Replication
Built-in async + synchronous
PITR
Yes
Online schema change
Yes
Connection model
Thread per connection
Default max conns
151
Managed options
Amazon RDSGoogle Cloud SQL+1
Ops burden
3

Ecosystem

Extension ecosystem
3
Client libraries
4
Migration tooling
3
GitHub stars
6,000
Positioning
The open source relational database, made by the original developers of MySQL.

Licence & governance

Licence
GPL-2.0
Embed in closed source
Partial
Governance
Foundation

History

First release
2009-10-29
MySQL logoMySQLThe relational server that ran the early web, now Oracle-stewarded and InnoDB-based.

Engine & SQL

Embedded or server
Server (client/server)
Concurrency model
MVCC (undo log)
Write concurrency
Concurrent writers (row-level)
Isolation levels
Read uncommittedRead committed+2
JSON support
Binary JSON type
Full-text search
Built-in
Vector search
Native type
Type strictness
Static, coercing
ALTER TABLE
Moderate
Max database size
64TB

Operations

Replication
Built-in async + synchronous
PITR
Yes
Online schema change
Yes
Connection model
Thread per connection
Default max conns
151
Managed options
Amazon RDSAmazon Aurora+3
Ops burden
3

Ecosystem

Extension ecosystem
2
Client libraries
5
Migration tooling
4
GitHub stars
11,000
Positioning
The world's most popular open source database.

Licence & governance

Licence
GPL-2.0 or commercial
Embed in closed source
No
Governance
Single vendor

History

First release
1995-05-23
PostgreSQL logoPostgreSQLMVCC relational server with the widest SQL surface and a deep extension ecosystem.

Engine & SQL

Embedded or server
Server (client/server)
Concurrency model
MVCC (heap row versions)
Write concurrency
Concurrent writers (row-level)
Isolation levels
Read committedRepeatable read+1
JSON support
Binary JSONB + indexes
Full-text search
Built-in
Vector search
Extension
Type strictness
Static, strict
ALTER TABLE
Minimal
Max database size

Operations

Replication
Built-in async + synchronous
PITR
Yes
Online schema change
Partial
Connection model
Process per connection
Default max conns
100
Managed options
NeonSupabase+5
Ops burden
4

Ecosystem

Extension ecosystem
5
Client libraries
5
Migration tooling
5
GitHub stars
18,000
Positioning
The world's most advanced open source relational database.

Licence & governance

Licence
PostgreSQL Licence (BSD-style)
Embed in closed source
Yes
Governance
Community project

History

First release
1997-01-29
SQLite logoSQLiteEmbedded SQL engine that runs inside your process, a file, not a server.

Engine & SQL

Embedded or server
Embedded (in-process)
Concurrency model
Reader/writer locking
Write concurrency
Single writer
Isolation levels
Serializable
JSON support
Text functions only
Full-text search
Extension
Vector search
Extension
Type strictness
Dynamic (per-value)
ALTER TABLE
Severe (rebuild required)
Max database size
256TB

Operations

Replication
Third-party only
PITR
Partial
Online schema change
No
Connection model
In-process (no connections)
Default max conns
Managed options
TursoCloudflare D1+1
Ops burden
1

Ecosystem

Extension ecosystem
4
Client libraries
5
Migration tooling
3
GitHub stars
8,000
Positioning
Small. Fast. Reliable. Choose any three.

Licence & governance

Licence
Public domain
Embed in closed source
Yes
Governance
Independent team

History

First release
2000-08-17
yespartialnounknown
Sources shown beside each value · Learn how sourcing works
measured vendor-claimed community inferredExpand any row for the source, verification date, and caveat behind every cell.

Where each one wins

  • One application process, or one machine, owning the data
  • Read-heavy workloads where removing the network hop is the whole win
  • Anything shipped to the edge, a device, a CLI or a test suite

Best when one process owns the data; limits are single writer, no replication and painful schema changes.

  • Concurrent writers plus queries that outgrow simple key lookups
  • Anything storing embeddings, geometry or time series alongside rows
  • Teams who will run it managed, or who have someone who wants to own it

Strongest engine on every axis except operational cost; nothing else pairs transactional DDL, this much SQL and pgvector.

  • Very large tables that must be altered without downtime
  • Read-replica topologies your team has already run before
  • Environments where the host, ORM or ops runbook already assumes MySQL

Underused for its strength, altering an enormous table while writes continue; narrower SQL, but a well-worn operational path.

  • MySQL-shaped workloads where GPL-only licensing or Oracle stewardship is a blocker
  • Synchronous multi-primary clustering without buying anything
  • Vector search inside a MySQL dialect you can self-host

MySQL without Oracle, plus Galera clustering and native vectors ahead of MySQL; smaller ecosystem and growing compatibility drift.

  • Aggregation and scans over columns rather than fetching rows by key
  • Querying Parquet, CSV or object storage without an ingestion pipeline
  • The reporting half of a system whose rows live in Postgres or SQLite

The analytical contrast, included so the others are legible; superb over Parquet, but never a system of record.

Should I use SQLite, PostgreSQL or MySQL?

  • This page has no score column, and never will.
  • Other toolweight comparisons rank vendors selling the same thing at different prices.
  • These five are engines with different shapes, not competitors.
  • SQLiteSQLite logo is a file format with a query planner attached.
  • PostgreSQLPostgreSQL logo is a process-per-connection MVCC server.
  • MySQLMySQL logo and MariaDBMariaDB logo are thread-per-connection MVCC servers tuned for replication.
  • DuckDBDuckDB logo is a columnar analytics engine that happens to speak SQL.
  • Weighting them would say more about the weights than the engines.
  • So the table is descriptive, and the decision lives in prose.
  • PostgreSQLPostgreSQL logo is the correct default for most teams.
  • It has the widest SQL surface and the best extension ecosystem.
  • Most people already know it.
  • pgvector made it the default vector store, killing a category of standalone databases.
  • The catch is the operational tax: it is the heaviest engine here to run.
  • Expect autovacuum tuning, transaction-ID wraparound and bloat.
  • A process per connection means PgBouncer stops being optional past a few hundred clients.
  • Major-version upgrades mean pg_upgrade or a logical-replication cutover.
  • Managed PostgresPostgreSQL logo exists because self-hosting it well is a job.
  • SQLiteSQLite logo is the most under-used engine here, and the most over-claimed.
  • WAL mode gives many concurrent readers.
  • One NVMe machine serves astonishing traffic with zero network hops.
  • But: one writer at a time, and no built-in replication.
  • Most schema changes beyond ADD COLUMN need a twelve-step table rebuild.
  • Backups mean adopting Litestream or Turso.
  • It is a straight trade: one process, short writes, great simplicity.
  • MySQLMySQL logo and MariaDBMariaDB logo are right more often than the PostgresPostgreSQL logo-shaped internet admits.
  • Their edge: changing a very large table's schema without taking writes offline.
  • Online DDL, INSTANT ADD COLUMN, gh-ost and pt-online-schema-change make it routine.
  • Thread-per-connection also forgives a badly behaved pool.
  • Against that: a narrower SQL surface and a thin extension ecosystem.
  • Licence differs: MySQLMySQL logo is GPLv2-or-commercial under Oracle, MariaDBMariaDB logo GPLv2 under a foundation.
  • Embedding the server in a product makes that the whole decision; a website makes it noise.
  • The decision tree, in order:
  • More than one process writing concurrently? If no, and it fits one disk, use SQLiteSQLite logo.
  • Turn on WAL mode.
  • If yes: is much of the load aggregation over columns, not key lookups?
  • If so, that half belongs in DuckDBDuckDB logo or a warehouse, not your OLTP engine.
  • Need extensions, pgvector, PostGIS, TimescaleDB, or window-heavy, CTE-heavy SQL?
  • If yes, PostgreSQLPostgreSQL logo, and budget for the operations.
  • If not, but you fear altering a 500 GB table without downtime, MySQLMySQL logo or MariaDBMariaDB logo.
  • If nothing discriminates, it is a genuine tie.
  • A tie means pick the engine somebody already debugged at three in the morning.

Axis 1, deployment shape

  • The first question is not which SQL dialect you prefer.
  • It is whether the database is a library or a server.
  • SQLiteSQLite logo and DuckDBDuckDB logo run inside your process.
  • No daemon, no port, no credentials, no network hop, no connection pool, nothing extra to monitor.
  • A query is a function call.
  • That collapses an entire layer of your architecture.
  • The cost: the database's availability is now your process's availability.
  • Adding a read replica means shipping the file, Litestream, LiteFS, Turso, not pointing a replica at a primary.
  • Server engines charge you a daemon and pay you back with a network boundary.
  • Several app instances, an analyst with psql, a cross-region replica, a bastion host.
  • Migrations run from CI rather than whichever container won the race.
  • The detail that catches teams out is the connection model.
  • PostgreSQLPostgreSQL logo forks a process per connection.
  • A thousand idle Lambda connections becomes a memory problem, and PgBouncer stops being optional.
  • MySQLMySQL logo and MariaDBMariaDB logo use a thread per connection and forgive a badly configured pool.
  • If your compute is serverless and bursty, that beats any feature in the table.

Axis 2, concurrency profile

  • SQLiteSQLite logo in WAL mode gives many concurrent readers and exactly one writer.
  • Writes are serialised, so the arithmetic is simple.
  • Write transaction duration times writes per second must stay comfortably below one.
  • Short transactions at a few hundred writes per second are fine on commodity hardware.
  • Long transactions are what kill you.
  • Holding a write transaction open across a network call is the classic way to lock a healthy app.
  • MVCC engines let writers proceed in parallel by keeping old row versions.
  • Then they hand you the bill for those versions.
  • On PostgreSQLPostgreSQL logo it arrives as autovacuum, table and index bloat, and transaction-ID wraparound warnings.
  • On InnoDB it arrives as undo-log growth and a history list that climbs when a long read refuses to end.
  • Neither is hard once you know it exists; both are surprises the first time.
  • One detail deserves more attention: the default isolation levels differ.
  • PostgreSQLPostgreSQL logo defaults to READ COMMITTED.
  • MySQLMySQL logo and MariaDBMariaDB logo default to REPEATABLE READ.
  • SQLiteSQLite logo is effectively serialisable, and DuckDBDuckDB logo gives snapshot isolation.
  • Code written against one engine's default can change behaviour silently on another.
  • Read-modify-write races that were impossible become possible, or vice versa.
  • Port the isolation assumptions, not just the SQL.

Axis 3, query complexity

  • PostgreSQLPostgreSQL logo has the widest SQL surface here by a distance.
  • Lateral joins, materialised and non-materialised CTEs, partial and expression indexes, generated columns, exclusion constraints.
  • Window functions that keep gaining features, plus JSONB with GIN indexes.
  • Its extension mechanism made it a geospatial, time-series and vector database without forking.
  • If your queries are analytical in shape but transactional in access pattern, it will not run out of room.
  • MySQLMySQL logo and MariaDBMariaDB logo trade surface area for a fast primary-key path and predictable clustered-index behaviour.
  • Most application queries are exactly that shape, which is why so much of the web runs on them.
  • You feel the ceiling when reporting queries bring five-way joins with correlated subqueries.
  • SQLiteSQLite logo's planner is small and honest about it.
  • It handles ordinary plans well, does less well on many-way joins, and has no parallelism: one query, one core.
  • DuckDBDuckDB logo inverts every one of these assumptions.
  • Vectorised columnar execution, multi-core by default.
  • It reads Parquet, CSV, S3 and live PostgreSQLPostgreSQL logo tables directly.
  • It aggregates a billion rows on a laptop while your OLTP engine is still planning.
  • The right architecture for many teams is running two, not choosing between them.
  • Rows in PostgresPostgreSQL logo or SQLiteSQLite logo, columns in DuckDBDuckDB logo, over the same object storage.

What this page deliberately leaves out

  • There is no pricing group: these engines are free, and the money is in who runs them.
  • The comparison people need next is different: Neon vs SupabaseSupabase logo vs RDS vs Aurora, or PlanetScale and Vitess vs managed MySQLMySQL logo.
  • That is another page with different fields: cold start, branching, connection pooling, egress, backup retention, region coverage.
  • Hosted-PostgresPostgreSQL logo and hosted-MySQLMySQL logo are planned as their own categories.
  • They will have score columns, because those are vendors selling the same thing at different prices.
  • Until then, the adjacent pages are the useful ones.
  • ConvexConvex logo alternatives covers the layer above, where database, API and sync engine ship together and the engine choice is made for you.
  • S3-compatible storage covers where the blobs go, and the substrate DuckDBDuckDB logo reads from.
  • LLM APIs covers the retrieval side of the pgvector column.
  • The embedding model constrains dimensionality, and therefore the index you can afford.

What is sqlite vs postgresql vs mysql vs mariadb vs duckdb?

SQLite vs PostgreSQL vs MySQL vs MariaDB vs DuckDB

On toolweight, SQLiteSQLite logo vs PostgreSQLPostgreSQL logo vs MySQLMySQL logo vs MariaDBMariaDB logo vs DuckDBDuckDB logo means the 5 tools benchmarked on this page, SQLiteSQLite logo, PostgreSQLPostgreSQL logo, MySQLMySQL logo, MariaDBMariaDB logo, DuckDBDuckDB logo, judged on the same 26 fields, from the same sources, on the same date. The question it exists to answer: Should I use SQLiteSQLite logo, PostgreSQLPostgreSQL logo or MySQLMySQL logo?

How does toolweight compare these?

  • Every cell comes from the engine's own reference manual, not a vendor pricing page.
  • That makes this the best-sourced page on toolweight.
  • These projects document their limits precisely and change them slowly.
  • Judgement calls, extension ecosystem, migration tooling, client-library maturity, ops burden, are marked inferred.
  • The ladder is spelled out in the column help, so you can disagree with placement.
  • Where a project documents no limit, the cell is null and renders as an em dash.
  • The killer field is operational burden, scored 1-5 where lower is better.
  • It measures what a team must do to keep the engine healthy, not install difficulty.
  • 1 is a file your process opens; 5 is a cluster with a full-time owner.
  • It inverts the usual ranking: PostgreSQLPostgreSQL logo has the strongest features and the highest burden.
  • Pretending otherwise is how teams hit a vacuum problem eighteen months in.
  • One finding shows only by absence: SQLiteSQLite logo appears nowhere in the timeline.
  • It ships several backwards-compatible releases a year, none of which change a decision.
  • That stability is a feature, and it generates no news.
Full methodology and sourcing policy →
Cite this comparisonCC-BY-4.0 · verified 2026-07-01

Use SQLite when one process owns modest writes, PostgreSQL for concurrent writers and extensions, MySQL or MariaDB for online schema changes, and DuckDB for analytics. — toolweight, https://toolweight.com/compare/sqlite-vs-postgres-vs-mysql, verified 2026-07-01. Data from toolweight (https://toolweight.com), licensed CC-BY-4.0.

Frequently asked questions

Is SQLite production-ready for a real web application?

  • Yes, with conditions.
  • Turn on WAL mode, set a busy timeout, and keep write transactions short.
  • Adopt a replication or backup tool such as Litestream on day one.
  • The limits that bite are single-writer serialisation and no built-in replication, not throughput, correctness or size.

When does SQLite's single writer actually become a problem?

  • Multiply your write transaction duration by your write rate.
  • Five-millisecond transactions at 200 writes per second use about a second of writer time per wall-clock second, already near the wall.
  • Long transactions are the real killer: one 300 ms write blocks every other writer for 300 ms.
  • If you cannot bound transaction duration, you want an MVCC engine.

MySQL or MariaDB in 2026?

  • For a normal application either works, and the drivers are largely interchangeable.
  • Choose MariaDBMariaDB logo for a foundation over Oracle, GPLv2 without a commercial upsell, native vector search, or Galera clustering.
  • Choose MySQLMySQL logo if your managed host, ORM or replication tooling assumes it.
  • Or choose MySQLMySQL logo if you need Oracle's commercial licence to embed the server in a product.

Do I need a dedicated vector database, or is pgvector enough?

  • For almost everyone, pgvector is enough.
  • It gives HNSW and IVFFlat indexes in the same transaction as your rows, so embeddings cannot drift out of sync.
  • Reach for something specialised only when index build time, high-dimensional recall, or billion-scale corpora become the bottleneck.
  • That is later than most teams assume.

Can DuckDB be my application database?

  • No, and it does not try to be.
  • It is an in-process columnar engine for scans and aggregation, with a single-process write path and no replication or PITR.
  • Superb as the analytics half of a system, querying Parquet or reading straight from your PostgresPostgreSQL logo.
  • A poor fit for many clients writing single rows.

Is PostgreSQL always the safe default?

  • It is the safest default, not a free one.
  • You get the widest SQL surface, transactional DDL and the deepest extension ecosystem.
  • You also get autovacuum, bloat, transaction-ID wraparound and a process per connection.
  • If nobody will own those, use managed PostgresPostgreSQL logo or pick a lighter engine deliberately.

How painful are schema migrations on each engine?

  • MySQLMySQL logo and MariaDBMariaDB logo are best: online DDL plus gh-ost and pt-online-schema-change make altering a huge table routine.
  • PostgreSQLPostgreSQL logo runs DDL inside a transaction, a genuine advantage, but type changes rewrite the table under an exclusive lock.
  • So PostgresPostgreSQL logo teams reach for pgroll or pg_repack.
  • SQLiteSQLite logo is worst: most changes need the documented twelve-step table rebuild, though modern tooling automates it.