Skip to content
Discord Get Started

Extensions

DB9 ships all extensions compiled into the server binary. There is no runtime dynamic loading, which is what buys you the guarantees below: there is nothing to install, no build step, no version skew between two databases, and every extension is available the moment a database exists. CREATE EXTENSION records install metadata per database rather than loading anything.

The trade is that the set is fixed. CREATE EXTENSION accepts exactly the names on this page and raises 42704 extension is not available for every other name — PostGIS, pg_trgm, ltree, citext and the rest of the PostgreSQL contrib ecosystem included.

CREATE EXTENSION accepts eleven names, and they fall into two groups:

  • Eight functional extensions — fs9, parquet, vector, embedding, zhparser, http, pg_cron and uuid-ossp (uuid_generate_v4() only). These add types, functions, or operators.
  • Three metadata-only shims — hstore, pgcrypto and plpgsql. CREATE EXTENSION succeeds and writes a pg_extension row so dumps and ORM bootstrap scripts restore unchanged, but none of them registers a function of its own, and the hstore type name that hstore adds to pg_type cannot hold a value. Read the pgcrypto caution before you depend on any of them.

This page is the authoritative list; other pages link here rather than restating it.

ExtensionWhat it doesDocs
fs9Query, read, and write the database filesystem from SQLfs9 reference
parquetRead Parquet files from the filesystem or HTTP URLs into SQL tablesParquet import
ExtensionWhat it doesDocs
vectorpgvector-compatible similarity search with HNSW indexingVector Search
embeddingServer-side text embedding via EMBEDDING() and EMBED_TEXT() — no external API neededVector Search
zhparserChinese full-text search tokenizer (jieba-rs, always available)Full-Text Search

English and general-purpose full-text search is not an extension — tsvector, tsquery, to_tsvector(), websearch_to_tsquery(), GIN indexes on tsvector and the rest of the FTS surface are core server features, so there is no fts name to pass to CREATE EXTENSION. See Full-Text Search. zhparser is the one FTS-related extension descriptor, and it covers Chinese tokenization only.

ExtensionWhat it doesDocs
httpMake HTTP requests from SQL (GET, POST, PUT, DELETE, HEAD, PATCH as table functions)HTTP client
pg_cronSchedule SQL statements to run on a cron expressionpg_cron
ExtensionWhat it doesDocs
uuid-osspuuid_generate_v4() only — the other uuid-ossp functions (uuid_generate_v1(), uuid_generate_v3(), uuid_generate_v5(), uuid_nil(), …) fail with 42883uuid-ossp
hstoreMetadata only — hstore values are not supported (0A000). Use JSONBhstore
pgcryptoMetadata only — registers no functions. CREATE EXTENSION pgcrypto succeeds so Supabase and ORM bootstrap scripts restore unchanged, but crypt(), gen_salt(), hmac(), encrypt()/decrypt(), pgp_sym_encrypt() and gen_random_bytes() are not availablecaution below
plpgsqlMetadata only — PL/pgSQL is compiled into the server and works with or without CREATE EXTENSION plpgsql; the statement exists so restored dumps do not failcaution below

Most extensions require CREATE EXTENSION before use. A few are pre-enabled or always available.

Pre-enabled (available on every new database)

Section titled “Pre-enabled (available on every new database)”

These extensions are installed automatically when a database is created:

SQL
-- Already enabled — no CREATE EXTENSION needed
SELECT http_get('https://httpbin.org/get');
SELECT count(*) FROM cron.job;
  • http — HTTP client functions available immediately
  • pg_cron — Extension pre-installed; catalog and management functions (cron.job, cron.unschedule, etc.) are available immediately, but job scheduling/execution is unavailable in the current release

These extensions must be explicitly enabled — for fs9, only its table functions depend on it:

SQL
CREATE EXTENSION IF NOT EXISTS fs9;
CREATE EXTENSION IF NOT EXISTS embedding;
CREATE EXTENSION IF NOT EXISTS parquet;
  • embedding and parquet — until enabled, calls fail with ERROR: extension "embedding" is not installed. Run: CREATE EXTENSION embedding (0A000), and the same message naming parquet for extensions.read_parquet(...).
  • fs9 — the scalar functions (fs9_write, fs9_read, fs9_append, fs9_mkdir, fs9_exists, fs9_remove and the other fs9_* file functions) work on a new database without CREATE EXTENSION, bare or extensions.-qualified, and calling them does not add fs9 to pg_extension. The table functions — extensions.fs9(), extensions.fs9_events(), extensions.fs9_jg(), extensions.fs9_storage_stats() and extensions.fs9_cached_storage_stats() — fail with ERROR: unsupported table-valued function: fs9 (0A000, naming the function you called) until you run CREATE EXTENSION fs9.

Metadata shims (built-in, CREATE EXTENSION optional)

Section titled “Metadata shims (built-in, CREATE EXTENSION optional)”

These need no CREATE EXTENSION — what they provide is built in, or, for hstore, not implemented at all — but running it records metadata in pg_extension for ORM and tool compatibility:

  • vector — The vector type and operators (<->, <#>, <=>) work as built-ins. HNSW indexes can be created and the planner uses them for similarity search when the probe is a literal or a bound parameter and the query has a LIMIT and no WHERE clause — see Vector Search. CREATE EXTENSION vector is recommended so ORMs that check pg_extension see it as installed.
  • uuid-ossp — uuid_generate_v4() is built in, and it is the only uuid-ossp function DB9 has: uuid_generate_v1(), uuid_generate_v3(), uuid_generate_v5() and uuid_nil() fail with 42883. CREATE EXTENSION "uuid-ossp" records metadata for pg_dump/pg_restore compatibility.
  • hstore — Extension metadata only: hstore values are not supported, so any use of the type fails with 0A000 type "hstore" is not supported and the hint Use jsonb instead. — store key-value data in JSONB. While the extension is registered, pg_dump fails with column "typanalyze" does not exist; DROP EXTENSION hstore clears it.
  • pgcrypto — Metadata only, so Supabase and ORM bootstrap scripts that run CREATE EXTENSION pgcrypto succeed unchanged. It registers no functions of its own: gen_random_uuid() and digest() are DB9 built-ins that work with or without it. The rest of pgcrypto is not implemented — see the caution below.
  • plpgsql — PL/pgSQL is compiled in. CREATE EXTENSION plpgsql records metadata so restored dumps (which almost always contain it) do not fail.
  • zhparser — The Chinese full-text tokenizer is compiled in and always active. CREATE EXTENSION zhparser is accepted but has no effect.

Extensions install their functions into specific schemas:

ExtensionDefault schemaAccess pattern
httpextensionshttp_get(...) for the scalar JSONB form; SELECT * FROM extensions.http_get(...) for the table form. The qualifier is not interchangeable — see http
fs9extensionsfs9_read(...) or extensions.fs9_read(...) — both resolve on the default search_path
embeddingextensionsembedding(...) — the bare name; extensions.embedding(...) does not resolve
parquetextensionsSELECT * FROM extensions.read_parquet(...) — table-valued, FROM position only
pg_croncroncron.schedule(...), cron.unschedule(...)
vectorpublicOperators and type available directly
uuid-ossppublicuuid_generate_v4() available directly
hstorepublicMetadata only — hstore values are not supported
pgcryptoextensionsMetadata only — registers no functions (gen_random_uuid(), digest() are built-ins)
plpgsqlpg_catalogMetadata only — PL/pgSQL is compiled in

For vector, uuid-ossp, hstore, pgcrypto and plpgsql, CREATE EXTENSION ... SCHEMA accepts only the schema in this table; naming another fails with 0A000 extension "vector" must be installed in schema "public". The vector type, its operator classes and its operators are built in, so write them unqualified (OPERATOR(public.<=>) fails with internal error): public.vector(3) and extensions.vector(3) both fail with 42704 type "public.vector" does not exist (or "extensions.vector"), and extensions.uuid_generate_v4() fails with 42883. pg_dump writes these names schema-qualified — rewrite them before an import, as described in Migrate from PostgreSQL and Migrate from Supabase.

I want to…Use
Store and search vector embeddingsvector + embedding
Build a RAG pipeline without external APIsembedding + fs9
Call an external API from SQLhttp
Query files on the database filesystemfs9
Watch filesystem changes in real timefs9 events + CLI watch
Import Parquet dataparquet
Schedule a recurring cleanup or reportpg_cron
Search text contentFull-Text Search
Generate UUIDsuuid-ossp