Vercel
Deploy your app to Vercel as a serverless application with zero infrastructure management.
How it works
The generated project includes a packages/deploy/vercel directory with everything needed:
vercel.json— build commands, rewrites, serverless function config, and cron scheduleapi/index.js— a single serverless function entry point that re-exports the backend
Vercel builds the backend and frontend together, serves the frontend as static files, and routes /api/* requests to the serverless function.
Setup
Copy the deploy files to your project root:
cp -r packages/deploy/vercel/* .Important: In the Vercel dashboard, keep the Root Directory set to the repository root (leave it empty). Vercel may auto-detect
packages/backendor another subdirectory — this is wrong. Thevercel.jsonat the root already handles build commands for all packages. See Root Directory for more details.
Environment variables
Set these in the Vercel dashboard under Settings > Environment Variables.
Required
| Variable | Description |
|---|---|
DATABASE_RLS_URL | PostgreSQL connection string (RLS user) |
DATABASE_BYPASS_RLS_URL | PostgreSQL connection string (bypass user) |
AUTH_SECRET | Random string for session encryption |
FRONTEND_URL | Your Vercel app URL (e.g. https://your-app.vercel.app) |
BACKEND_URL | Same as FRONTEND_URL for Vercel deployments |
ORGANIZATION_MODE | single, multi (default), or multi-domain |
If ORGANIZATION_MODE is set to multi-domain:
| Variable | Description |
|---|---|
ORGANIZATION_MULTI_DOMAIN_MODE | subdomain (default) or domain |
Background jobs
| Variable | Description |
|---|---|
BACKGROUND_JOB_MODE | inline (recommended for Hobby), cron (recommended for Pro), or worker (not supported on Vercel) |
CRON_SECRET | Required when using cron mode |
Optional
| Variable | Description |
|---|---|
STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET | Payments |
ANTHROPIC_API_KEY | AI chatbot |
AUTH_GOOGLE_ID, AUTH_GOOGLE_SECRET | OAuth providers |
EMAIL_FROM, EMAIL_SMTP_* | Email sending |
S3_BUCKET, S3_ACCESS_KEY_ID, etc. | File storage |
Database
Vercel works best with serverless-compatible PostgreSQL providers:
These handle connection pooling automatically, which is important for serverless environments where each function invocation may open a new connection.
Important: Create your database in the same region as your Vercel deployment. Vercel defaults to Washington, D.C. (
iad1). Mismatched regions add significant latency to every database query.
Background jobs
Inline mode (recommended for Hobby plan)
Set BACKGROUND_JOB_MODE=inline. Jobs run immediately after being added, blocking the request until complete. No external scheduling needed — this is the simplest option and works well for most use cases.
Cron mode (recommended for Pro plan)
Set BACKGROUND_JOB_MODE=cron. The vercel.json includes a cron job that calls /api/background-jobs/process:
"crons": [
{
"path": "/api/background-jobs/process",
"schedule": "0 0 * * *"
}
]The default schedule runs once daily. On a Pro plan, change to every minute for near-real-time processing:
"schedule": "* * * * *"Set CRON_SECRET in your environment variables when using cron mode.
Deploy
Via CLI
# Install Vercel CLI
npm i -g vercel
# Preview deployment
vercel
# Production deployment
vercel --prodVia GitHub
Connect your repository in the Vercel dashboard for automatic deployments on every push.
After deployment
Once deployed, copy your app URL (e.g. https://your-app.vercel.app) and set both FRONTEND_URL and BACKEND_URL to that URL in the Vercel dashboard. Both must point to the same URL since the backend runs as a serverless function on the same domain. Redeploy after updating.
Multi-domain subdomains
If your project uses multi-domain organization mode, each organization gets its own subdomain (e.g., tenant.yourdomain.com). Vercel supports this with wildcard domains.
Add a wildcard domain
Wildcard domains require Vercel's nameservers to issue wildcard SSL certificates.
- Point your domain's nameservers to
ns1.vercel-dns.comandns2.vercel-dns.comat your domain registrar. - In the Vercel dashboard, go to Settings > Domains.
- Add your apex domain (e.g.,
yourdomain.com). - Add a wildcard domain:
*.yourdomain.com.
Any subdomain (e.g., tenant1.yourdomain.com, tenant2.yourdomain.com) will now automatically resolve to your Vercel deployment with SSL.
Note: DNS changes can take up to 48 hours to propagate. Use WhatsMyDNS to check status.
Environment variables
Update these variables in the Vercel dashboard for multi-domain:
| Variable | Value |
|---|---|
FRONTEND_URL | https://*.yourdomain.com |
BACKEND_URL | https://yourdomain.com |
ORGANIZATION_MODE | multi-domain |
ORGANIZATION_MULTI_DOMAIN_MODE | subdomain |
Both the apex domain and all subdomains point to the same Vercel deployment. The application reads the subdomain from the request to identify the tenant.
Limitations
| Constraint | Hobby | Pro |
|---|---|---|
| Max execution time | 10s | 60s |
| Cron jobs | 1/day | Every minute |
Other limitations:
- Cold starts — serverless functions have startup latency on first request
- No persistent connections — WebSockets require an external service
- No background workers — use cron or inline mode instead
For long-running jobs or WebSocket support, consider the VM deployment option.