Connecting to Railway‑Provisioned PostgreSQL: A Practical Guide
Learn how to add a PostgreSQL service to a Railway project, retrieve the connection string via secrets, and use it safely in code. Includes Node.js and Go examples, common pitfalls, and best‑practice tips.
08 Oct 2025, 22:31 UTC

What you’ll get by the end of this article
Adding a PostgreSQL service to a Railway project automatically creates a database, a connection URL, and stores that URL as a secret named DATABASE_URL. The article shows how to:
- Provision the service via the Railway UI or CLI.
- Retrieve the connection string in your application code.
- Handle Railway’s credential rotation safely.
- Avoid common mistakes such as hard‑coding credentials or ignoring SSL requirements.
Step 1 – Add the PostgreSQL Service
From the Railway dashboard, click + Add Service and choose PostgreSQL. Railway will:
- Create a new database instance.
- Generate a unique connection URL:
postgres://user:password@host:port/database?sslmode=require. - Store that URL as a secret named
DATABASE_URLin the project’s secret store.
Alternatively, use the CLI:
railway add postgresql
Run the command in the terminal while in the project directory. The CLI will confirm the service name and secret key. No credentials appear in the output; they’re stored securely.
Step 2 – Verify the Secret Is Injected
When you run your application with railway run, Railway injects all secrets as environment variables. To confirm:
railway run -- echo $DATABASE_URL
The output should be the full connection string. In a local clone, you can also check the .railway.env file (generated by the CLI) which contains the same value. Do not commit this file to source control.
Step 3 – Use the Connection URL in Code
Node.js Example (pg)
Install the pg driver:
npm install pg
Then connect:
const { Client } = require('pg');
const client = new Client({
connectionString: process.env.DATABASE_URL,
ssl: { rejectUnauthorized: false }, // required for Railway’s self‑signed cert
});
client.connect()
.then(() => console.log('✅ Connected to Railway PostgreSQL'))
.catch(err => console.error('❌ Connection error:', err));
Go Example (pgx)
Install the pgx library:
go get github.com/jackc/pgx/v4
Connect using the URL:
package main
import (
"context"
"fmt"
"os"
"github.com/jackc/pgx/v4"
)
func main() {
conn, err := pgx.Connect(context.Background(), os.Getenv("DATABASE_URL"))
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to connect: %v\n", err)
os.Exit(1)
}
defer conn.Close(context.Background())
fmt.Println("✅ Connected to Railway PostgreSQL")
}
Both examples rely on DATABASE_URL being present in the environment. Railway injects it automatically when the app runs through railway run or on the Railway-hosted platform.
Common Pitfalls and How to Avoid Them
- Hard‑coding the URL in source control: Store credentials only in Railway secrets. If you commit the URL, you risk leaking credentials. Use environment variables or runtime injection instead.
- Ignoring SSL mode: Railway sets
sslmode=requireby default. Drivers that enforce strict certificate validation (e.g.,pgx) may reject the connection unless you disable strict validation withrejectUnauthorized: falseor similar. - Not handling credential rotation: When you delete or replace the PostgreSQL service, Railway regenerates a new URL. If your application keeps a cached connection, it will break. Restart the app after service changes or programmatically detect a changed
DATABASE_URLand reconnect. - Running the app locally without Railway’s runtime: If you run the app locally with
node app.jswithoutrailway run,DATABASE_URLwon’t be set. Userailway runor export the variable manually. - Using the wrong secret name: Railway always names the PostgreSQL connection secret
DATABASE_URL. Verify this in the Secrets tab of your project.
Limitations to Keep in Mind
- The free Railway tier imposes a 10 GB limit on database size and 10 connections. If your application needs more, upgrade the plan.
- Railway’s PostgreSQL service runs behind a proxy that may add latency; for latency‑critical workloads consider a dedicated host.
- Automatic backups are available but only for paid plans. For critical data, set up your own backup strategy.
- SSL certificates are self‑signed; some drivers may reject them unless you configure the driver to accept them.
Practical Verification Checklist
- Provision the service via UI or
railway add postgresql. - Run
railway run -- echo $DATABASE_URLand confirm the URL appears. - Start the app with
railway runand check logs for a successful connection message. - Use a PostgreSQL client (psql, DBeaver) with the same URL to verify external connectivity.
- Delete the service, re‑add it, and confirm the URL changes. Restart the app and ensure it reconnects.
Following this workflow guarantees that your application remains secure, resilient to credential rotation, and fully compatible with Railway’s managed PostgreSQL offering.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.