Build a Voice Agent on Railway: One-Click FastAPI Deploy (2026)
Ship a production voice agent in 5 minutes on Railway: FastAPI bridge, OpenAI Realtime, Postgres for sessions, and a one-click template. No Docker knowledge required.
TL;DR — Railway gives you Postgres, a Python service, environment variables, and a public HTTPS URL with two clicks. Drop in a FastAPI WebSocket bridge between Twilio and OpenAI Realtime, push to GitHub, and Railway redeploys on every commit. Total time from
git initto live voice agent: under 5 minutes.
What you'll build
A FastAPI service hosted on Railway that:
- Returns TwiML at
/incoming - Bridges
/mediaWebSocket to OpenAI Realtime - Logs every call to Railway-managed Postgres
- Auto-deploys on
git push
Prerequisites
- Railway account (
railway login). - GitHub repo.
OPENAI_API_KEY, Twilio number.- Python 3.11.
Architecture
flowchart LR
C[Caller] --> T[Twilio]
T -->|HTTP TwiML| RW[Railway FastAPI]
T -->|wss media| RW
RW <-->|wss| OAI[OpenAI Realtime]
RW -->|asyncpg| PG[(Railway Postgres)]
GH[GitHub repo] -->|push| RW
Step 1 — FastAPI app
```python
app.py
import os, json, base64, asyncio, asyncpg, websockets from fastapi import FastAPI, WebSocket, Request from fastapi.responses import Response
app = FastAPI() pool: asyncpg.Pool
@app.on_event("startup") async def startup(): global pool pool = await asyncpg.create_pool(os.environ["DATABASE_URL"]) async with pool.acquire() as c: await c.execute("""create table if not exists turns ( id serial primary key, call_sid text, role text, text text, ts timestamptz default now())""")
Hear it before you finish reading
Talk to a live CallSphere AI voice agent in your browser — 60 seconds, no signup.
@app.post("/incoming")
async def incoming(req: Request):
host = req.headers["host"]
return Response(content=f"""
@app.websocket("/media") async def media(ws: WebSocket): await ws.accept() async with websockets.connect( "wss://api.openai.com/v1/realtime?model=gpt-realtime", additional_headers={"Authorization": f"Bearer {os.environ['OPENAI_API_KEY']}", "OpenAI-Beta": "realtime=v1"} ) as ai: await ai.send(json.dumps({ "type": "session.update", "session": { "instructions": "You are a concise voice agent.", "voice": "marin", "input_audio_format": "g711_ulaw", "output_audio_format": "g711_ulaw", "turn_detection": {"type": "server_vad"} } })) sid = "" async def to_ai(): async for raw in ws.iter_text(): ev = json.loads(raw) nonlocal_sid = ev.get("streamSid") if ev.get("event") == "media": await ai.send(json.dumps({"type": "input_audio_buffer.append", "audio": ev["media"]["payload"]})) async def to_caller(): async for raw in ai: ev = json.loads(raw) if ev["type"] == "response.audio.delta": await ws.send_text(json.dumps({"event": "media", "streamSid": sid, "media": {"payload": ev["delta"]}})) if ev["type"] == "response.done": text = ev["response"]["output"][0]["content"][0]["transcript"] async with pool.acquire() as c: await c.execute("insert into turns(call_sid, role, text) values($1, 'assistant', $2)", sid, text) await asyncio.gather(to_ai(), to_caller()) ```
Step 2 — requirements.txt and railway.toml
``` fastapi==0.115.0 uvicorn[standard]==0.32.0 websockets==13.1 asyncpg==0.30.0 ```
```toml
railway.toml
[build] builder = "NIXPACKS" [deploy] startCommand = "uvicorn app:app --host 0.0.0.0 --port $PORT" restartPolicyType = "ON_FAILURE" ```
Railway's Nixpacks builder detects Python automatically; no Dockerfile needed.
Step 3 — Provision Postgres + service
In Railway dashboard: New Project → Deploy from GitHub repo → pick the FastAPI repo. Add a Postgres plugin from the same project; Railway sets DATABASE_URL automatically.
Step 4 — Set env vars
In the service settings, add OPENAI_API_KEY. Railway redeploys on save.
Still reading? Stop comparing — try CallSphere live.
CallSphere ships complete AI voice agents per industry — 14 tools for healthcare, 10 agents for real estate, 4 specialists for salons. See how it actually handles a call before you book a demo.
Step 5 — Public URL + Twilio webhook
Railway generates https://your-app.up.railway.app. Plug into Twilio → number → Voice Webhook → POST https://your-app.up.railway.app/incoming.
Step 6 — Add observability
Pin the Railway "OpenTelemetry" template, set OTEL_EXPORTER_OTLP_ENDPOINT to a Honeycomb/Tempo URL. Latency per turn shows up in spans automatically with the standard FastAPI OTel instrumentation.
Step 7 — Scale
Bump replicas from 1 to N in the dashboard. Railway puts a load balancer in front; sticky sessions on x-twilio-signature keep call legs pinned.
Pitfalls
- Cold-start on free hobby plan is ~5s — voice agents will drop. Use
Pro($5/mo + usage) or pin always-on. - Twilio retries TwiML POSTs aggressively on slow boots; first request must respond <15s.
- Postgres pool sizing: Railway's Postgres has a connection cap; tune
asyncpg.create_pool(min_size=2, max_size=10). - Nixpacks Python version: pin via
runtime.txtorPYTHON_VERSION=3.11env var. - No persistent disk on basic plans; logs are ephemeral. Pipe to Logtail/Axiom.
How CallSphere does this in production
CallSphere doesn't run on Railway — we use bare k3s + Postgres on Hetzner for cost predictability at our scale (~$1k/mo infra for 6 verticals). For early-stage builders, Railway is the fastest way to ship a real voice agent with a real database. CallSphere's 37 agents, 90+ tools, 115+ DB tables, 6 verticals run on FastAPI :8084 with the same code patterns shown here. $149/$499/$1499, 14-day trial, 22% affiliate.
FAQ
Q: Railway vs Render vs Fly? Railway: easiest CLI + UI, Postgres bundled. Render: similar, slightly slower deploys. Fly: best for multi-region. Pick Railway for speed.
Q: Can I use a one-click template?
Yes — Railway's marketplace has Deploy OpenAI Voice Assistant and Deploy Faster Whisper templates that wire most of this for you.
Q: Latency?
Railway runs in us-west and us-east; voice-to-voice ~750ms vs Twilio + OpenAI on East Coast.
Q: Cost at 100k call-min/month? Compute ~$30, Postgres ~$10, OpenAI Realtime ~$30k. Infra is rounding error — pick what's productive.
Q: HIPAA? Railway doesn't sign BAAs as of May 2026. For HIPAA, run on AWS/GCP/Azure with their BAA.
Sources
Try CallSphere AI Voice Agents
See how AI voice agents work for your industry. Live demo available -- no signup required.