Database
PostgreSQL extensions
Kuunda Cloud follows the model teams expect from managed Postgres: rich image, minimal preload, on-demand activation. The tenant is a proj_* schema — not an isolated database. That changes where an extension can be installed.
1. Three layers (do not mix them up)
1 · Image
Package present
The extension appears in pg_available_extensions. It is not yet created in the database.
2 · Preload
Postgres startup
Only pg_stat_statements is preloaded. No pg_cron by default.
3 · CREATE
Activation
CORE and optional extensions at provisioning. The rest: console button on a dedicated instance, never via the SQL editor.
2. Shared pool vs dedicated instance
A PostgreSQL extension is database-level, not schema-level. On the shared pool, several proj_* projects share the same database: a CREATE EXTENSION would affect all of them.
| Plan | Catalog | Installation |
|---|---|---|
| Shared pool | Read: CORE + optional extensions already created | Denied (contact support for a dedicated instance) |
| Dedicated / cluster | Allowlist ∩ packages on the instance | Database → Extensions, one extension at a time |
Why the button is greyed out
3. In the console
- Project → Database → Extensions
- Review already installed extensions (
extensionsschema except the exceptions below) - Dedicated instance: pick a packaged extension, then install. Dependencies (e.g. PostGIS before raster) are applied without CASCADE
SQL editor
CREATE EXTENSION and DROP EXTENSION are rejected in the editor. Use the Extensions screen. Do not create tables in the extensionsschema.4. SQL, search_path and API
After creation, types and functions usually live in extensions. The project search_path is:
proj_<id_sans_tirets>, public, extensionsThe REST API adds the same extra-search-path (public, extensions). You can therefore write citext or vector without a prefix, as on a Supabase project.
-- Exemple une fois citext activée (instance dédiée)
CREATE TABLE contacts (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
email citext NOT NULL UNIQUE
);Schemas outside the REST API
public and proj_*. Never extensions, graphql, topology, tiger, cron and net in pgrst.db_schemas. GraphQL and PostGIS remain usable in SQL; they do not become REST collections.plpgsql is PostgreSQL’s native language: it does not appear as a UI catalog row.
5. Catalog
The console only offers names packaged on the instance and allowed. An extension missing from pg_available_extensions is not listed.
Always there (CORE)
Created at provisioning (the project is not delivered without them). Present on the shared pool and on dedicated. No “install” button: they are already there.
| Extension | Role |
|---|---|
| uuid-ossp | UUID generation (uuid_generate_v4, etc.). |
| pgcrypto | Hashing, encryption, gen_random_uuid(). |
| pg_trgm | Trigram similarity, GIN/GiST indexes for fuzzy search. |
Optional (provisioner)
Installed if the package is available. pg_stat_statements requires the preload (already in place). pg_graphql lives in its own schema.
| Extension | Role |
|---|---|
| vector | Embeddings and similarity search (pgvector). |
| pg_stat_statements | SQL execution statistics (preloaded at startup). |
| pg_graphql | GraphQL API (graphql schema, outside the REST API). |
On demand — contrib (dedicated instance)
Standard PostgreSQL 16 extensions, activable from the console on dedicated / cluster.
| Extension | Role |
|---|---|
| amcheck | B-tree index integrity checks. |
| autoinc | Auto-increment trigger (legacy contrib). |
| bloom | Bloom index for multi-column equality filters. |
| btree_gin | B-tree operator classes for GIN indexes. |
| btree_gist | B-tree operator classes for GiST indexes. |
| citext | Case-insensitive text (emails, identifiers). |
| cube | Multidimensional cube type (required by earthdistance). |
| dict_int | Full-text search dictionary for integers. |
| dict_xsyn | Synonym dictionary for full-text search. |
| earthdistance | Distance between points on a sphere (depends on cube). |
| fuzzystrmatch | Soundex, Levenshtein, metaphone (required by tiger). |
| hstore | Key/value pairs in a column. |
| insert_username | Trigger that records the current user. |
| intagg | Integer aggregates (legacy). |
| intarray | Operations and indexes on integer arrays. |
| isn | ISBN / ISSN / EAN types and related checks. |
| ltree | Hierarchical paths (categories, trees). |
| moddatetime | Automatic updated_at trigger. |
| old_snapshot | Inspection of old MVCC snapshots. |
| pageinspect | Low-level page inspection (admin). |
| pg_buffercache | PostgreSQL buffer cache contents. |
| pg_freespacemap | Free space map. |
| pg_prewarm | Preload relations into cache. |
| pg_visibility | Tuple visibility map. |
| pg_walinspect | WAL inspection. |
| pgrowlocks | Current row locks. |
| pgstattuple | Table fragmentation statistics. |
| refint | Referential integrity triggers (legacy). |
| seg | Number interval / segment type. |
| sslinfo | SSL session information. |
| tablefunc | crosstab and crosstab functions. |
| tcn | Triggered change notification. |
| tsm_system_rows | TABLESAMPLE SYSTEM_ROWS. |
| tsm_system_time | TABLESAMPLE SYSTEM_TIME. |
| unaccent | Accent stripping for search. |
On demand — Kuunda image (PostGIS, etc.)
Tenant image packages. PostGIS can take 1–2 minutes and RAM. Do not install it on the shared pool (the UI refuses).
| Extension | Role |
|---|---|
| postgis | Geographic types and functions (extensions schema). |
| postgis_raster | PostGIS rasters (depends on postgis). |
| postgis_sfcgal | SFCGAL 3D geometry if the package is present on the instance. |
| postgis_topology | PostGIS topology (topology schema, outside the REST API). |
| postgis_tiger_geocoder | TIGER geocoder (USA). tiger / tiger_data schemas. |
| address_standardizer | Postal address normalization. |
| address_standardizer_data_us | US ruleset (depends on address_standardizer). |
| hypopg | Hypothetical indexes for EXPLAIN. |
| pg_repack | Table reorganization without a long exclusive lock. |
Packaged, no UI (dormant)
| Extension | Role |
|---|---|
| pg_cron | Scheduled SQL jobs. No UI. Preload only on ops request. |
| pgaudit | SQL audit. Packaged, no console activation. |
Never offered
Isolation, attack surface or boot. Absent from the allowlist, including in the SQL editor.
| Extension | Role |
|---|---|
| dblink | Queries to another database (isolation leak). |
| postgres_fdw | PostgreSQL Foreign Data Wrapper. |
| file_fdw | Read server files. |
| http | HTTP calls from SQL. |
| pg_net | Async HTTP (Supabase). |
| wrappers | Supabase FDW wrappers. |
| pgsodium | Legacy Supabase crypto / vault. |
| supabase_vault | Supabase secrets vault. |
| plv8 | JavaScript in the server. |
| pljava | Java in the server. |
| plls | LiveScript in the server. |
| plcoffee | CoffeeScript in the server. |
| adminpack | pgAdmin admin tools. |
| lo | Server-side large objects. |
| xml2 | Legacy XML (risks). |
| pg_surgery | Destructive page repair. |
| pg_plan_filter | Plan filtering (unsupported). |
| safeupdate | Guard UPDATE/DELETE without WHERE (not packaged). |
| supautils | Third-party image internal utilities. |
Intentionally absent from the image
Not a “full Supabase” clone. Among the missing: pgroongarumpgroutingpgjwtpgmqindex_advisorpg_partmanpg_jsonschemapg_hashidspg_tle*_wrapper.
6. Dependencies and imposed schemas
Kuunda installs the listed dependencies, without CASCADE.
| Extension | Before |
|---|---|
| postgis_topology | postgis |
| postgis_raster | postgis |
| postgis_sfcgal | postgis |
| postgis_tiger_geocoder | postgis, fuzzystrmatch |
| address_standardizer_data_us | address_standardizer |
| earthdistance | cube |
Some extensions cannot be relocated into extensions (the .controlfile):
| Extension | Schema(s) |
|---|---|
| pg_graphql | graphql, graphql_public |
| postgis_topology | topology |
| postgis_tiger_geocoder | tiger, tiger_data |
| pg_cron | cron (if enabled by ops) |
postgis_tiger_geocoder
search_path to find the geometry type (PostGIS in extensions). The console handles this order. US geocoding only.7. Import from Supabase / pg_dump
Import rewrites extensions.* references to match the Kuunda search_path . The dump’s CREATE EXTENSION statements are not replayed as-is: first install the needed pieces via Database → Extensions (dedicated) the needed pieces (pgcrypto is already CORE).
Guide: Supabase migration · Data import.
8. FAQ
Can I paste CREATE EXTENSION vector like on Supabase?
On dedicated: use the UI (safe equivalent). On the shared pool: vector is already installed at provisioning; a second CREATE from the editor is blocked.
Where are uuid-ossp / pgcrypto if I come from public?
New creations go into extensions. Kuunda does not move an extension already created in public. The search_path covers both.
How long does PostGIS take?
Up to about two minutes. One CREATE at a time; a platform lock avoids races.
How do I get citext / PostGIS on an existing project?
Shared-pool projects stay catalog-read-only. You need a dedicated instance (support / plan change), then the Extensions screen.