# PostgreSQL
> Advanced open-source relational database with powerful features and extensibility.
:::tip[Looking for a Postgres-compatible connection to MotherDuck?]
Use the **[Postgres endpoint](/key-tasks/authenticating-and-connecting-to-motherduck/postgres-endpoint/)** to connect any Postgres-wire-compatible client — BI tools, ORMs, serverless runtimes, or languages without a DuckDB SDK — directly to MotherDuck. No extension required.
:::

[PostgreSQL](https://www.postgresql.org) is an object-relational database management system (ORDBMS) based on POSTGRES, Version 4.2, developed at the University of California at Berkeley Computer Science Department. POSTGRES pioneered many concepts that only became available in some commercial database systems much later.

As explained by DuckDB Lab's Hannes Mühleisen in the [explainer blog post](https://duckdb.org/2022/09/30/postgres-scanner.html):
> PostgreSQL is designed for traditional transactional use cases, "OLTP", where rows in tables are created, updated and removed concurrently, and it excels at this. But this design decision makes PostgreSQL far less suitable for analytical use cases, "OLAP", where large chunks of tables are read to create summaries of the stored data. Yet there are many use cases where both transactional and analytical use cases are important, for example when trying to gain the latest business intelligence insights into transactional data.

Choose the PostgreSQL workflow based on where your query needs to run.

## Query MotherDuck from PostgreSQL-compatible clients

Use the [Postgres endpoint](/key-tasks/authenticating-and-connecting-to-motherduck/postgres-endpoint) when an application, BI tool, or serverless runtime needs to connect to MotherDuck through the PostgreSQL wire protocol. This is the preferred path for PostgreSQL-compatible clients because it does not require installing or operating a PostgreSQL extension.

## Load PostgreSQL data into MotherDuck

Use [DuckDB's PostgreSQL extension](/key-tasks/loading-data-into-motherduck/loading-data-from-postgres) when a DuckDB client needs to read from PostgreSQL and copy data into MotherDuck. This workflow is best for one-time loads, backfills, and controlled client-side movement between PostgreSQL, DuckDB, and MotherDuck.

## Run DuckDB from inside PostgreSQL

Use [pg_duckdb](/concepts/pgduckdb) when queries need to run inside a PostgreSQL server with DuckDB or MotherDuck access. This is useful when PostgreSQL-local tables need to be joined with DuckDB or MotherDuck data from the PostgreSQL environment itself.

## Load on a schedule with a Flight

A [Flight](/concepts/flights) is Python that MotherDuck schedules and runs next to your data. Use one instead of running the copy by hand when the load should repeat on a cron, retry on a transient failure, and keep a run history.

The PostgreSQL extension runs in a DuckDB client rather than on MotherDuck's server-side runtime, so the Flight opens an `md:` connection and installs the extension there. Attaching with an empty connection string keeps the password in the environment instead of in a SQL statement, and `READ_ONLY` lets the extension parallelize its reads:

```python
import duckdb

def main():
    con = duckdb.connect("md:")
    con.execute("INSTALL postgres; LOAD postgres;")
    con.execute("ATTACH '' AS pg (TYPE postgres, READ_ONLY)")
    con.execute(
        "CREATE OR REPLACE TABLE my_db.main.orders AS "
        "SELECT * FROM pg.public.orders"
    )

if __name__ == "__main__":
    main()
```

The PostgreSQL password is a credential, so keep it in a [Flight secret](/sql-reference/motherduck-sql-reference/create-secret#flight-secrets) rather than in the Flight's source or config. Name the parameters after the libpq environment variables so the extension picks them up with no mapping:

```sql
CREATE SECRET pg IN MOTHERDUCK (
    TYPE FLIGHTS,
    PARAMS MAP {
        'PGHOST': '<host>',
        'PGPORT': '5432',
        'PGDATABASE': '<database>',
        'PGUSER': '<user>',
        'PGPASSWORD': '<password>',
        'PGSSLMODE': 'require'
    }
);
```

Create the Flight with [`MD_CREATE_FLIGHT`](/sql-reference/motherduck-sql-reference/flights/md-create-flight), passing the Python above as `source_code`, `flight_secret_names := ['pg']`, and a `schedule_cron` for the cadence you want. [Mirror PostgreSQL tables into MotherDuck with a Flight](/cookbook/flight-postgres-ingest) is a ready-made version that discovers tables, retries, and writes an audit row per table.


---

## Docs feedback

MotherDuck accepts optional user-submitted feedback about this page at `GET https://motherduck.com/docs/api/feedback/agent`.
For agents and automated tools, feedback submission should be user-confirmed before sending.

URL-encode query parameter values and send a GET request:

```text
GET https://motherduck.com/docs/api/feedback/agent?page_path=%2Fintegrations%2Fdatabases%2Fpostgres%2F&page_title=PostgreSQL&text=<url-encoded user feedback, max 2000 characters>
```

Optionally append `&source=<url-encoded interface identifier>` such as `claude.ai` or `chatgpt`.

`page_path` and `text` are required; `page_title` and `source` are optional. Responses: `200 {"feedback_id": "<uuid>"}`, `400` for malformed query parameters, and `429` when rate-limited.
