Skip to main content
Dreamlit integrates seamlessly with your PostgreSQL database, allowing you to trigger notification workflows based on row changes (inserts/updates).
If you’d like to learn more about how Dreamlit works overall, check out the How it works page.

Adding a connection

To add a connection:
  1. Go to SettingsDatabase Connections.
  2. Click + Add connection.
  3. Paste your PostgreSQL URL (e.g., postgresql://user:password@host:5432/database) into any field. Dreamlit will automatically parse and fill in the required fields.
  4. Verify all details, and configure SSL settings if necessary.
  5. Click Test Connection to ensure it works before saving.
  6. Click Save.
Configuring your Postgres database connection in Dreamlit

Configuration panel for Postgres in the settings connections page

Dreamlit requires an IPv4 compatible connection to your database. To ensure optimal performance, we strongly recommend using a connection pooler like Pgbouncer in transaction mode and connecting through that instead of directly to your database.

How Dreamlit configures your database

Dreamlit’s notification architecture is optimized for the performance and robustness of your workflows. Your database is minimally instrumented accordingly. The very first time you set up a database connection, Dreamlit creates a dreamlit schema (if it doesn’t already exist) and an event_log table inside it. Then, whenever you publish a workflow containing a Database Trigger step, Dreamlit creates:
  1. A table trigger on the specified table, which activates whenever a relevant insert or update occurs.
  2. A trigger function in the dreamlit schema that runs when the trigger fires, which simply logs a row to the dreamlit.event_log table indicating that a new event has occurred.
From there, Dreamlit efficiently monitors the dreamlit.event_log table, and whenever it sees a new row matching an active trigger, it launches the associated workflow.
In addition to the event_log table, Dreamlit may create other small housekeeping tables in the dreamlit schema. It never writes to your existing tables (beyond installing triggers).
A schema is a grouping of tables, functions, and other database objects. It’s a way for you organize your tables, often for security reasons. See here for more.Dreamlit manages its objects in a dedicated schema so that it provides a clean separation between your application and the Dreamlit-managed objects. Dreamlit’s approach allows for events to be detected in realtime, while ensuring events don’t get lost. This separate schema approach is inspired by similar techniques used in other tools like Supabase and Hasura.

Permissions needed

The Postgres user provided to Dreamlit must at least have the following permissions:
  • Read relevant tables (SELECT).
  • Create triggers on tables that launch workflows.
  • Manage its own dreamlit schema for housekeeping and logging.
Of course, if you already have a user with the sufficient privileges (such as a superuser) you can use that. However, it is best practice to create a separate Postgres user for each service that needs access to your database, following the principles of isolation and least privilege. As such, we recommend following the steps below to create a dedicated user with the minimum permissions required for Dreamlit.
If you’re using a wire-compatible Postgres database, like CockroachDB or Google Spanner, these steps won’t work for you, as the commands below are not fully implemented by your database. Instead, please reach out to us and we can provide custom instructions.
Below is a guide to create a dedicated user with the minimum permissions required for Dreamlit. Run these SQL commands in your database:

1. Create a dedicated Dreamlit user

First, we create a new database user specifically for Dreamlit with a secure password. Be sure to replace <SECRET_PASSWORD> below with a strong, unique password.
CREATE USER dreamlit_user WITH PASSWORD '<SECRET_PASSWORD>';

2. Grant ability to create and manage the dreamlit schema

Next, we allow the Dreamlit user to create and manage the dreamlit schema within your database. Be sure to replace <YOUR_DATABASE_NAME> below with the name of your database (e.g., defaultdb or postgres).
GRANT CREATE ON DATABASE <YOUR_DATABASE_NAME> TO dreamlit_user;

-- if `dreamlit` schema already exists (like if you already setup a Dreamlit connection previously to the database with a different user), you need to run the following:   
GRANT dreamlit_user TO <OLD_OWNER_USER_NAME>; -- needed to run the commands below. This grants membership of the old owner (for ex, "postgres" user) of `dreamlit` schema objects to dreamlit_user.
ALTER SCHEMA dreamlit OWNER TO dreamlit_user;
ALTER TABLE dreamlit.event_log OWNER TO dreamlit_user;
ALTER TABLE dreamlit.version OWNER TO dreamlit_user;

3. Grant view access and trigger creation permissions

Finally, we need to ensure the Dreamlit user has view and trigger creation access to the tables you’d like to build workflows on. Run the commands below for each schema, replacing <YOUR_SCHEMA_NAME> with each schema name (e.g., public).
GRANT USAGE, CREATE ON SCHEMA <YOUR_SCHEMA_NAME> TO dreamlit_user;
GRANT SELECT, TRIGGER ON ALL TABLES IN SCHEMA <YOUR_SCHEMA_NAME> TO dreamlit_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA <YOUR_SCHEMA_NAME> GRANT SELECT ON TABLES TO dreamlit_user; -- ensures future tables created will be readable for this user by default
If any of your tables have RLS enabled (common for Supabase projects if you use the “anon” role), you must create policies that allow the newly created dreamlit_user to SELECT rows. Otherwise, you won’t be able to read the data needed for your Dreamlit workflows. If you’re not sure, you can run the following command to check which tables have RLS enabled:
-- First, check which tables have RLS enabled
SELECT schemaname, tablename, rowsecurity 
FROM pg_tables 
WHERE schemaname = '<YOUR_SCHEMA_NAME>' AND rowsecurity = true;
If the above query returns any rows, then you have RLS enabled and you’ll need to create a policy for each table that allows the dreamlit_user to SELECT rows. Run the following command to generate the policy creation commands for all RLS-enabled tables:
-- Generate CREATE POLICY commands for all RLS-enabled tables
SELECT 'CREATE POLICY dreamlit_user_select_policy ON ' || schemaname || '.' || tablename || 
      ' FOR SELECT TO dreamlit_user USING (true);' as policy_command
FROM pg_tables 
WHERE schemaname = '<YOUR_SCHEMA_NAME>' AND rowsecurity = true;
Finally, copy and execute the commands returned from the above query. For future tables: Unfortunately, PostgreSQL doesn’t support default RLS policies like it does for privileges. You’ll need to remember to create a policy whenever you add a new table with RLS enabled.

4. Construct your new connection string

Construct your PostgreSQL connection string using the dreamlit_user and the <SECRET_PASSWORD> you created. Provide this string to Dreamlit.
Use the Pooler connection details from your Supabase dashboard. You must add your Project Ref to the username.
postgresql://dreamlit_user.<YOUR_PROJECT_REF>:<SECRET_PASSWORD>@<SUPABASE_POOLER_HOST>:<POOLER_PORT>/postgres
  • Replace <YOUR_PROJECT_REF>, <SUPABASE_POOLER_HOST>, and <POOLER_PORT> (usually 6543) with values from your Supabase Database settings.
Use the Pooled connection details from your Neon dashboard. The username is just dreamlit_user.
postgresql://dreamlit_user:<SECRET_PASSWORD>@<NEON_POOLED_HOST>:<NEON_PORT>/<NEON_DB_NAME>
  • Replace <NEON_POOLED_HOST>, <NEON_PORT>, and <NEON_DB_NAME> with values from your Neon Connection Details.
Use your standard database connection details.
postgresql://dreamlit_user:<SECRET_PASSWORD>@<YOUR_DATABASE_HOST>:<PORT>/<YOUR_DATABASE_NAME>
  • Replace <YOUR_DATABASE_HOST>, <PORT> (usually 5432), and <YOUR_DATABASE_NAME> with your database’s connection details.
Connect to your pooler’s address. The database name might be an alias defined in the pooler config.
postgresql://dreamlit_user:<SECRET_PASSWORD>@<YOUR_POOLER_HOST>:<POOLER_PORT>/<DB_NAME_ALIAS_IN_POOLER>
  • Replace <YOUR_POOLER_HOST>, <POOLER_PORT> (e.g., 6432), and <DB_NAME_ALIAS_IN_POOLER> with your pooler’s specific details. Check pooler configuration if unsure.
Copy the correctly formatted connection string and paste it into the Dreamlit connection setup field.
If you’d like to drop the dreamlit_user, you can issue the following commands:
  REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM dreamlit_user;
  REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public FROM dreamlit_user;
  REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public FROM dreamlit_user;
  REVOKE USAGE ON SCHEMA public FROM dreamlit_user;
  REVOKE ALL ON SCHEMA public FROM dreamlit_user;
  REVOKE ALL ON DATABASE postgres FROM dreamlit_user;
  ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE SELECT ON TABLES FROM dreamlit_user;

DROP USER dreamlit_user;

Protecting notifications from breaking schema changes

When you make database schema changes, such as renaming or dropping tables or columns, you risk accidentally breaking notifications linked to your Dreamlit workflows. To help you avoid silently breaking notifications, Dreamlit provides two protective options:
You can install a protective event trigger directly in your database.This trigger monitors schema-altering commands (DROP, ALTER) and cross-references them with metadata stored in a dedicated dreamlit schema table. If the schema object you’re modifying is referenced by an active workflow, the trigger raises an exception and prevents the change.Currently in beta. Reach out to us and we can supply you with the SQL to install the trigger in your database.
Alternatively, you can integrate schema validation as part of your CI process. Dreamlit offers a validation step you can run in your preview or staging environments.This step compares your database schema against the expected schema required by your Dreamlit workflows, catching any potential breaking changes before they reach production.Currently in beta. Reach out to us if you’d like access to this feature.

Making the schema change safely

To ensure a smooth transition to a new schema for an otherwise breaking change, we recommend one of the following approaches:
If you don’t mind brief downtime for your workflows, this is the quickest approach.
  1. Unpublish any workflows referencing the old column/table.
  2. Apply your schema update.
  3. Adjust your Dreamlit workflow steps to reference the new schema.
  4. Publish your workflow again.
You can follow the “expand, migrate, and contract pattern” to make your schema changes.
  1. Add new columns or tables.
  2. Write to both old and new columns from your application.
  3. Backfill data into the new columns or tables.
  4. Update your Dreamlit workflow to reference the new columns/tables, and possibly update your application to reference the new columns/tables.
  5. Remove (or rename) the old columns/tables once no longer needed.
This approach avoids downtime for dependent workflows.

Uninstalling Dreamlit

If you ever want to remove Dreamlit entirely:
  1. Unpublish all workflows that depend on your Postgres connection (this removes triggers/functions).
  2. Delete the connection in the Dreamlit dashboard.
  3. (Optional) Drop the dreamlit schema to remove all Dreamlit-managed objects.
That’s it! By connecting Postgres to Dreamlit, you can create powerful, real-time workflows triggered by database changes — without writing any custom code in your application.