SaaS
Deploy a Next.js app with Prisma and Postgres on Railway
Host a Next.js app and Postgres together on Railway: plan limits, Prisma migrations, the DATABASE_URL reference variable, and keeping Stripe webhooks awake.
Disclosure: the “Create a Railway account” links in this article are referral links. If you sign up through one and become a paying Railway customer, Designyff earns a commission and you get Railway’s sign-up credit. The pricing link and every other link are ordinary links. Nothing here was paid for by Railway.
The Designyff SaaS guides stop at “deploy on Vercel or a Node host.” That is fine until the app needs Postgres in production. Then you are choosing two things at once: where the Next.js server runs, and where the database lives. Railway is one of the few hosts where both sit in the same project, on the same private network, under one bill.
This guide covers what changes when a Next.js + Prisma + Postgres app moves to Railway. It is not a list of every host. It covers the four settings that decide whether the deploy works: standalone output, the DATABASE_URL reference variable, a pre-deploy prisma migrate deploy, and keeping the webhook service awake. It also covers which plan you actually need.
If you already know you want this setup, create a Railway account and deploy the app plus Postgres.
When Railway is the right host for this stack
Pick Railway when you want a long-running Node server and a Postgres database you do not have to wire across providers. In this case:
- The app runs as a normal
nodeprocess, not as per-request functions. Route handlers, server actions, and the Stripe webhook all live in one service. - Postgres is a service in the same project. The app reads its URL through a reference variable, so a rotated password does not break production.
- Traffic between the app and the database can stay on the private network. Railway’s cost-control docs note that using
DATABASE_URLinstead ofDATABASE_PUBLIC_URLavoids network egress charges.
Pick something else when you need a free production tier, or when your traffic is so spiky that per-request billing on a serverless host is cheaper than a process that is always on.
Railway vs Vercel when you need Postgres
Vercel no longer sells its own Postgres. Vercel’s docs say Vercel Postgres is no longer available and new projects install a Postgres integration from the Marketplace instead. That works well. It still means two vendors, two dashboards, and a database reached over the public internet.
On Railway the database is part of the project. That is the whole difference for this stack. It does not make Railway faster or cheaper in every case. It makes the setup shorter and keeps the moving parts in one place.
Railway pricing for a small SaaS (as of 8 October 2026)
Railway bills a monthly plan fee plus per-second usage. The plan fee comes with the same amount of usage credit. These numbers are from railway.com/pricing and the plans docs. Check that page before you rely on them, because they change.
| Free | Hobby | Pro | |
|---|---|---|---|
| Monthly fee | $0 | $5 | $20 per workspace |
| Included usage | $1/month | $5/month | $20/month |
| Max CPU / RAM per service | 1 vCPU / 0.5 GB | 48 vCPU / 48 GB | 1,000 vCPU / 1 TB |
| Max volume size | 500 MB | 5 GB | 1,000 GB |
| Replicas | 1 | 6 | 42 |
| Log history | 3 days | 7 days | 30 days |
| Custom domains | 0 | 2 | 20 |
| Members per project | 1 | 3 | Unlimited |
New accounts start on a Free Trial: a one-time $5 credit that expires after 30 days, with up to 2 vCPU / 1 GB per service. You do not need a card for it.
Usage beyond the included credit is billed at these rates:
| Resource | Rate | About per month |
|---|---|---|
| Memory | $0.00000386 per GB/s | $10 per GB |
| CPU | $0.00000772 per vCPU/s | $20 per vCPU |
| Volume storage | $0.00000006 per GB/s | $0.15 per GB |
| Egress | $0.05 per GB | n/a |
Which plan a real SaaS needs
Free is not a SaaS host. It allows 0 custom domains, 0.5 GB of RAM per service, and 500 MB of volume. Use it to try the deploy, not to take payments.
Hobby is the realistic starting point. You get 2 custom domains, a 5 GB volume for Postgres, and $5 of usage. Do the arithmetic before you assume $5 covers it. At $10 per GB-month, one service holding 512 MB of RAM all month uses about $5 of memory on its own, before CPU. A Next.js service and a Postgres service both running all month can go over the included $5. Railway then bills the difference. Its docs give the example: $7 of usage on Hobby is a $7 bill.
Pro is for a team (members are unlimited and included in the workspace fee), for log history longer than 7 days, or for a database larger than 5 GB.
Set a usage limit on day one. Railway lets you set an email alert and a hard limit for compute usage, and the minimum hard limit is $10 (cost control). A hard limit takes your workloads offline when you hit it, so set it above what a normal month costs, not at it.
Step 1: Build Next.js as a standalone server
Railway’s Next.js guide asks for standalone output:
// next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
output: "standalone",
};
export default nextConfig;
and a start script that runs the standalone server:
{
"scripts": {
"build": "prisma generate && next build",
"start": "node .next/standalone/server.js"
}
}
Two details catch people here:
- Static files. Next.js documents that the standalone
server.jsdoes not copypublicor.next/staticby default. Railway’s Dockerfile in the same guide copies both into the image. If you build without that Dockerfile and your CSS or images 404 after deploy, this is the first thing to check. - Prisma Client. Run
prisma generateas part of the build, as shown above, so the client that ships matches your schema.
If you would rather control the image, use the Dockerfile from Railway’s guide. Railway detects a Dockerfile in the repo root and builds with it.
Step 2: Add Postgres and reference DATABASE_URL
In the Railway project, click + New → Database → PostgreSQL. The database service exposes DATABASE_URL and the usual PG* variables.
Do not copy and paste the connection string into your app service. In the Next.js service, open Variables → Add Reference Variable and pick DATABASE_URL from the Postgres service. Railway’s guide describes this as a reference that stays in sync if the database credentials change. Redeploy once so the new variable is picked up.
Your Prisma schema does not change:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
If you started on the Next.js SaaS Boilerplate, its schema uses SQLite. Switch provider to postgresql before this step. A SQLite file on a container disk is not a production database.
Want the database close to EU users? Railway has an EU West Metal region in Amsterdam (europe-west4-drams3a), next to US West, US East, and Singapore (regions). Put the app and Postgres in the same region. A volume follows the region of its service, and moving a service that has a volume means a migration with downtime.
Step 3: Run prisma migrate deploy before each release
Railway runs a pre-deploy command in a separate container that has your service’s environment variables, before the new version starts taking traffic. In the Next.js service go to Settings → Deploy → Pre-deploy Command and set:
npx prisma migrate deploy
migrate deploy applies migrations that are already committed in prisma/migrations. It does not create them. That matters for the Designyff kits. Their READMEs use npx prisma db push for local setup, and db push does not write migration files. Before your first Railway deploy, create a baseline locally and commit it:
npx prisma migrate dev --name init
git add prisma/migrations
git commit -m "Add initial Prisma migration"
After that, every schema change is a migrate dev locally, a commit, and an automatic migrate deploy on Railway. Do not run db push against the production database. The SaaS database schema article covers the same rule.
The pre-deploy container cannot see volumes. Prisma migrations only need the database URL, so that is fine here.
Step 4: Keep the webhook service awake
Railway has a Serverless setting (formerly App Sleeping). It stops a service after it has sent no outbound traffic for about 5 to 10 minutes. It saves money on side projects. On a SaaS that takes Stripe payments, leave it off for the service that handles /api/stripe/webhook. In the Designyff kits, that is the same Next.js service as the rest of the app.
Railway’s Serverless docs state the two caveats that matter:
- The first request to a sleeping service has cold-boot delay.
- The first request to a sleeping service may return a 502.
Stripe treats a non-2xx response as a failed delivery and retries. In live mode it keeps trying for up to three days with exponential backoff (Stripe webhooks). The event is not lost. The problem is timing. A customer finishes Checkout, lands on your success page, and the plan column still says free until a retry lands. That is a support ticket you created to save a few cents.
The webhook handler itself is covered in Stripe webhooks with Next.js. The state it writes is covered in synchronizing Stripe subscription state. On Railway, the only extra step is registering the production URL in Stripe and putting the dashboard signing secret, not the stripe listen secret, in STRIPE_WEBHOOK_SECRET.
Serverless is still fine for a staging environment or an internal admin service that nobody pays through.
Deploy checklist
output: "standalone"innext.config.ts, and a start script that runs.next/standalone/server.js, or Railway’s Dockerfile.prisma generateruns during the build.- A Postgres service in the same project and region, and
DATABASE_URLadded as a reference variable. prisma/migrationscommitted, and the pre-deploy command set tonpx prisma migrate deploy.AUTH_SECRET,STRIPE_SECRET_KEY, andSTRIPE_WEBHOOK_SECRETset on the app service. None of them areNEXT_PUBLIC_.- Serverless off on the service that receives Stripe webhooks.
- A custom domain on Hobby or Pro, and the Stripe webhook endpoint pointed at it.
- A usage alert and a hard limit set in workspace usage settings.
Create a Railway account and deploy the app plus Postgres
FAQ
Does Railway replace Prisma Postgres or Neon? No. Those are hosted Postgres products with their own pricing. Railway Postgres is the database service inside a Railway project. Prisma’s Railway guide runs the app on Railway and connects it to Prisma Postgres. This guide uses Railway’s own Postgres. Pick one database, not three connection strings.
Will the Designyff starter kits deploy unchanged?
That was not verified by running them on Railway for this article. The kits expect DATABASE_URL, a Prisma schema, and Stripe environment variables, which is the same contract Railway’s guide uses. You still set standalone output, the pre-deploy migration, and the production webhook secret yourself. The product pages today point at Vercel or a Node host, not at a finished Railway template.
Is the Free plan enough for a SaaS? No. Free is 1 vCPU and 0.5 GB of RAM per service, a 500 MB volume, $1 of monthly usage, and no custom domain. That is a demo, not a place to store customers.
Does the Hobby plan’s $5 credit roll over? No. Railway resets included usage at the end of each billing cycle, and unused usage does not accumulate.
Do I have to use the referral link? No. railway.com works without it. The link is how Designyff gets credited if you do use it.