Extensions: PostGIS, pgvector & More
One reason PostgreSQL is so popular is that you can add new data types, functions, index types and even background workers without changing the server itself. These add-ons are called extensions. Some ship with PostgreSQL, and others, such as PostGIS for maps and pgvector for AI similarity search, are separate projects that turn PostgreSQL into a specialised database.
In this lesson you will install and manage extensions, and meet the ones you are most likely to use: pg_trgm, pgcrypto, pg_stat_statements, PostGIS and pgvector.
Installing an extension
An extension has two steps. First its files must be on the server (they come with PostgreSQL, a package such as postgresql-18-postgis-3, or a Docker image that includes them). Then you enable it in each database that needs it:
CREATE EXTENSION IF NOT EXISTS pg_trgm;CREATE EXTENSION
To see what your server can install, query SELECT name, default_version, installed_version FROM pg_available_extensions;; the versions depend on your PostgreSQL release. \dx in psql lists the extensions installed in the current database, ALTER EXTENSION name UPDATE upgrades one after a server upgrade, and DROP EXTENSION removes it. Creating most extensions needs a superuser or the database owner; managed cloud databases offer an approved list.
Even a fresh database has one extension, the PL/pgSQL language you used in PL/pgSQL Functions & Procedures. That is the only extension available in the browser editor:
SELECT extname, extversion FROM pg_extension ORDER BY extname;extname | extversion --------+----------- plpgsql | 1.0 (1 row)
Useful extensions that ship with PostgreSQL
These contrib modules come with the standard packages:
| Extension | What it adds |
|---|---|
pg_trgm | Similarity search on text using trigrams (groups of three letters); speeds up ILIKE '%term%' and finds typos |
pgcrypto | Hashing and encryption functions, such as crypt() for password hashes and pgp_sym_encrypt() |
pg_stat_statements | Statistics for every distinct query: calls, total time, rows; the first place to look for slow queries |
citext | A case-insensitive text type, handy for email addresses |
unaccent | Removes accents for search (café becomes cafe) |
btree_gist | Lets GiST indexes handle plain types, needed for exclusion constraints with = |
postgres_fdw | Query tables on another PostgreSQL server as if they were local |
pg_trgm makes fuzzy search easy. With a trigram index, the query below finds "Mechanical Keyboard" even when a user types "keybord":
CREATE EXTENSION pg_trgm;
CREATE INDEX products_name_trgm ON products USING gin (product_name gin_trgm_ops);
SELECT product_name, round(similarity(product_name, 'keybord')::numeric, 2) AS score
FROM products
WHERE product_name % 'keybord' OR product_name ILIKE '%keybord%'
ORDER BY score DESC;pg_stat_statements must also be loaded at server start: add it to shared_preload_libraries in postgresql.conf, restart, then run CREATE EXTENSION pg_stat_statements; and query the pg_stat_statements view ordered by total_exec_time.
PostGIS: maps and locations
PostGIS adds geographic types and hundreds of spatial functions, so PostgreSQL can answer questions like "which stores are within 10 km of this customer?". It is a separate project, installed as an extra package. Locations are usually stored as the geography type with longitude first, then latitude:
CREATE EXTENSION postgis;
CREATE TABLE stores (
store_id int PRIMARY KEY,
city text,
location geography(Point, 4326)
);
INSERT INTO stores VALUES
(1, 'Rohtak', ST_MakePoint(76.61, 28.90)::geography),
(2, 'Delhi', ST_MakePoint(77.21, 28.61)::geography),
(3, 'Jaipur', ST_MakePoint(75.79, 26.91)::geography);
CREATE INDEX stores_location_gist ON stores USING gist (location);
SELECT city, round(ST_Distance(location, ST_MakePoint(77.03, 28.46)::geography) / 1000) AS km
FROM stores
WHERE ST_DWithin(location, ST_MakePoint(77.03, 28.46)::geography, 100000)
ORDER BY km;4326 identifies the WGS 84 coordinate system used by GPS. ST_Distance on geography returns metres, and ST_DWithin keeps stores within 100,000 metres (100 km) of a point in Gurugram, using the GiST index. Delivery apps, property sites and logistics companies build on exactly these functions.
pgvector: similarity search for AI
pgvector adds a vector type for embeddings: lists of numbers that AI models produce to describe the meaning of text or images. Similar meanings give vectors that are close together, so "find the nearest vectors" becomes "find similar products" or "find the paragraphs that answer this question", the core of retrieval-augmented generation (RAG). The tiny 3-number vectors below stand in for the hundreds or thousands of numbers a real model returns:
CREATE EXTENSION vector;
CREATE TABLE product_embeddings (
product_name text,
embedding vector(3)
);
INSERT INTO product_embeddings VALUES
('Wireless Mouse', '[0.9, 0.1, 0.0]'),
('Mechanical Keyboard', '[0.8, 0.2, 0.1]'),
('Bluetooth Speaker', '[0.1, 0.9, 0.3]');
SELECT product_name
FROM product_embeddings
ORDER BY embedding <-> '[0.9, 0.12, 0.02]'
LIMIT 2;CREATE EXTENSION
CREATE TABLE
INSERT 0 3
product_name
---------------------
Wireless Mouse
Mechanical Keyboard
(2 rows)<-> is Euclidean (L2) distance, <=> is cosine distance and <#> is negative inner product. For large tables, pgvector provides approximate nearest-neighbour indexes, hnsw and ivfflat, for example CREATE INDEX ON product_embeddings USING hnsw (embedding vector_cosine_ops);. Keeping embeddings next to your normal data means one query can combine "similar to this" with ordinary filters such as price and stock.
Common mistakes
- Running
CREATE EXTENSIONbefore the package is installed. The error says the control file is missing. Install the OS package or use an image that includes it. - Enabling an extension in the wrong database. Extensions are per database; enable them where your tables are.
- Forgetting
shared_preload_libraries. Some extensions, such aspg_stat_statements, need it and a restart. - Swapping latitude and longitude. PostGIS points are (longitude, latitude).
Key points
- Extensions add types, functions, operators and index types; enable one with
CREATE EXTENSIONin each database. pg_available_extensionsshows what can be installed;\dxandpg_extensionshow what is installed.- Contrib extensions such as
pg_trgm,pgcrypto,pg_stat_statementsandcitextship with PostgreSQL. - PostGIS adds geographic types and functions such as
ST_DistanceandST_DWithin, indexed with GiST. - pgvector adds a
vectortype, distance operators and HNSW/IVFFlat indexes for AI similarity search.
Exercise
Write the SQL to enable pgcrypto and create a table staff_logins (username text PRIMARY KEY, password_hash text NOT NULL). Insert a user whose password is hashed with crypt() and a bcrypt salt from gen_salt('bf'), then write a query that checks a typed password against the stored hash.
Show solution
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE TABLE staff_logins (username text PRIMARY KEY, password_hash text NOT NULL);
INSERT INTO staff_logins VALUES ('neha', crypt('Correct-Horse-42', gen_salt('bf')));
SELECT username,
password_hash = crypt('Correct-Horse-42', password_hash) AS password_ok
FROM staff_logins
WHERE username = 'neha';crypt() with the stored hash as the salt re-hashes the typed password the same way, so the comparison is t only for the right password. In a web app, hashing passwords in application code (for example with PHP's password_hash()) is just as good and keeps plain passwords out of SQL logs.
Quick Quiz
1. What does CREATE EXTENSION pg_trgm; do?
The files must already be installed; CREATE EXTENSION enables it per database.
2. Which extension helps you find the slowest queries on a server?
It records calls, total time and rows for every distinct query.
3. In PostGIS, in which order are point coordinates given to ST_MakePoint?
Points are (x, y), which is (longitude, latitude).
4. What does the pgvector operator <-> calculate?
<-> is L2 distance; <=> is cosine distance and <#> negative inner product.
Learn PostgreSQL with a mentor
Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
