---
title: "Custom tables"
canonical_url: "https://docs.getdx.com/custom-tables/"
md_url: "https://docs.getdx.com/custom-tables.md"
last_updated: "2026-05-22"
---

# Custom tables
Custom tables make it possible to load and query additional data in DX alongside connector data, enabling a unified view of engineering metrics from any source. The Data Cloud Postgres instance includes a `custom` schema for creating tables and indexes, named like `custom.my_data` or `custom.my_other_data`.

Custom tables offer several advantages for teams that need to incorporate their own data into DX:

- **Available everywhere**: Custom tables are accessible in [Data Studio](https://docs.getdx.com/data-studio/) queries and reports, making it easy to build dashboards on additional data alongside connector data.
- **Performance at scale**: Indexes can be defined on custom tables to keep queries fast as data grows.
- **Join with connector data**: Custom tables can be joined with data from connectors (e.g. `github_pulls`, `jira_issues`) in a single query, providing a complete picture across all data sources.

## Getting started

Custom tables must reside in the `custom` schema—tables cannot be created in other schemas or in the default `public` schema. Foreign key constraints that reference DX-managed tables are not supported.

#### Step 1 – Create a database user

A database user with `read_write` scope is required. To create and manage database users, see [DB users](https://docs.getdx.com/db-users/).

#### Step 2 – Create a table in the `custom` schema

Connect to the database with the `read_write` credentials and create a table using standard SQL. All tables must be prefixed with `custom.`.

```sql
CREATE TABLE custom.my_table (
  id         SERIAL PRIMARY KEY,
  name       TEXT NOT NULL,
  created_at TIMESTAMPTZ DEFAULT NOW()
);
```

#### Step 3 – Add indexes

Define indexes on columns frequently used in filters and joins to keep queries fast as data grows.

```sql
CREATE INDEX idx_my_table_name ON custom.my_table (name);
```

#### Step 4 – Load data

Use an ETL process, script, or direct `INSERT` statements via the `read_write` user to populate the table.

```sql
INSERT INTO custom.my_table (name)
VALUES ('example-record');
```

#### Step 5 – Query in Data Studio

Custom tables are accessible in [Data Studio](https://docs.getdx.com/data-studio/) queries and reports, and can be joined with connector data (e.g. `github_pulls`, `jira_issues`) in a single query.

## Example: joining custom data with connector data

Suppose an internal tool exports manual deployment approvals into Data Cloud. The following example creates a table for that data, adds indexes for common query patterns, loads a record, and joins it with the `deployments` connector table in a report.

```sql
-- Create the table
CREATE TABLE custom.deployment_approvals (
  id            SERIAL PRIMARY KEY,
  deployment_id TEXT NOT NULL,
  approver      TEXT,
  approved_at   TIMESTAMPTZ NOT NULL,
  source_system TEXT DEFAULT 'internal-approval-tool'
);

-- Add indexes for time-based and join-heavy queries
CREATE INDEX idx_deployment_approvals_approved_at
  ON custom.deployment_approvals (approved_at);
CREATE INDEX idx_deployment_approvals_deployment_id
  ON custom.deployment_approvals (deployment_id);

-- Load data
INSERT INTO custom.deployment_approvals (deployment_id, approver, approved_at)
VALUES ('deploy-1234', 'alice', '2025-03-01T10:00:00Z');

-- Join with connector data in a Data Studio report
SELECT d.id, d.environment, a.approver, a.approved_at
FROM deployments d
JOIN custom.deployment_approvals a ON a.deployment_id = d.id
WHERE d.completed_at >= NOW() - INTERVAL '7 days';
```
---

## Sitemap

[Overview of all docs pages](/llms.txt)
