What is Railway's role in the Pantheon stack, what runs on it vs N5/VPS, and
which projects do we stand up? Railway facts deep-read from official docs; footprint from
fleet_services. Grounds the durable MCP/workflow deployment-layer decision.
Railway is the sanctioned home for stateless / agent app-layer services — Mastra agents & hosted MCP servers. N5 stays the self-hosted substrate (vault, fabric, obs, media). n8n stays on the Hostinger VPS — Railway's volume/replica limits make it a poor n8n host. The vault never moves to PaaS. Split by workload class — not "everything to Railway."
| Use case | Fit | Notes |
|---|---|---|
| Always-on Mastra agent | strong | mimir proven; metis next |
| Hosted MCP server (remote, OAuth) | w/ constraint | WebSocket / streamable-HTTP+heartbeat — not SSE |
| Client-facing API (SSE chat) | proven | mimir-chat-api; heartbeat ≤5min, reconnect <15min |
| Per-PR preview / staging | strong DX | preview env inherits shared vars |
| Scheduled jobs (cron) | yes | supported (light-coverage this pass) |
| n8n workflow runtime | weak | single-replica forced → keep on VPS (§5) |
| Stateful DB of record | avoid | DB "templates" self-run on volume, not managed/SLA'd |
| Area | What |
|---|---|
| Compute / plans | Per-service caps: Hobby 48GB/48vCPU·6 replicas; Pro 1TB/1000vCPU·42 replicas. No scale-to-zero — always-on bills continuously. |
| Deploy | GitHub repo / Dockerfile / Nixpacks. Config-as-code railway.toml (code overrides dashboard), per-env overrides. |
| Persistence | Ephemeral FS wiped on redeploy; persistence needs a Volume. Single-attach: one volume/service, not shareable, not with replicas. Redeploy of volume-backed svc = downtime. DBs are self-run templates, not managed. |
| Networking | Private SERVICE.railway.internal (WireGuard, IPv6, same project+env). Public .railway.app + auto-TLS, custom domains, TCP proxy. WebSocket = no timeout; SSE/HTTP = 15-min max, 5-min idle close. Static outbound IPv4 (Pro+); SMTP Pro+ only. |
| Envs / secrets | Preview env per PR. Shared vars (per-env), Sealed vars (write-only), Reference vars ${{ shared.X }} — point, don't copy. |
| Observability | Logs 7d/30d/90d by plan; metrics CPU/mem/disk/net 30d, no app-level metrics. Healthcheck = deploy-gate only, NOT liveness (default 300s). |
| Regions / HA | 4 Metal regions (US-W, US-E, EU-W, SEA). Multi-region replicas, nearest-route, no sticky sessions. No published uptime SLA on self-serve — real SLA = Enterprise-only, negotiated. |
| CLI / API | CLI up/run/logs/ssh/connect; CI via RAILWAY_TOKEN. GraphQL backboard.railway.com/graphql/v2 — token types Account/Workspace/Project/OAuth. |
15-min hard cap + 5-min idle close. MCP must heartbeat+reconnect, or use WebSocket (exempt). deep-read
SSE needs same instance; replicas break it (n8n #14761, closed "not planned"). Forces single-replica. deep-read
Volume single-attach + no-replicas-with-volumes + redeploy downtime = no zero-downtime HA for n8n / self-run DBs. deep-read
No volume → wiped on redeploy; build-phase writes don't persist. deep-read
DATABASE_URL shadowingRailway Postgres plugin injects it; name external-DB vars explicitly (mimir uses VISKA_DB_URL). in-fleet
None on self-serve; healthcheck is deploy-gate, not liveness. Keep external monitoring (Talos). deep-read
Per-second RAM+CPU; a steady 0.5vCPU/1GB ≈ a full Pro credit/mo. Not cheaper than a flat VPS for steady-state. deep-read
mimir's prod env is mimir-staging-production. Name service+env deliberately. in-fleet
pantheon-* vs client-viska-*. A client never rides fleet auth.fleet_services with real host/url (retire stdio rows).n8n is stateful (volume) and its MCP Server-Trigger needs single-replica (#14761). On Railway: single-replica only, redeploy downtime on the volume, per-second cost on a 24/7 app. The Hostinger VPS already runs it at flat cost with full control. n8n stays on the VPS. Railway is for Mastra agents + new hosted MCP servers — not the n8n runtime.
| Project / service | Tenant | What | Status |
|---|---|---|---|
viska-mimir-agent · svc mimir · prod | client (Viska) | Mastra agent (Slack) | LIVE |
mimir-chat-api (/api/chat SSE) | client (Viska) | chat API → portal | LIVE |
| Metis-as-Mastra | pantheon | fleet Mastra agent | SCOPED, NOT SHIPPED |
mastra-bridge MCP | atlas | MCP (deploy unconfirmed) | registry |
railway CLI returns Unauthorized this session. RAILWAY_TOKEN is
healthy+wired in vault but not injected into the session (registry↔session drift). This table =
fleet_services + operator statement, not a live account dump. Fix via
token-in-session (Hades) before treating as exhaustive.pantheon-metis-agent (Railway, pantheon) — ship the scoped Metis Mastra agent as the Pantheon pilot + first hosted MCP under the new standard (WebSocket/streamable-HTTP).pantheon-* vs client-viska-* projects + project-scoped tokens + per-tenant auth/secrets.MCPServer on Railway) vs stay stdio-local. Don't lift what doesn't need lifting.RAILWAY_TOKEN session-injection (Hades) to restore railway CLI + Talos railway probe + live enumeration.--extension / Chrome DevTools --autoConnect); keep DOMShell if it earns its place. Not a Railway concern.Railway turns a fixed VPS bill into a variable RAM-hours bill. 24/7 steady-state → usually
pricier & less predictable than the VPS; bursty/preview/agent workloads → per-second metering
can win. Rates deep-read: $20/vCPU·mo ·
$10/GB-RAM·mo · $0.15/GB-vol·mo · $0.05/GB egress ·
Pro $20/seat·mo.
deep-read plans/caps, cost rates, volumes, DB-templates, private networking, TCP proxy, WS-no-timeout/SSE-15min (2 pages), logs/metrics/healthcheck, regions, no-self-serve-SLA, CLI/GraphQL, n8n #14761, secrets/reference/sealed vars, config-as-code.
in-fleet DATABASE_URL shadowing, naming drift, footprint.
verify before quoting object-storage $/GB, build-minute pricing, volume region-binding, usage-cap/suspension, cron mechanics, deploy-method internals, metrics sampling, default restart-policy, multi-region plan floor. (none load-bearing for §0)
blocked live Railway-account enumeration (RAILWAY_TOKEN not in session).