The Postgres wire protocol endpoint is an experimental, enterprise-only feature.
- On Lightdash Cloud, availability is instance-dependent — contact Lightdash to enable it for your organization.
- On self-hosted deployments, admins enable it via the
PGWIRE_PORTenvironment variable and a valid enterprise license (see Enable the endpoint).
What it is
The Postgres wire protocol endpoint exposes your Lightdash semantic layer as a read-only Postgres database. Any standard Postgres client —psql, node-postgres, psycopg, JDBC drivers, SQL notebooks, and most BI tools — can connect, authenticate, and query your explores as if they were Postgres tables.
Behind the scenes, Lightdash parses the incoming SQL, compiles it into a MetricQuery, and runs it through the same query path as the explorer. That means:
- Project access controls, joins, metric definitions, and user attribute row-level rules apply exactly as they would in the Lightdash UI. The endpoint is not a warehouse passthrough — it’s a semantic-layer query interface.
- Metrics, dimensions, and joins are honored automatically. You reference field IDs (for example,
orders_total_order_amount), and Lightdash generates the correct warehouse SQL, including joins between explores. - Queries are read-only. Only
SELECTis supported — the endpoint cannot modify warehouse data.
- Query your semantic layer from a Python or Node script without going through the HTTP API.
- Connect BI tools or notebooks that speak Postgres but don’t have a native Lightdash integration.
- Use
psqlfor quick ad-hoc analysis against governed, semantically consistent data.
Enable the endpoint
Enabling the endpoint is a two-step process: the instance must expose a Postgres wire port, and each organization then opts in from its project settings.1. Enable the endpoint at the instance level
The Postgres wire protocol server lives in the enterprise codebase and only starts when both an enterprise license and thePGWIRE_PORT environment variable are configured.
- Self-hosted
- Lightdash Cloud
Set the following environment variables on the Lightdash backend:On startup Lightdash logs
Postgres wire protocol server listening on port 5433. Without a valid enterprise license the server logs a warning and does not listen, even if PGWIRE_PORT is set.PGWIRE_PORT— the TCP port the server binds to. Required.PGWIRE_HOST— optional. The hostname advertised to users in the project settings UI. If unset, the settings page shows an empty host and admins will need to fill it in themselves.
sslmode=disable, so we recommend terminating TLS in front of the endpoint or restricting it to a private network.2. Enable the endpoint for your organization
Once the instance exposes a pgwire port, each organization has to explicitly opt in. The setting is off by default.- Go to Project settings → Semantic layer (the tab only appears when the instance has pgwire enabled).
- As an organization admin, toggle Semantic layer Postgres connection on.
psql, and JDBC). Non-admins see the tab but not the connection details.
Connection details (host and port) are only returned to organization admins. The
enabled flag is visible to all org members so the settings tab can render correctly for everyone.Connect
Use any Postgres client. The Project settings → Semantic layer page shows the exact host, port, database (project UUID), and ready-to-copypsql, connection URL, and JDBC snippets for your instance — copy the snippet that matches your client and paste in a token as the password.
The connection parameters are:
Example: psql
Example: connection URL
Example: JDBC (DBeaver / DataGrip)
Authentication
The password must be one of:- Service account token (
ldsvc_prefix) — recommended for automation and production integrations. Create one from Settings → Service accounts. See Service accounts. Service accounts scoped only to SCIM are rejected. - Personal access token (
ldpat_prefix) — useful for interactive use. Create one from Settings → Personal access tokens. See Personal access tokens.
-U value is not used for authentication — the user identity is derived entirely from the token, so any placeholder works.
Choosing a database
The-d value can be either the project UUID (always unambiguous) or a slugified project name derived from the display name in Lightdash (for example, the project “Ecom Store” becomes ecom-store).
If two projects share the same slugified name, the endpoint returns error code 3D000 at connect time and lists the candidate UUIDs — use one of those UUIDs to connect.
What maps to what
Because explores already flatten joins in the semantic layer, joined-table fields appear as columns on the base explore — you do not (and cannot) write
JOIN clauses yourself.
Discovering tables and columns
The endpoint serves a virtualinformation_schema so clients and users can list explores and fields:
field_type column is a Lightdash extension that returns dimension or metric. Standard columns like column_name, data_type, and is_nullable behave the same as in real Postgres.
pg_catalog is not implemented. GUI schema browsers that rely on pg_catalog (for example, DBeaver’s schema tree) will show an empty catalog. Query information_schema instead, or use a client that respects it (for example, psql \dt and \d work).Example queries
The examples below assume an explore calledorders in an ecom-store project.
Basic query
orders_total_order_amount is a metric and orders_status is a dimension, Lightdash automatically:
- Adds
orders_statusto the group-by. - Runs the query through the metric definition (so aggregation logic lives in YAML, not the SQL you write).
- Applies the same permissions and user attributes as the Lightdash explorer.
Filtering on metrics (routed to HAVING)
Metric conditions in WHERE are automatically routed to metric filters, so this works:
HAVING explicitly — it maps to the same metric filters.
Table calculations
Expressions in theSELECT list become table calculations:
CASE expressions, window functions, and references to other calculations in the same query.
Supported SQL
The parser accepts a practical subset of Postgres SQL, focused on what maps cleanly onto a semantic-layer query:SELECT— including*, column aliases, and table-qualified names (orders.orders_status).WHERE—=,!=,<,<=,>,>=,IN/NOT IN,LIKE/ILIKE,BETWEEN,IS NULL/IS NOT NULL, boolean columns, and nestedAND/OR. Metric conditions are automatically routed to metric filters.HAVING— routed to metric filters.GROUP BY— optional (Lightdash groups by the selected dimensions automatically), but accepted.ORDER BY— on field IDs, ordinal positions, column aliases, and table calculations.NULLS FIRST/NULLS LASTare honored.LIMIT.- Table calculations — arithmetic, functions,
CASE, window functions, and references to other calculations in the same query. - Catalog discovery — virtual
information_schema.tablesandinformation_schema.columns(with an extrafield_typecolumn). - Session shims —
BEGIN,COMMIT,SET,SHOW,SELECT version(), andFROM-less selects (for example,SELECT 1) are accepted so that clients and drivers connect cleanly.
Not supported
The following are rejected by design, so that queries stay within the semantic-layer contract:- Extended query protocol / bind parameters — clients that force prepared statements will receive error code
0A000. Configure your driver to use the simple query protocol. pg_catalog— GUI schema browsers (for example, DBeaver’s tree) will not populate. Useinformation_schemainstead.- Explicit
JOINs — joins are defined in your explores; you cannot join tables in ad-hoc SQL. - Subqueries and CTEs.
- DML (
INSERT,UPDATE,DELETE,MERGE) and DDL — the endpoint is read-only. - Ad-hoc custom metrics — only pre-defined metrics from your semantic layer can be selected. Aggregate expressions like
count(*)orsum(...)in theSELECTlist are rejected. - Period-over-period and other Lightdash features that require additional query-time metadata beyond what SQL can express.
SELECT DISTINCTandOFFSET.
Errors
Errors are returned as standard PostgresErrorResponse messages, so your client’s error handling behaves normally.
Security and permissions
All queries flow through the same services as the Lightdash UI, so:- Every query is authorized against the caller’s project and space permissions.
- User attributes and row-level rules are applied to metric queries exactly as they are in the explorer.
- The endpoint is read-only — it cannot mutate warehouse data or Lightdash content.