← Our stack

Railway deployment for persistent backends.

When a workload needs a long-running process, persistent connections, or a container that stays alive, we deploy and run it on Railway.

railway.com ↗
How we use Railway

Railway handles the backend workloads that don't fit the serverless model. WebSocket servers, background job processors, real-time communication services, and AI agent runtimes all need processes that stay alive between requests. Railway gives us container-based hosting with automatic deploys from git, built-in databases, and straightforward scaling. We use it alongside Vercel: the frontend and API routes deploy on Vercel, and long-running backend services deploy on Railway. Each platform handles what it does best.

Not everything is serverless. Railway runs the things that need to stay on.

Why Railway

Railway is the simplest path from a Dockerfile to a running service. No Kubernetes configuration, no infrastructure-as-code boilerplate, no multi-step CI pipeline. Push to git, it deploys. Need a Postgres database? Click a button. Need Redis? Same. For the backend services that don't fit into serverless functions (WebSocket servers, background workers, AI agent processes), Railway provides the persistent compute without the operational overhead of managing EC2 instances or container orchestration.

Railway in the Philter commerce build

The published Philter case study lists Railway among the tools used in its open-source commerce rebuild. Read the case study for the implementation, migration, and ownership details across the full stack.

Railway hosting for production backends

Railway hosting is where we put the parts of an application that need to stay running. Serverless functions handle request-response work well, and Vercel's Fluid compute can reuse an instance for multiple requests. A continuously running WebSocket server, background worker, or AI agent process still needs a runtime designed to stay alive between requests. Railway gives those workloads a real container that stays alive, deployed straight from a Dockerfile or Railpack with no Kubernetes to babysit. For production we lean on what makes it boring in the best way: Postgres and Redis templates a click away, private networking between services, environment-based config, and logs and metrics in the same dashboard. We run it next to Vercel rather than instead of it (the front end and stateless API routes stay on Vercel, and the long-lived processes live on Railway) so each side of the app runs where it actually belongs.

Railway vs serverless: when a process needs to stay on

The honest version of the serverless-versus-Railway question is that it is rarely either/or. Serverless is our default for bursty request-response traffic with automatic scaling. We reach for a persistent container when a process needs to stay on: a WebSocket server holding connections, a job queue draining continuously in the background, an AI agent process that must keep running, or work that exceeds a function execution-time limit. Those workloads want a persistent container, and forcing them into serverless means fighting cold starts, timeouts, and connection churn. Our rule is simple: if the work is a short reply to a request, it stays serverless on Vercel; if it needs to live between requests, hold a connection, or run continuously, it moves to a Railway container. Most production apps we ship end up with some of each, and Railway hosts the half that has to stay alive.

How we do it

How we deploy on Railway

  1. Containerize

    We define the service in a Dockerfile or let Railway's Railpack detect and build it. Pinning the runtime and dependencies at the container level means the service runs identically in development, in a preview environment, and in production.

  2. Connect

    We link the git repository so every push triggers a build and deploy automatically. Pull requests get their own environments, so a backend change can be reviewed running live before it reaches production, the same workflow we use on the front end.

  3. Provision

    We add the pieces the service needs (Postgres, Redis, environment variables, and private networking between services) from Railway's dashboard. The database templates are unmanaged: we configure backups and recovery, security and access, monitoring, and maintenance. Secrets stay in environment config, never in the repository.

  4. Scale and observe

    We tune replicas and resource limits to real traffic, then watch logs and metrics in the same place to catch memory leaks, slow queries, or restart loops. Scaling is adjusting numbers, not re-architecting the deployment.

Where we use it

Real-Time Services

WebSocket servers and Socket.io backends for live chat, notifications, and collaborative features.

AI Agent Runtimes

Long-running AI agent processes that maintain state across conversations and need persistent connections.

Background Workers

Job queues, scheduled tasks, and data processing pipelines that run continuously outside the request-response cycle.

Questions

Railway FAQs

Get started

Let's talk about
your next build.