What is PostgreSQL and why it became the default
Published on 2026-09-12 by frfrand
De proyecto universitario a la base relacional que casi todo el mundo elige. Qué la hizo ganar, qué trae de fábrica que sorprende, y los dos ajustes que casi nadie toca y debería.

PostgreSQL started in the eighties in Berkeley as a successor to a project called Ingres. For decades it was "the other one", the serious but less popular alternative than MySQL.
In the last ten years it became the default option for new projects. It is worth seeing why, because the reasons are concrete.
What made it win
Correctness before speed. Postgres always prioritized behaving well in difficult cases: transactions that are truly atomic, constraints that are fulfilled, types that do not accept invalid data. Historically that made it slower in simple tests and much more reliable in production.
An example that illustrates the philosophy: if you try to save a text longer than the column, Postgres gives an error. Other engines, for years, truncated it silently. An error is uncomfortable; a mutilated piece of data that you discover six months later is worse.
Transactional DDL. You can put several schema changes in a transaction and revert them all if something fails. For migrations this is huge: a half-applied migration is one of the worst possible situations, and with Postgres it simply does not happen.
Extensible by design. You can add types, functions and indexes without touching the engine. From there came PostGIS for geographic data, TimescaleDB for time series, pgvector for similarity searches. The same database serves for things that previously required a separate system.
What it brings and many people do not use
JSONB. Stores JSON in binary format, indexable and queryable. Allows starting with a well-defined relational schema and having a couple of flexible columns where needed, without adding a document database to the project.
Arrays and ranges. A column can be a list. Or a date range, with operators to ask if two ranges overlap — perfect for reservations, and resolved without logic in the application.
Indexes for every way of searching. Besides the classic one, there are GIN indexes for JSON and text, partial indexes (which only cover rows that meet a condition and take up much less space), and indexes on expressions.
Materialized views. A heavy query saved as a table and refreshed whenever you say so. Solves many metrics dashboards without adding infrastructure.
The two settings almost nobody touches
Postgres' default configuration is conservative: it's designed to start on any machine, even a very small one. On a real server, two parameters make a big difference:
shared_buffers. How much memory it uses for its cache. The default value is usually 128 MB. The usual recommendation is around 25% of the server's RAM.
work_mem. Memory per sorting or grouping operation. If it's too small, those operations are done on disk and queries drag. Careful: it multiplies per operation and per connection, so raising it a lot with many connections can exhaust memory.
And the usual diagnosis: put EXPLAIN ANALYZE in front of the slow query. If the first line says Seq Scan on a large table, an index is missing.
A warning about connections
Each connection to Postgres is an operating system process. That makes it very robust (a process that dies does not take down the others) and also means connections are expensive.
An application with many workers can exhaust the limit quickly. The solution is not to raise the limit: it is to put a connection pooler in front, like PgBouncer. It is the setting that most often saves an application that "started failing when traffic grew".
In ArduMaker you can set up Postgres on your VPS from the panel, with credentials, backups, and tunnel access instead of an open port.