Connecting, at a glance
You can connect any PostgreSQL database, including Supabase, Neon, RDS, and Cloud SQL. Dreamlit uses the connection for two things: building and diagnosing your user funnel, and hooking into key events in real time to kick off email workflows, with no code for your engineering team to instrument. It is best practice to create a separate database user for each service that connects to your database, following security principles of least privilege and isolation. That way you can see exactly what each one is allowed to do, and revoke any of them independently. To create one for Dreamlit, you can run the following SQL, replacing<SECRET_PASSWORD> with a strong, unique password:
Read-only access
Thedreamlit_readonly user has read access and nothing else. It can’t insert, update, delete, or alter anything, and it can’t create databases or other users. No changes are ever made to your data.
Read access is what lets Dreamlit build your funnel and render email previews with real rows. By default it’s granted through pg_read_all_data, PostgreSQL’s built-in read-only role, which covers tables you add later without touching the grant again.
If you’d rather limit it further, grant SELECT on specific tables instead:
Replication
Replication access is what lets a workflow start the moment something happens, instead of on a polling schedule. It works through PostgreSQL logical replication using wal2json, the same mechanism your database uses for its own replicas. By default, nothing is replicated. Connecting the user creates no replication slot and follows no tables. Only when a workflow goes live does Dreamlit subscribe to that workflow’s trigger table. Tables with no live workflow are never streamed. No data is retained. The change feed is not copied anywhere. Each change is evaluated against the live workflows and discarded. The only thing that persists is the state a running workflow needs to finish, such as which user it’s emailing and which step it’s on, and that lives only as long as the run. It’s robust to outages. If the connection drops, or Dreamlit is briefly unavailable, your database queues the changes in the slot until we reconnect, then Dreamlit picks up exactly where it left off. Nothing is missed, and nobody gets the same email twice. The queue is bounded by yourmax_slot_wal_keep_size setting, so it can’t grow without limit.
To see what Dreamlit is currently subscribed to, run this on your database:
active column shows whether Dreamlit is connected right now.