# Shipping a full-stack app with Next.js, NestJS, and Postgres on Railway

*By Roberto Lazar, founder of Dock30 · Published 2026-06-21 · Updated 2026-07-25 · 7 min read*

A working monorepo setup for a Next.js frontend, NestJS API, and PostgreSQL on Railway, with deploy steps and what hosting really costs in 2026.

If you want one dependable way to ship a production full-stack TypeScript app in 2026, use a pnpm monorepo with a Next.js 16 frontend, a NestJS 11 API, and PostgreSQL, deployed as three services in one Railway project. You get a single language end to end, shared types so the client and API never drift, and a host that runs the web app, the API, and the database side by side. For a small always-on app, expect the hosting bill to land around **$10 to $35 a month**, not the $5 that older guides promise.

We have been shipping variations of this setup for client work since 2021, and it covers most of our current [tech stack](/tech-stack), with [on-chain and web3 work](/services/blockchain-web3) sitting on a separate track. What follows is the configuration we actually deploy, with numbers that are true in July 2026 rather than the ones that were true at Railway's launch.

## Why Next.js plus NestJS instead of just Next.js

You do not need NestJS for a marketing site with a contact form, or for an app whose backend is a handful of CRUD endpoints. Next.js route handlers cover that fine, and bolting on a second framework there is self-inflicted complexity. I tell people this on intro calls more often than you would guess.

The split earns its keep when the backend grows real domain logic: role-based auth, scheduled jobs, queues, third-party integrations, anything a webhook can wake up at 3 a.m. NestJS gives you modules, dependency injection, guards, and a proper testing story, so the API stays navigable at 50 endpoints instead of turning into a drawer of loose route files. It sits on the 11.x line as of mid-2026. Version 12 is expected around Q3 2026 and swaps the toolchain to ESM-only output with Vitest, oxlint, and Rspack, per [InfoQ](https://www.infoq.com/news/2026/04/nestjs-12-roadmap-esm/); nothing in this guide changes with v12, but if you start a project today, keep your imports ESM-friendly and the upgrade should be boring.

The frontend side is an easy sell right now. Next.js 16.2, released in March 2026, cut dev-server startup by roughly 400% and made server-side rendering about 50% faster, per the [release notes](https://releasebot.io/updates/vercel/next-js). If your app feels slow in the browser rather than on the server, that is usually an interaction problem, and we wrote a separate piece on [fixing INP in Next.js](/blog/fix-inp-nextjs-react) for exactly that.

Postgres needs no defense. On top of it we put Prisma or Drizzle for a type-safe data layer; on client projects we usually pick Prisma because its migrations and onboarding are easier to hand over when our 30 days of free post-launch support end.

## Monorepo setup

One repo, two apps, one shared package:

```text
my-app/
  apps/
    web/        # Next.js 16
    api/        # NestJS 11
  packages/
    shared/     # types, zod schemas, constants
  pnpm-workspace.yaml
  turbo.json
```

The workspace file is two lines:

```yaml
packages:
  - "apps/*"
  - "packages/*"
```

`packages/shared` is the quiet hero of the whole arrangement. Define an `Invoice` type and its zod schema once, import it from both apps, and the frontend can no longer drift from the API contract without the compiler complaining. For about a week on a two-person project this feels like ceremony. Then the first serious refactor lands and it pays for itself in an afternoon.

Turborepo handles task orchestration and caching. Nx does the same job if your team already knows it. This is not a decision worth a meeting.

## Deploying to Railway step by step

Railway models each app and the database as a service inside one project, and services in a project talk over a private network. The sequence we follow:

1. Create a Railway project and connect the Git repo. Every push to main deploys from then on.
2. Add PostgreSQL. One click, and Railway provisions it and exposes `DATABASE_URL`.
3. Add the API service. Keep the root directory at the repo root so pnpm can see the lockfile, and set watch paths to `apps/api/**` and `packages/shared/**` so a frontend-only commit does not rebuild the API.
4. Add the web service the same way, watching `apps/web/**` and `packages/shared/**`.
5. Wire variables by reference. The API's `DATABASE_URL` is just `${{Postgres.DATABASE_URL}}`, and the web app's API URL points at the API service. Secrets never enter the repo.
6. Run migrations as a pre-deploy step, then add a health check.

Config as code for the API service, in `railway.json`:

```json
{
  "$schema": "https://railway.com/railway.schema.json",
  "build": {
    "buildCommand": "pnpm install --frozen-lockfile && pnpm --filter api build"
  },
  "deploy": {
    "preDeployCommand": "pnpm --filter api exec prisma migrate deploy",
    "startCommand": "node apps/api/dist/main.js",
    "healthcheckPath": "/health"
  }
}
```

One Railway-specific detail worth knowing: traffic between your services can use the private network (hostnames like `api.railway.internal`), which is lower latency and does not count as egress. Point the web service's server-side fetches at the internal hostname and reserve the public domain for the browser.

For the database itself, Railway shipped one-click high-availability Postgres in March 2026, built on Patroni, with automatic failover in under 30 seconds, in-region replicas, point-in-time recovery, and pgvector support ([Railway](https://railway.com/deploy/postgres-ha-patroni)). Start on a single instance. When the app starts holding revenue, flip to HA without re-architecting anything, which is a sentence you could not write about most budget hosts two years ago.

## What Railway actually costs in 2026

The pricing model itself is simple, per the [Railway pricing docs](https://docs.railway.com/pricing/plans):

| Component | Price |
|---|---|
| Hobby plan base | $5/month, includes $5 usage credit |
| Pro plan base | $20 per seat/month, includes $20 usage credit |
| RAM | $10 per GB-month |
| CPU | $20 per vCPU-month |
| Egress | about $0.05 per GB |

Everything is billed per second, so a preview environment you delete after an hour costs cents.

Now the honest math, because this architecture is three always-on services. A Next.js server and a NestJS API each idle at a few hundred MB of RAM, and Postgres wants its own memory on top. Independent 2026 breakdowns put a small always-on full-stack app at roughly $20 to $40 a month once you sum real usage ([livemy.app](https://livemy.app/blog/railway-pricing)), with a small SaaS plus a background worker landing at $40 to $70. Our working rule for this three-service setup, after the plan credit is absorbed: $10 to $35 a month for a small app, and **budget $40 or more** once you add a worker or real traffic. The "$5 a month on Railway" figure you still see quoted is true for one hobby service that sleeps most of the day, not for a web app, an API, and a database that stay up.

That is still cheap for what you get. It is just not free, and pretending otherwise is how people end up surprised at the second invoice.

## Railway vs Vercel

Vercel is a frontend specialist and Railway is the all-in-one, and that framing settles most of the debate. Vercel's Hobby tier is free but bans commercial use and has hard caps, so a real product needs Pro at $20 per developer per month plus usage, and a typical Pro user ends up around **$67 a month all-in** per [makerkit's cost analysis](https://makerkit.dev/blog/saas/vercel-cost). Vercel also does not run your NestJS API or your database, so Railway (or something like it) stays on the bill anyway.

The two sane configurations:

| Setup | Good for | What you accept |
|---|---|---|
| Everything on Railway | Cohesive products, small teams, one bill | You give up Vercel's edge network and preview tooling |
| Vercel (web) + Railway (API and DB) | Teams that specifically want Vercel's frontend platform | Two bills, CORS and env coordination, no private path from web to API |

For most product teams we recommend keeping everything on Railway and revisiting only if a concrete Vercel feature, not a vibe, pulls you toward the split. In five years of client work, the projects where splitting was genuinely worth it were a handful.

## Production checklist

Before you call it shipped:

- Secrets live in Railway variables, referenced between services, never committed.
- `prisma migrate deploy` runs as a pre-deploy command, not from someone's laptop.
- The API exposes `/health` and Railway's health check points at it, so bad deploys never receive traffic.
- Postgres connection pooling is sized to the instance; Prisma's defaults are fine early, PgBouncer when connection counts climb.
- Watch paths are set per service, so frontend commits stop triggering pointless API builds.
- HA Postgres is enabled before the database becomes the thing your revenue depends on.
- CI runs the test suite before Railway ever sees the push.

None of this is exotic. It is maybe two hours of setup, and it is the difference between a stack you trust and one you check on nervously after every deploy.

This is our default backbone for [custom development](/services/custom-development) work, whether that is a [customer-facing site or store](/services/websites-ecommerce), an [internal dashboard or tool](/services/dashboards-tools), or the data-heavy builds we covered in our [realtime dashboard write-up](/blog/realtime-dashboard-data-aggregation). If you are weighing this stack for your own product and want a second opinion on the architecture or the likely bill, book a [free 15-minute call](https://calendly.com/dock30/15min) or reach us through [our contact page](/contact). Worst case you leave with a checklist. We have talked more than one founder out of hiring anyone at all.

## Frequently asked questions

**How much does it cost to host a full-stack app on Railway in 2026?**

Plan for $10 to $35 a month for a small app with a web frontend, an API, and Postgres, and budget $40 or more once you add a background worker or real traffic. Railway charges a plan base (Hobby $5, Pro $20 per seat, each including a matching usage credit) plus usage: $10 per GB-month of RAM, $20 per vCPU-month, and about $0.05 per GB of egress, billed per second.

**Should I use NestJS with Next.js or just Next.js API routes?**

Use plain Next.js route handlers while your backend is simple CRUD. Add NestJS once the backend has real domain logic such as role-based auth, scheduled jobs, queues, or third-party integrations. Its module system and dependency injection keep a large API testable in a way loose route files do not.

**Is Railway better than Vercel for a full-stack app?**

They solve different problems. Vercel is a frontend specialist: excellent for the Next.js app itself, but a typical Pro user lands around $67 a month all-in and the free tier bans commercial use. Railway runs your frontend, API, and database together in one project with private networking, which is simpler and usually cheaper for a cohesive product.

**What version of NestJS is current in 2026?**

NestJS is on the 11.x line as of mid-2026. Version 12 is expected around Q3 2026 and moves the toolchain to ESM-only output, Vitest for testing, oxlint for linting, and Rspack for builds. Code written for v11 with ESM-friendly imports should upgrade with little drama.

**Does Railway support high-availability Postgres?**

Yes. Since March 2026 Railway offers one-click HA Postgres built on Patroni, with automatic failover in under 30 seconds, in-region replicas, point-in-time recovery, and pgvector support. You can start on a single instance and move to HA later without changing application code.

---

Written by Roberto Lazar, founder of Dock30. Book a call: https://dock30.com/contact
