RoyceTL;DR Vercel for Next.js apps with zero-config deploys and the best DX. Railway for teams...
Vercel for Next.js apps with zero-config deploys and the best DX. Railway for teams that need persistent servers, background workers, cron jobs, or want to co-locate their database. Render for simple Docker-based deploys at predictable pricing. Most indie SaaS starts on Vercel; hits Railway or Render when background job complexity grows.
| Feature | Vercel | Railway | Render |
|---|---|---|---|
| Free tier | Hobby (limited) | $5/mo credit | Free (with limits) |
| Pro starts at | $20/mo | $20/mo | $19/mo |
| Next.js support | ⭐⭐⭐⭐⭐ (built by Vercel) | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| Background workers | ❌ | ✅ | ✅ |
| Cron jobs | ✅ (Vercel Cron) | ✅ (native) | ✅ |
| PostgreSQL | ❌ (via partner) | ✅ Built-in | ✅ Built-in |
| Redis | ❌ (via Upstash) | ✅ Built-in | ✅ Built-in |
| Docker | Limited | ✅ First-class | ✅ First-class |
| Custom domains | ✅ | ✅ | ✅ |
| Preview deploys | ✅ Per PR | ✅ | ✅ |
| Edge network | ✅ Global CDN | ❌ | ❌ |
| Cold starts | Yes (serverless) | No (persistent) | No (persistent) |
Vercel created Next.js and deploys it perfectly. Push to git, Vercel handles the rest.
# Deployment in 3 commands
npm install -g vercel
vercel login
vercel --prod
Zero configuration. Automatic SSL. Preview URLs for every PR. Global CDN.
Preview deployments — Every pull request gets a unique URL. Frontend + API changes are testable before merge:
main branch → https://yourapp.vercel.app
PR #42 → https://yourapp-git-fix-auth-yourteam.vercel.app
feature/new-ui → https://yourapp-git-feature-new-ui-yourteam.vercel.app
Edge Middleware — Auth checks at the edge, before your app server:
// middleware.ts — runs globally at edge (no cold start for auth)
const isPublicRoute = createRouteMatcher(['/', '/sign-in(.*)', '/sign-up(.*)']);
if (!isPublicRoute(request)) auth().protect();
});
matcher: ['/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', '/(api|trpc)(.*)'],
};
No persistent processes — Vercel runs serverless functions. No long-running processes, no persistent connections, no background workers.
What you CAN'T run natively on Vercel:
- Bull/BullMQ workers
- WebSocket servers
- Cron jobs > once per minute (Vercel Cron is limited)
- Long-running processes (video encoding, PDF generation)
Pricing at scale — Vercel's Pro plan is $20/month per team member. Bandwidth charges add up. At meaningful scale (100k+ users), Vercel can be expensive vs self-hosted.
Vendor lock-in — Server Components, Edge Middleware, and Image Optimization are deeply integrated with Vercel's infrastructure. Migrating away is non-trivial.
Railway deploys Docker containers as persistent servers. Your app runs continuously — no cold starts, no serverless limitations.
# railway.toml — deploy any stack
[build]
builder = "nixpacks"
[deploy]
startCommand = "npm run start"
healthcheckPath = "/health"
healthcheckTimeout = 300
Everything in one project — Run your Next.js app, background workers, PostgreSQL, and Redis all in the same Railway project:
Railway Project: my-saas
├── web (Next.js app)
├── worker (BullMQ background jobs)
├── PostgreSQL (managed, backups)
└── Redis (BullMQ queue)
No external database services, no queue-as-a-service subscriptions. One bill, one dashboard.
Background workers with Railway:
// worker/index.ts — runs as a separate Railway service
const emailQueue = new Queue('email', process.env.REDIS_URL!);
const imageQueue = new Queue('images', process.env.REDIS_URL!);
emailQueue.process(5, processEmailQueue);
imageQueue.process(2, processImageQueue);
console.log('Worker started');
Transparent pricing — Railway charges by resource usage (CPU/RAM/network), not by seat or feature tier. $20/month goes much further than Vercel at moderate scale.
Render hits the middle ground: easier than AWS, more flexible than Vercel. Deploy any Dockerfile with minimal configuration.
# render.yaml — infrastructure as code
services:
- type: web
name: my-saas
runtime: node
buildCommand: npm install && npm run build
startCommand: npm start
envVars:
- key: DATABASE_URL
fromDatabase:
name: my-db
property: connectionString
- type: worker
name: my-worker
runtime: node
startCommand: node worker/index.js
databases:
- name: my-db
databaseName: mydb
plan: starter
Pattern 1: Start Vercel, migrate workers to Railway
Vercel: Next.js app (fast deploys, preview URLs)
Railway: BullMQ worker + Redis (add when jobs > 60s or need queuing)
Supabase/Neon: Database (external, not Railway)
Most common for solo founders who start on Vercel and add Railway when complexity requires it.
Pattern 2: Full Railway from day one
Railway: Next.js app + worker + PostgreSQL + Redis
Cloudflare: CDN layer (optional)
Best for teams that need background jobs early and don't want multiple platforms.
Pattern 3: Render for everything
Render: Web + Worker + PostgreSQL
Cloudflare R2: File storage
Resend: Email
Clean, Docker-based, Heroku-like simplicity.
Assuming a typical indie SaaS: 1k active users, 10 background jobs/minute, 50GB storage:
| Platform | Monthly Cost | Includes |
|---|---|---|
| Vercel Pro | $20 + overages | Web app only |
| Vercel + Railway | $20 + $15 | Web + workers |
| Railway only | $20-35 | Everything |
| Render | $25-40 | Everything |
Find boilerplates with deployment guides on StarterPick.