Railway’s documentation covers the deploy story (git push, Docker, one-click templates), the service graph (multi-service apps, shared networking), the variables (env vars, references, secrets), and the cost model (per-second metering, free tier, team plan). The right answer is to start with the railway init flow for a git-push deploy, the railway up flow for a Docker deploy, and the dashboard’s Variables tab for env vars. The wrong answer is to over-provision before the team knows the actual usage — Railway’s per-second metering means the team only pays for what they use, and over-provisioning is a wasted cost.
Table of contents
- The deploy story — git push, Docker, one-click templates
- The service graph — multi-service apps and shared networking
- The variables — env vars, references, secrets
- The cost model — per-second metering and the free tier
- The deploy previews — the branch-based deploy URL
- The CLI — railway login, init, up, link, run
- The databases — Postgres, Redis, and the managed services
- How this fits the rest of the stack
- FAQ
The deploy story — git push, Docker, one-click templates
The first deploy pattern is git-push. The team runs railway init, the CLI creates a Railway project, the team adds the project as a git remote, the team pushes. The build is detected automatically (Node, Python, Go, Ruby, etc.), the deploy runs, the URL is live. The right answer is git-push for a team that has a git repo and wants the simplest deploy.
The second deploy pattern is Docker. The team runs railway init, the CLI detects the Dockerfile, the deploy uses the Dockerfile’s build instructions. The right answer is Docker for a team that needs a custom runtime, a specific base image, or a multi-stage build. The wrong answer is Docker for a team that the default builder handles — the team is paying for the build time, not the simpler config.
The third deploy pattern is one-click templates. Railway has a template gallery (Postgres, Redis, Next.js, FastAPI, etc.) and the team can deploy a template with one click. The right answer is templates for a team that wants to spin up a stack quickly, the wrong answer is templates for a team that needs a custom stack — the team will replace the template’s services with their own anyway.
The service graph — multi-service apps and shared networking
A Railway project can have multiple services. The team’s web service, the team’s API service, the team’s worker, the team’s Postgres, the team’s Redis — each one is a service in the same project. The services share a private network (the team can reach postgres.railway.internal from the web service), they can share environment variables (a DATABASE_URL set on the Postgres service is referenceable from any other service), and they can communicate over TCP.
The right answer is a multi-service project for a team that has a web app, an API, a worker, and a database. The wrong answer is a multi-service project for a single-service app — the team is paying for the project overhead, not getting the multi-service benefit.
The variables — env vars, references, secrets
Variables are the env vars for a Railway service. The team sets a variable in the dashboard (Variables tab), the variable is injected into the service’s environment at runtime. The right answer for a service-specific var is to set it on the service. The right answer for a shared var (the database URL) is to set it on the source service and reference it from other services (${{Postgres.DATABASE_URL}}).
The gotcha: the variable’s value is a string, not a structured object. The team that needs a JSON object as a variable must serialize it (JSON.stringify({...})) in the app or use a different approach. The right answer for production secrets is a real secret manager (AWS Secrets Manager, GCP Secret Manager), with the Railway variable pointing to the secret manager.
The cost model — per-second metering and the free tier
Railway’s pricing is per-second metering: the team pays for the actual CPU and memory the service uses, not the provisioned size. The free tier is $5/month of usage (the ‘Hobby’ plan). The Pro plan is $20/month + usage. The Team plan is custom pricing.
The right answer is the free tier for a team’s first project or a low-traffic app. The right answer is the Pro plan for a production app. The wrong answer is to over-provision — the team’s 8GB memory service that uses 256MB is paying for 32x what it needs. The right answer is to start small and scale up as the usage grows.
The deploy previews — the branch-based deploy URL
Every git push to a branch gets a preview deploy URL. The URL is unique to the branch, the URL is public (or private, depending on the team plan), the URL is removed when the branch is deleted. The right answer is preview deploys for a team that wants to test PRs before merging. The wrong answer is to skip previews and deploy every branch to production — the team is one bad push away from a 4am page.
The CLI — railway login, init, up, link, run
The Railway CLI is the team’s command-line interface. railway login authenticates, railway init creates a new project, railway up deploys the current directory, railway link connects the local code to an existing project, railway run <command> runs a command in the service’s environment. The right answer is the CLI for a team that deploys frequently, the dashboard for a team that deploys occasionally.
The gotcha: railway run runs a command in the service’s environment, with the service’s env vars and the service’s network access. The right answer is railway run npm run migrate to run a database migration with the production env vars. The wrong answer is to set the env vars locally and run npm run migrate — the team is running the migration with the wrong database.
The databases — Postgres, Redis, and the managed services
Railway has first-class Postgres and Redis services. The team adds a Postgres service, the team gets a DATABASE_URL variable on the service, the team’s app connects to the Postgres. The right answer is the managed Postgres for a team that does not want to operate a database. The wrong answer is the managed Postgres for a team that needs a specific Postgres version or extension that Railway does not support — the team should use the external Postgres provider.
How this fits the rest of the stack
The infrastructure question is a small piece of a larger pattern: the team’s runtime, storage, database, secret store, logs, and deployment platform are all parts of the same platform. The right answer is to model the full stack before the project ships, not after. The RunxBuild hosting calculator is the right place to do that exercise — pick the runtime, the memory tier, the storage, the secret store, and the egress, and the calculator shows what the deploy actually costs at the team’s actual usage.
Useful related references:
FAQ
What is Railway?
A platform-as-a-service that supports git-push deploys, Docker deploys, and one-click templates, with per-second metering and managed Postgres/Redis.
How much does Railway cost?
Free tier is $5/month of usage (Hobby). Pro is $20/month + usage. Team is custom. The right answer is to start on the free tier and scale up.
How do I deploy to Railway?
railway init to create a project, railway up to deploy the current directory, or push to a connected git remote. The build is detected automatically.
Does Railway support Docker?
Yes. The CLI detects the Dockerfile and uses it for the build. The right answer is Docker for a team that needs a custom runtime or multi-stage build.
What is the difference between Railway and Render?
Railway has per-second metering, a service graph, and a first-class CLI. Render has flat-rate pricing, native Docker support, and a more traditional PaaS feel. The right answer is the one that matches the team’s pricing preference.
Does Railway have a free tier?
Yes — the Hobby plan gives $5/month of usage. The right answer is the free tier for a team’s first project or a low-traffic app.
How do I add a database to Railway?
Add a Postgres service to the project, the team gets a DATABASE_URL variable on the service. The right answer is the managed Postgres for a team that does not want to operate a database.
How do I run a one-off command in Railway?
railway run <command> runs the command in the service’s environment, with the service’s env vars and network access. The right answer is railway run npm run migrate to run a database migration.