7 Postgres extensions
Postgres owes much of its popularity to its extensibility, a design principle rooted in its origins at UC Berkeley under Michael Stonebraker. Early database research showed that one-size-fits-all relational systems struggled beyond traditional business workloads, so Postgres was built to be adaptable. That philosophy sparked a thriving ecosystem of extensions and gave rise to the “Just use Postgres” ethos—using a solid core database augmented by plug-in capabilities to handle a wide spectrum of modern use cases.
Extensions integrate cleanly because Postgres exposes system catalogs, hook points in the execution pipeline, and dynamic loading for logic written in SQL, procedural languages, or compiled code. Administrators can discover what’s available via system views, install extensions on the server, and then enable them per database with simple commands. The chapter demonstrates this flow using the bundled pgcrypto extension: checking availability, enabling it, and then applying gen_salt and crypt to securely store and verify passwords. Extensions remain modular—easy to enable when needed and disable when not—while leaving the core engine stable.
For developers, the chapter highlights five practical extension categories. “Beyond relational” adds new data and workload types (for example, vectors and AI with pgvector/pg_ai/pgvectorscale, time series with TimescaleDB, geospatial with PostGIS, messaging with pgmq, and analytics acceleration with pg_duckdb). “Programming and procedural languages” let you write database logic in familiar languages (such as PLV8, PL/Java, PL/Python, and PL/Rust). “Connectors and foreign data wrappers” unify access to external stores (e.g., file_fdw, postgres_fdw, mysql_fdw, oracle_fdw, sqlite_fdw, redis_fdw, parquet_s3_fdw, kafka_fdw). “Query and performance optimization” aids diagnosis and tuning (pg_stat_statements, auto_explain, hypopg). “Tools and utilities” streamline operations (pg_cron, PostgreSQL Anonymizer, pgaudit, pg_partman). When extensions aren’t sufficient, Postgres-compatible systems step in—some built from scratch to speak the Postgres wire protocol (like large-scale distributed databases), others built atop the Postgres codebase (such as serverless or distributed variants)—letting teams reuse skills and tooling to reach new performance and scalability frontiers.
Summary
- Extensibility was one of the main requirements for Postgres.
- Postgres enables extensibility through catalog-driven operations, database hooks, and dynamic loading of external logic.
- Postgres extensions can be installed via extension registries/repositories, package managers, or prebuilt container images or built from source.
- Postgres ships dozens of extensions in its standard distribution.
- Application developers can use a wide range of extensions to go beyond relational workloads, query data from remote sources, simplify query optimization, and more.
- Postgres-compatible solutions address specific problems that cannot be easily or effectively solved through an extension. They either support the Postgres wire-level protocol and a subset of its features or are built on the Postgres source code with modifications to its original logic.
FAQ
What makes Postgres so extensible?
Postgres was designed for extensibility from the start. Extensions can add types, functions, and behaviors by interacting with system catalogs (catalog-driven operations), hooking into lifecycle events (database hooks), and, when needed, loading compiled code at runtime (dynamic loading) without rebuilding the core server.How do I see which extensions are available and which are enabled?
Querypg_available_extensions to see what’s available on the server (with default_version and installed_version). Use pg_extension or \dx in psql to list extensions enabled in the current database. Tip: \x on toggles expanded display.What’s the difference between installing an extension and enabling it?
First, the extension’s files must exist on the server (bundled, installed via a repo, a package manager, a container image, or from source). Then you enable it per database withCREATE EXTENSION. Availability is server-wide; enablement is database-specific.How do I enable the pgcrypto extension and verify its version?
RunCREATE EXTENSION pgcrypto; in the target database. Verify with SELECT name, default_version, installed_version FROM pg_available_extensions WHERE name = 'pgcrypto'; or SELECT extname, extversion FROM pg_extension;.How can I securely store passwords with pgcrypto?
Use a per-password salt and a strong hash:INSERT INTO accounts(username, password_hash) VALUES ('user', crypt('RawPassword', gen_salt('bf'))); The random salt ensures unique hashes even for identical passwords, and the salt is stored inside the resulting hash.How do I verify a password at login with pgcrypto?
Compare the stored hash against a hash of the provided password using the stored salt:SELECT username FROM accounts WHERE username = 'user' AND password_hash = crypt('RawPassword', password_hash); A match indicates successful authentication.How do I disable an extension, and what happens to dependent queries?
Disable withDROP EXTENSION <name>; After dropping, functions or types provided by that extension (for example, crypt from pgcrypto) become unavailable and dependent queries will fail until you CREATE EXTENSION again.What are common ways to add extensions to a Postgres server?
- Extension registries like PGXN- Prebuilt container images bundling Postgres + extension(s)
- OS package managers (APT, DNF/YUM)
- Downloading binaries or building from source following the extension’s instructions
Which extension categories are especially useful to developers?
- Beyond relational:pgvector, pg_ai, pgvectorscale, TimescaleDB, PostGIS, pgmq, pg_duckdb- Procedural languages:
PLV8, PL/Java, PL/Python, PL/Rust- Connectors/FDWs:
file_fdw, postgres_fdw, mysql_fdw, oracle_fdw, sqlite_fdw, redis_fdw, parquet_s3_fdw, kafka_fdw- Performance:
pg_stat_statements, auto_explain, hypopg- Tools/utilities:
pg_cron, PostgreSQL Anonymizer, pgaudit, pg_partmanWhat does default_version vs installed_version mean?
default_version is the version available on the server that will be used if you don’t specify one. installed_version is the version currently enabled in the connected database. If blank, the extension isn’t enabled there.
Just Use Postgres! ebook for free