---
title: Connect a warehouse
description: Connect Postgres, BigQuery, Snowflake, Redshift, Databricks, or SQL Server so your dashboards refresh from your own data on a schedule.
updated: 2026-08-04
tier: pro
engines: [postgres, bigquery, snowflake, redshift, databricks, sqlserver]
---

A dashboard can only refresh if there is something to re-query. Connecting a
warehouse is what turns a one-time dashboard into one that re-runs its own SQL on
a schedule with no AI in the loop.

Dashies calls these **data sources** in the app. The wire format, the API fields,
and the error strings call the same thing a **connection**, so both words appear
on these pages.

:::warning{title="Warehouse connections are a paid feature"}
Creating, testing, and resyncing a data source all require a paid plan. See
[what is gated](/concepts/plans-and-gating#what-is-gated). The
refusal is `403` with `A paid plan is required to connect a warehouse.` Deleting,
renaming, and rotating an existing one are not gated.
:::

## Pick your engine

| Engine | What it connects to | Page |
|---|---|---|
| PostgreSQL | Postgres or a Postgres-compatible warehouse. | [Postgres](/guides/connect-warehouse/postgres) |
| BigQuery | Google BigQuery, via a service account. | [BigQuery](/guides/connect-warehouse/bigquery) |
| Snowflake | Snowflake, via key-pair authentication. | [Snowflake](/guides/connect-warehouse/snowflake) |
| Amazon Redshift | Amazon Redshift, via the Data API. | [Redshift](/guides/connect-warehouse/redshift) |
| Databricks | Databricks SQL Warehouse, via the Statement Execution API. | [Databricks](/guides/connect-warehouse/databricks) |
| SQL Server | Microsoft SQL Server or Azure SQL. | [SQL Server](/guides/connect-warehouse/sqlserver) |

## What to have ready

Pick your engine below. The tab you choose is remembered across this whole site,
so every other page with engine tabs will open on the same one.

::::tabs{sync=engine}

:::tab{label="PostgreSQL"}
- A host reachable from the public internet, on port 5432, 5433, or 6543.
- The database name and the schemas you want to import.
- A read-only login. The connect form gives you the exact SQL to create one.

IP allow-listing is not supported. Full page:
[Connect PostgreSQL](/guides/connect-warehouse/postgres).
:::

:::tab{label="BigQuery"}
- The BigQuery project id Dashies reads from.
- A dedicated service account with BigQuery access, and its JSON key.

You paste the service account email and the private key separately, not the whole
JSON file. Full page: [Connect BigQuery](/guides/connect-warehouse/bigquery).
:::

:::tab{label="Snowflake"}
- Your account identifier in the hyphenated form, for example `myorg-myaccount`.
  The dotted org form is rejected.
- A dedicated read-only user with an RSA public key registered on it, and the
  matching PKCS#8 private key.
- The warehouse Dashies should run refresh queries on.

Full page: [Connect Snowflake](/guides/connect-warehouse/snowflake).
:::

:::tab{label="Amazon Redshift"}
- The AWS region, plus either a Serverless workgroup name or a provisioned
  cluster identifier.
- An IAM access key pair whose policy allows the Redshift Data API.
- A Secrets Manager ARN holding the read-only database user.

Two separate credentials. Full page:
[Connect Redshift](/guides/connect-warehouse/redshift).
:::

:::tab{label="Databricks"}
- Your workspace host, for example `dbc-xxxxxxxx-xxxx.cloud.databricks.com`.
- The SQL warehouse id.
- A service principal's client id and OAuth client secret.

Full page: [Connect Databricks](/guides/connect-warehouse/databricks).
:::

:::tab{label="SQL Server"}
- A host reachable from the public internet, on port 1433.
- The database name and the schemas you want to import.
- A read-only SQL login. This is a requirement, not a recommendation: the test
  refuses a login that can write.
- TLS with a certificate that validates. A self-signed certificate cannot
  connect.

Full page: [Connect SQL Server](/guides/connect-warehouse/sqlserver).
:::

::::

## Where to add one

You add a data source in the Dashies web app, never through your AI tool.
Credentials are entered in the app's own form and are never passed through the AI
or the publish service, which is why your AI cannot connect a warehouse for you.

Open [dashies.xyz/app/connections](https://dashies.xyz/app/connections), or use
the account menu, then **Data sources**.

Every form has an optional **Display name** field, hinted `Optional. Helps you
tell data sources apart.` and capped at 120 characters. Set it if you will have
more than one.

## Two connect shapes

Which one you get depends on the engine, and it changes what you do after
clicking Connect.

| Shape | Engines | What happens |
|---|---|---|
| Connect, then Test | PostgreSQL, SQL Server | Creating the data source proves Dashies can reach the warehouse and leaves it `pending`. You then click **Test** to run a real query and move it to `active`. |
| Connect only | BigQuery, Snowflake, Amazon Redshift, Databricks | Creating the data source runs the verification in the same round trip and comes back already `active`, with the databases or datasets it found. |

## Limits that apply to every engine

- **Five active warehouse data sources per scope.** The sixth is refused with
  `You have reached the maximum number of warehouse data sources.` Personal and
  each workspace count separately.
- **Twenty connection changes per minute.** Past that you get
  `Too many connection changes. Wait about a minute and try again.`
- **Credentials go into Supabase Vault.** The stored row keeps a pointer to the
  encrypted secret plus non-secret settings such as the host and database name.
  The secret value never appears in the row, an API response, a log line, or an
  audit entry.
- **Failures never echo your host, login, or driver text.** Every failure is
  classified into one of eight classes: `connection_auth`,
  `connection_unreachable`, `connection_timeout`, `ssl_failed`, `schema_drift`,
  `cube_error`, `tier_lapsed`, `connection_removed`.

:::danger{title="A data source belongs permanently to the scope it was created in"}
A data source is owned by the pair of you and the workspace you created it in,
and neither half can be changed afterwards. There is no move path in either
direction.

The consequence catches people out: a **workspace** dashboard cannot use a
**personal** data source, even though your AI can see that data source and its id
is real. Full explanation:
[the workspace trap](/concepts/connections-and-scope#the-workspace-trap). To use a warehouse on a team dashboard, create it from inside that
workspace.

Worse, on a spec publish this does not stop the publish. The dashboard goes live
at a real URL and only the refresh manifest is refused, leaving a dashboard that
can never update. See [Work as a team](/guides/work-as-a-team).
:::

## Two status fields, and why both exist

Each data source shows two independent facts. They disagree normally, and that is
not a bug.

- **Status** is what an explicit Test concluded: `pending`, `active`, or `error`.
  That test may be days old.
- **Health** is what the refresh cron or an authoring call last actually
  observed: `ok` or `failing`.

`active` plus `failing` is a normal reading. It means the last Test passed but a
real query since then did not, which usually means a credential expired or was
rotated. Health gates nothing.

## Check it worked

1. The data source's status reads **active** on
   [dashies.xyz/app/connections](https://dashies.xyz/app/connections).
2. Ask your AI tool to list connections and introspect the schema:

   > List my Dashies connections, then introspect the schema of the warehouse
   > one.

   You should get back the tables and columns of the schemas, datasets, or
   catalogs you allowlisted. An empty schema list means the login can reach the
   server but cannot see your tables, so re-check the grants on that page's
   setup script.

3. Then [author a dashboard against it](/guides/author-a-dashboard).
