CareersInCloud
PostgreSQL vs MySQL: Threads vs Processes - How Each Database Handles Connections
PostgreSQLMySQLDatabaseSQLArchitectureDevOpsBackendPerformanceConnectionPooling

PostgreSQL vs MySQL: Threads vs Processes - How Each Database Handles Connections

By Shiva2 Aug 2026CloudSutra

PostgreSQL and MySQL are the two most popular open-source relational databases in the world, but they are built on very different foundations. The most famous difference is in how they handle client connections: PostgreSQL uses one operating system process per connection, while MySQL uses one process with multiple threads.

This single architectural decision drives almost everything else - memory usage, connection limits, crash isolation, and even whether you need connection pooling. In this guide, we explain both models in simple terms and show you what they mean in practice.

Why the Connection Model Matters

Every time an application opens a database connection, the database server must allocate resources to handle it. That allocation is exactly where PostgreSQL and MySQL diverge.

  • PostgreSQL gives each connection its own dedicated process.
  • MySQL gives each connection its own thread inside a single shared process.

One is like giving every customer their own private room. The other is like one big hall where everyone shares the same space. Both work, but they have very different strengths and weaknesses.

How PostgreSQL Handles Connections: The Process Model

PostgreSQL runs what is called a multi-process architecture. When the database starts, a supervisor process called the postmaster starts first and listens for incoming connections on port 5432.

Here is what happens when a client connects:

  1. The client sends a connection request to the postmaster.
  2. The postmaster authenticates the request by checking credentials and permissions.
  3. Once verified, it uses the operating system's process creation mechanism - traditionally fork() on Unix-like systems - to create a brand-new backend process.
  4. That backend process is dedicated to this single connection for its entire life.
  5. It handles all queries for that client until the connection closes, then it exits.

Each backend process has a baseline memory overhead that is typically a few megabytes, but the total memory used by a connection can grow significantly depending on query execution, work_mem, temporary operations, and extensions. To make forking faster, PostgreSQL uses a Copy-on-Write (CoW) optimization: the new process does not copy the parent's memory immediately, only when it actually changes data.

The strengths of this model are isolation and stability. If one backend process crashes because of a bad query, only that connection dies. The rest of the server keeps running. Because each backend has its own virtual address space, memory errors are generally isolated to that backend process, improving fault isolation.

The weakness is cost. Processes are heavier than threads. Forking takes longer than creating a thread, and every connection consumes a meaningful amount of RAM even when idle. This is why PostgreSQL's default connection limit (max_connections) is conservative at 100, and why connection pooling is considered essential in production.

How MySQL Handles Connections: The Thread Model

MySQL uses a multi-threaded architecture. The server runs as a single process called mysqld, and each client connection is handled by a thread inside that process.

Here is what happens when a client connects:

  1. The mysqld process, already running, accepts the connection.
  2. It creates a lightweight thread to handle that connection.
  3. The thread shares the process's memory space with all other threads.
  4. The thread serves queries until the client disconnects, then it is cleaned up.

Because all threads live in the same memory space, they share resources like the buffer pool and table metadata. Creating a thread is much cheaper and faster than forking a process. MySQL can generally support much higher numbers of direct client connections than PostgreSQL due to its threaded architecture, assuming sufficient system resources and appropriate configuration.

The strengths of this model are efficiency and scale. MySQL generally has lower per-connection overhead than PostgreSQL because threads share the process address space, although memory usage also depends on thread buffers and server configuration. Context switching between threads is also cheaper than between processes. For applications with many short-lived connections, MySQL tends to feel lighter out of the box.

The weakness is isolation. Because all worker threads share the same process, a severe bug affecting the server process has the potential to impact all active connections, although such failures are uncommon in modern releases. Under heavy concurrency, threads also compete for internal locks, which can cause contention and rising latency when many connections are active at the same time.

PostgreSQL vs MySQL: Side-by-Side Comparison

PostgreSQL (Process Model)

  • Connection model: Process per connection
  • Parent/manager: Postmaster process
  • Connection creation: fork() a new process
  • Memory per connection: High (few MB base, workload-dependent)
  • Default max connections: 100
  • Crash isolation: Strong — one backend fails only
  • Connection speed: Slower (process forking)
  • Direct connections without pooler: Typically kept relatively low, with pooling
  • Connection pooling: Strongly recommended in production
  • Popular poolers: PgBouncer, Pgpool-II
  • Best for: Complex queries, heavy writes, advanced features

MySQL (Thread Model)

  • Connection model: Thread per connection
  • Parent/manager: Single mysqld process
  • Connection creation: Spawn a new thread
  • Memory per connection: Low (thread buffers, configuration-dependent)
  • Default max connections: 151
  • Crash isolation: Moderate — process-wide failure possible but uncommon
  • Connection speed: Faster (thread creation)
  • Direct connections without pooler: Much higher direct connections possible
  • Connection pooling: Recommended at scale
  • Popular poolers: ProxySQL, MySQL Router
  • Best for: High connection counts, simple queries

A simple way to picture both architectures:

  • PostgreSQL: Client → Postmaster → Backend Process
  • MySQL: Client → mysqld → Worker Thread

Memory Usage: The Real Difference

The memory picture is where the two models diverge most in real deployments.

With PostgreSQL, every backend process carries its own overhead even when completely idle. On a machine with limited RAM, a few hundred idle connections can push the server into swapping. This is why PostgreSQL databases are often sized around connection count, not just query load.

With MySQL, threads share the process address space, so idle connections cost much less. However, MySQL still has thread stack overhead, and unbounded connections can exhaust the thread limit or trigger the kernel's out-of-memory killer on small servers. Both databases punish careless connection patterns - PostgreSQL just hits the wall sooner because the wall is usually RAM.

Performance Under Load

For short-lived connections typical of web applications, the thread model gives MySQL an advantage because creating a thread is faster than forking a process. MySQL also tends to have more predictable latency under simpler workloads.

PostgreSQL scales very well when configured properly, but the process model means CPU scheduling and context switching become a factor once connection counts grow large. Despite using a process-per-connection architecture, PostgreSQL delivers excellent performance because query execution dominates connection creation costs in long-lived applications. Connection pooling largely eliminates the process creation overhead, keeping the database's CPU focused on queries instead of bookkeeping.

Neither database is "better" - each shines in its intended pattern. PostgreSQL handles complex, write-heavy, mixed workloads with strong consistency. MySQL excels at read-heavy, high-connection simple workloads.

Why Connection Pooling Matters

Connection pooling is the practice of keeping a small set of warm database connections open and reusing them across many application requests, instead of opening and closing a connection for every query.

For most production PostgreSQL deployments with many application clients, connection pooling is strongly recommended. It sits between the application and the database, multiplexing thousands of client connections onto a handful of backend processes. A typical setup might serve 1,000 application connections through only 20-50 real PostgreSQL backends.

For MySQL, pooling is more of a recommendation. The thread model tolerates many direct connections, but pooling still reduces handshake overhead and protects against connection storms. Tools like ProxySQL are commonly used at scale. Note that MySQL Enterprise Edition also includes a Thread Pool plugin, and MariaDB provides a thread pool implementation, both designed to improve scalability under extremely high connection counts.

Which Database Should You Choose?

Choose PostgreSQL when you need advanced features, strong data integrity, complex queries, JSON support, geospatial data, or heavy write workloads. Its process model gives you excellent isolation, and with pooling it handles high concurrency well.

Choose MySQL when you have thousands of simple, short-lived connections, a read-heavy workload, or a team already familiar with MySQL tooling. Its thread model handles high connection counts more gracefully without extra infrastructure.

Frequently Asked Questions

Does PostgreSQL create a new process for every connection? Yes. The postmaster process forks a dedicated backend process for each connection.

Does MySQL use threads or processes? MySQL runs as a single process and creates a thread per connection.

Is PostgreSQL faster than MySQL? It depends on the workload. PostgreSQL often wins on complex queries and heavy writes; MySQL often wins on simple, high-connection workloads.

Why does PostgreSQL need connection pooling? Because each connection maps to a full OS backend process that carries a baseline memory overhead, so thousands of idle connections can exhaust server RAM. Pooling keeps the number of live backends small.

Can MySQL handle more connections than PostgreSQL? Generally yes, without a pooler, thanks to its lower per-connection memory overhead and lightweight threads.

Summary

The process-versus-thread debate is not about which database is better - it is about understanding the trade-offs. PostgreSQL trades memory and connection overhead for strong isolation and stability. MySQL trades isolation for efficiency and the ability to handle many lightweight connections.

The right choice depends on your workload, your infrastructure budget, and your team's experience. What matters most is understanding the architecture underneath, so you can plan memory, connection limits, and pooling before the traffic arrives.

Author's Note: The memory figures in this article are approximate and depend heavily on server configuration, workload, and extensions. Always benchmark against your own environment before making capacity decisions.