Deployment and hosting platform specialist covering Vercel, Railway, and Convex. Use when deploying applications, configuring edge functions, setting up continuous deployment, or managing serverless infrastructure.
Comprehensive deployment platform guide covering Vercel (edge-first), Railway (container-first), and Convex (real-time backend).
Vercel - Edge-First Deployment:
Railway - Container-First Deployment:
Convex - Real-Time Backend:
Web Applications (Frontend + API):
Mobile Backends:
Full-Stack Monoliths:
Compute Requirements:
Storage Requirements:
Networking Requirements:
Stack: Vercel + Vercel Postgres/KV
Setup:
Best For: Web apps with standard database needs, e-commerce, content sites
Stack: Railway + Docker
Setup:
Best For: Microservices, complex backends, custom tech stacks
Stack: Convex + Vercel/Railway (frontend)
Setup:
Best For: Collaborative tools, live dashboards, chat applications
Stack: Vercel (frontend/edge) + Railway (backend services)
Setup:
Best For: High-performance apps, global distribution with complex backends
Stack: Vercel (frontend + API routes) + Convex (backend)
Setup:
Best For: Rapid prototyping, startups, real-time web apps
vercel.json:
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"framework": "nextjs",
"regions": ["iad1", "sfo1", "fra1"],
"functions": {
"app/api/**/*.ts": {
"memory": 1024,
"maxDuration": 10
}
}
}
Edge Function:
export const runtime = "edge"
export const preferredRegion = ["iad1", "sfo1"]
export async function GET(request: Request) {
const country = request.geo?.country || "Unknown"
return Response.json({ country })
}
railway.toml:
[build]
builder = "DOCKERFILE"
dockerfilePath = "Dockerfile"
[deploy]
healthcheckPath = "/health"
healthcheckTimeout = 100
restartPolicyType = "ON_FAILURE"
numReplicas = 2
[deploy.resources]
memory = "2GB"
cpu = "2.0"
Multi-Stage Dockerfile:
# Builder stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Runner stage
FROM node:20-alpine
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -g 1001 -S nodejs && adduser -S appuser -u 1001
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
USER appuser
EXPOSE 3000
CMD ["node", "dist/main.js"]
convex/schema.ts:
import { defineSchema, defineTable } from "convex/server"
import { v } from "convex/values"
export default defineSchema({
messages: defineTable({
text: v.string(),
userId: v.id("users"),
timestamp: v.number(),
})
.index("by_timestamp", ["timestamp"])
.searchIndex("search_text", {
searchField: "text",
filterFields: ["userId"],
}),
})
React Integration:
import { useQuery, useMutation } from "convex/react"
import { api } from "../convex/_generated/api"
export function Messages() {
const messages = useQuery(api.messages.list)
const sendMessage = useMutation(api.messages.send)
if (!messages) return <div>Loading...</div>
return (
<div>
{messages.map((msg) => (
<div key={msg._id}>{msg.text}</div>
))}
</div>
)
}