psql and PostgreSQL protocol connections
Connect to your database with existing PostgreSQL tools. Use your login session, or issue credentials for a system.
The fastest way
runlot pg shellThis command finds psql and connects to your database. Anything you pass after -- goes straight to psql.
runlot pg shell -- -c "select count(*) from posts"The password is passed through the PGPASSWORD environment variable, because command-line arguments are visible to other users on the same machine via ps.
Connecting through a local port
Port forwarding is convenient for GUI clients and other tools.
runlot port-forwardForwarding 127.0.0.1:15432 to the me/my-app database.
Connect with psql "postgresql://…@127.0.0.1:15432/…". Press Ctrl-C to stop.runlot port-forward --port 5555 --listen 127.0.0.1
runlot port-forward --port 0 # picks an available port automaticallyThe password never reaches your local machine. Port forwarding uses your runlot login session. The CLI only receives connection details (host, port, database name); authentication happens at the front using your login session. If the token expires or you are removed from the organization, the next connection is rejected.
Connecting directly from outside
Where runlot login is not available — an external BI tool, or an app running on another hosting environment — issue credentials with pg token.
postgresql://<user>:<password>@<project>--<org>.wire.runlot.app:5433/<database>?sslmode=requireThe port number is 5433. The hostname carries the project and organization joined by --; that is how the front knows which project's database to open before any credentials are sent. runlot pg connect prints the exact value.
TLS
In libpq, sslmode=require means encryption only, with no certificate verification. To verify the certificate as well, point at a CA directory.
runlot pg shell --ca-dir ./ca # or RUNLOT_CA_DIRSNI is always required, whether or not you verify the certificate. The front uses SNI to determine the target project, so turning SNI off makes the connection impossible.
Driver compatibility
Binary results are supported. Binary parameters are not: a Bind that marks any parameter as binary is refused with 0A000 binary parameter format is not supported. That one line decides which drivers work as they are.
| Driver | Works | What to know |
|---|---|---|
psql | Yes | Text throughout. Nothing to configure. |
node-postgres (pg) | Yes | It sends every parameter as text, so parameterised queries are fine. |
| Drizzle · Kysely · Prisma · TypeORM · Knex · Sequelize | Yes | Inside a worker, through @runlot/pg — no wire protocol involved. |
| psycopg 3 | Partly | Queries with no parameters, and text parameters, work. A Python int is dumped as a binary parameter, so cur.execute("… %s", (7,)) is refused. cursor(binary=False) does not help — that option is about results. Pass cursor_factory=ClientCursor to bind on the client side. |
| pgx · Npgsql · JDBC · asyncpg | Partly | They read binary results, which now works, so a query with no parameters succeeds. They send typed parameters in binary, which is refused. |
psql, node-postgres and psycopg 3.Binary parameter support is on the roadmap. Until it lands, send parameters as text with one of the options above.
Authentication methods
The front identifies the project from SNI and then completes authentication immediately after the connection starts. The following credentials are available.
| For | Credential | Where it is used |
|---|---|---|
| Users | runlot login session | runlot port-forward, dashboard SQL editor |
| Systems | Password in the connection string | External BI tools, apps on other hosting environments |
Any runlot_* startup parameters sent by the client are stripped at the front, and only verified role information is added back. A client cannot forge a role.