Connect · Railway
Connect to Railway Postgres from your Mac
Railway databases are private by default. Either add Public Access in the service’s Networking settings and use DATABASE_PUBLIC_URL, or run railway connect postgres --tunnel-only and connect to the local tunnel.
Updated 9 October 2026
What you need
- A PostgreSQL service in your Railway project (added from the
+ Newbutton or the ⌘K menu on the project canvas). - One way in from your Mac:
- Public Access, which gives the database a TCP proxy address on the internet, or
- the Railway CLI, which can open an SSH tunnel to a database that has no public address.
Find your connection details
The PostgreSQL service exposes its details as variables: PGHOST, PGPORT, PGUSER,
PGPASSWORD, PGDATABASE and DATABASE_URL. Those point at Railway’s private network, so they
only work from other services in the project.
Public Access. Railway deploys databases private by default. To reach one from your Mac, open
the service’s Settings → Networking and add Public Access. Railway creates a TCP proxy, a
generated host and port such as shuttle.proxy.rlwy.net:15140, and fills in a
DATABASE_PUBLIC_URL variable with the external connection string. Railway bills network egress
through the TCP proxy.
Tunnel instead. If you’d rather not expose the database, the CLI can tunnel to it over SSH:
railway connect postgres --tunnel-only
It prints the host, port, user, password, database and full connection URL for the local end of
the tunnel, and keeps the tunnel open until you press Ctrl-C. Railway suggests this for pointing a
GUI client at the database. Without --tunnel-only, railway connect opens psql directly.
Connection string
DATABASE_PUBLIC_URL has the usual form, with the proxy’s host and port:
postgresql://<user>:<password>@<proxy-host>.proxy.rlwy.net:<proxy-port>/<database>
The port is the one Railway generated, not 5432. If you point your own domain at the proxy with a CNAME, keep Railway’s port. See PostgreSQL connection strings.
TLS
Railway runs its own SSL-enabled PostgreSQL image, because the official Docker image doesn’t turn
TLS on. According to that image’s repository, it creates its own certificate authority and server
certificate when the database is first set up (and replaces them on a restart or redeploy when
they’re within 30 days of expiry). The certificate names localhost and the service’s private
host name, not the public proxy host.
So sslmode=require works and encrypts the connection, but verify-ca and verify-full can’t
succeed against the certificates macOS trusts. The TCP proxy forwards raw TCP, so the TLS session
runs between your client and the database itself.
Connect with Inlet
- Copy
DATABASE_PUBLIC_URLfrom the service’s variables and paste it into Inlet; Inlet fills in the connection form. If you usedrailway connect postgres --tunnel-only, paste the URL it printed instead, and leave the tunnel running while you work. You can also choose New Connection and type the fields. - Under TLS, choose
require. - Save the password in the Keychain, or have Inlet ask for it each time.
- Tag the environment. A production connection opens read-only, so the server refuses writes until you unlock it for ten minutes.
Connect from the command line
The CLI finds the right variables and starts psql for you (it needs psql installed):
railway connect postgres
For another environment, add --environment staging. Or use the public URL directly:
psql "postgresql://<user>@<proxy-host>.proxy.rlwy.net:<proxy-port>/<database>?sslmode=require"
Homebrew’s libpq package includes psql (keg-only: /opt/homebrew/opt/libpq/bin/psql).
Troubleshooting
- Connection refused or a timeout with the
DATABASE_URLhost: that’s the private address. UseDATABASE_PUBLIC_URL, or the tunnel. - Wrong port: the TCP proxy has its own port; 5432 won’t work on the proxy host.
verify-fullfails: expected, because the certificate comes from the database’s own authority and doesn’t name the proxy host. Userequire.- password authentication failed: copy the password again from the variables, and percent-encode special characters in a URL; see special characters in passwords.
- The tunnel closed:
--tunnel-onlyholds it open only while the command runs.