Deploy Astro + Convex to Vercel: 2026 Production Setup
Step-by-step 2026 guide: deploy your Astro + Convex app to Vercel with production deploy keys, preview deployments, custom domains, monitoring, and costs.

Astro and Convex
Part 2 of 2
Now that you’ve built a real-time Astro and Convex chat app (Part 1), it’s time to deploy it. In this guide I’ll show you how to deploy your Astro + Convex app to Vercel with proper production deploy keys, isolated preview deployments, and correct monitoring — all updated for Astro 7.2, Convex 1.4x, and Node 22.
This is Part 2 of the series. If you haven’t built the app yet, start with the Part 1 guide.
Why deploy an Astro + Convex app to Vercel?
The short version: Vercel serves the static shell, Convex Cloud handles everything real-time. They complement each other without overlap.
What Vercel provides
- Git-based automatic deployments on every push
- Free Hobby tier for personal projects
- Global CDN (Vercel Delivery Network) for fast static asset delivery
- Preview deployments for every pull request
- Astro auto-detection — zero framework config needed
- Built-in analytics and performance monitoring
What Convex Cloud handles
- Real-time database with live sync across clients
- Automatic scaling — no capacity planning
- Serverless functions with typed schemas
- Environment-based deployments (dev, preview, production)
- Function logs, error tracking, and usage analytics
The key insight: the browser connects to Convex directly over WebSocket for real-time data. Vercel just serves the HTML/CSS/JS bundle. That’s why this pairing works — each platform does what it’s good at.
What’s changed in this 2026 edition
If you’re returning from the 2025 version, here’s what’s different:
- Astro 7.2 — Vite 8 + Rolldown, Rust-based
.astrocompiler, 15–61% faster builds. Requires Node.js >= 22.12.0. See Astro 7’s faster builds benchmarks. - Convex 1.4x — CLI deployment management (
npx convex deployment create/select), typed deploy keys (prod:,preview:,dev:), EU hosting (Ireland), and Convex is now open-source with a self-hosting option. @astrojs/vercelv11 — requires Astro 7+. The old/serverlessand/staticsubpath exports were removed in v10 — use the default import only.- Vercel Marketplace — you can now create and pay for Convex through Vercel directly.
- Preview deployments — the original article’s setup silently pointed preview builds at production data. This edition fixes that with separate deploy keys.
Upgrading from the 2025 edition?
Run npx @astrojs/upgrade in your project to upgrade to Astro 7. You’ll also need Node.js >= 22.12.0. See the updated Part 1 guide for the full migration path.
Prerequisites
Before starting, make sure you have:
- Node.js >= 22.12.0 and npm >= 9.6.5 (
node -vto check) - An existing Astro + Convex project — follow our Part 1 guide to build one, or fast-start with
npx create-convex@latest -t astro - A Vercel account (free Hobby tier works)
- A GitHub repository with your code pushed
- A Convex account (free tier includes 1M function calls/month)
If you’re starting fresh, the fastest path:
npx create-convex@latest -t astro
cd my-app
npm run dev
This scaffolds the Astro + React + Tailwind v4 + Convex pattern with the withConvexProvider setup from Part 1.
Step 1 — Prepare your Convex production deployment
Create a production deployment
The quickest way — run npx convex deploy from your project directory:
cd your-project-directory
npx convex deploy
This creates a production deployment if one doesn’t exist, pushes your functions and schema, and generates a production URL.
For more control, use the newer deployment management commands (Convex CLI v1.34.0+):
npx convex deployment create # interactive: pick type, region, reference
npx convex deployment select # switch which deployment the CLI targets
npx convex deployment usage # see usage vs limits (v1.43.0+)
Generate a Convex deploy key
Deploy key dashboard path has changed
The old “Settings → Deploy Keys” path is outdated. Deploy keys are now created per-deployment on the Deployment Settings page.
- Go to the Convex Dashboard
- Select your project and navigate to your production deployment
- Go to Deployment Settings → Deploy keys
- Click Generate a deploy key (or “Generate Production Deploy Key”)
- Select the
deployment:deploypermission - Copy the key — you’ll need it for Vercel
The key will look like prod:your-deployment|abc123.... Convex uses typed deploy keys:
| Key type | Format | Use case |
|---|---|---|
| Production | prod:deployment-name|... |
Vercel Production environment |
| Preview | preview:team:project|... |
Vercel Preview environment |
| Development | dev:deployment|... |
Local/CI dev builds |
You can also generate keys via the CLI:
npx convex deployment token create my-ci-key --save-env
EU region note
Convex now offers EU West (Ireland, aws-eu-west-1) on all plans including free. If you’re in Europe, this means lower latency for your users.
EU hosting available
EU West is available on all plans. Paid resource pricing is 1.3x US pricing. Included free-tier usage does not apply to EU deployments — those are billed on demand. Regions can’t be migrated after creation (export/import only). Select the region when creating your deployment.
Step 2 — Push to GitHub
Standard git flow, with one addition — commit the convex/_generated/ directory:
git remote add origin [email protected]:youruser/your-repo.git
git branch -M main
git add -A
git commit -m "initial commit with convex generated code"
git push -u origin main
Commit convex/_generated/
Since Convex CLI v1.28.0, committing convex/_generated/ is recommended. The codegen step often requires a deployment for environment variables, so keeping the generated code in version control avoids issues during CI builds.
Step 3 — Deploy to Vercel
This is where we deploy your Astro + Convex app to Vercel. The build command override is the key — it tells Convex to inject the deployment URL and push functions before Astro builds.
Add the Astro Vercel adapter
npx astro add vercel
This installs @astrojs/vercel v11 and adds it to your astro.config.mjs.
Adapter optional for static sites
If your site is fully static (like the Part 1 chat app — client-side island hydration only), the adapter is technically optional. You only need it for SSR/on-demand routes, Vercel Web Analytics, or Vercel Image Optimization. For most apps, install it anyway — it’s one command and opens up those features later.
Important: @astrojs/vercel v10+ removed the /serverless and /static subpath exports. Use the default import:
// astro.config.mjs
import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel';
export default defineConfig({
adapter: vercel(),
});
If you later need SSR or advanced options:
export default defineConfig({
output: 'server',
adapter: vercel({
maxDuration: 30,
// isr: true,
// middlewareMode: 'edge', // replaces old edgeMiddleware: true
// skewProtection: true,
}),
});
Configure build settings
- Go to vercel.com/new and sign in with GitHub
- Click Import next to your repository — Vercel auto-detects Astro
- Configure the build settings:
| Setting | Value |
|---|---|
| Framework Preset | Astro |
| Build Command | npx convex deploy --cmd 'npm run build' |
| Output Directory | dist |
| Install Command | npm install |
What the build command does: npx convex deploy reads CONVEX_DEPLOY_KEY, injects CONVEX_URL into the build environment, pushes your functions and schema to the production deployment, then runs npm run build. Astro picks up CONVEX_URL at build time (via astro:env from Part 1) and bakes it into the client bundle.
Set the CONVEX_DEPLOY_KEY environment variable
Click Environment Variables in the Vercel project settings and add:
| Variable | Value | Environment |
|---|---|---|
CONVEX_DEPLOY_KEY |
prod:your-deployment|abc123... |
Production |
Scope to Production only
Set CONVEX_DEPLOY_KEY for the Production environment only. If you also want preview deployments with their own Convex backend, see Step 4 — don’t just copy the production key to Preview.
Deploy
- Review your build command and environment variable
- Click Deploy
- Vercel builds the project — this takes a couple of minutes
- Your site is live at
https://your-project.vercel.app
Verify it works: open the URL, then open the same URL in a second browser tab. Send a message in one tab — it should appear instantly in the other. That confirms the Convex real-time connection is working against your production deployment.
Vercel Marketplace alternative (optional)
Using the Vercel Marketplace instead?
Instead of creating Convex separately, you can create and manage Convex through Vercel:
npx convex login --vercel
npm create convex@latest -- --with-vercel-jsonRequirements:
- Production + Preview environments must be enabled
- Custom Prefix must be empty
This path bills Convex through Vercel and auto-configures environment variables. The build command override is the same: npx convex deploy --cmd 'npm run build'. Pick one path or the other — don’t mix them.
Step 4 — Set up Vercel preview deployments
This is the biggest correctness upgrade from the 2025 article. The original setup used a single production deploy key — which meant every Vercel Preview Deployment’s frontend pointed at the production Convex backend. Preview apps would read and write production data.
Production-only key = previews hit production data
If you only set CONVEX_DEPLOY_KEY for the Production environment, every Vercel preview build gets the production Convex URL. Your preview app will read and write real production data. Fix this with a separate Preview deploy key.
Generate a separate Preview deploy key
- In the Convex Dashboard, go to your project’s Settings page
- Click Generate Preview Deploy Key
- Copy the key — it will have a
preview:prefix
In your Vercel project settings, add a second environment variable:
| Variable | Value | Environment |
|---|---|---|
CONVEX_DEPLOY_KEY |
prod:your-deployment|abc123... |
Production |
CONVEX_DEPLOY_KEY |
preview:team:project|xyz789... |
Preview |
Yes, the same variable name with different values scoped to different environments. Vercel handles this — Production builds get the production key, Preview builds get the preview key.
Seed fresh preview backends
Optionally, seed data into fresh preview backends with the --preview-run flag:
npx convex deploy --cmd 'npm run build' --preview-run 'seedMessages'
This runs the seedMessages function after deploying to a new preview backend. Useful for demo data or smoke tests.
You can also control preview backend reuse with --preview-create and --preview-name.
Preview deployment lifetimes
Preview deployments are auto-deleted after a set period:
| Plan | Lifetime |
|---|---|
| Free / Starter | 5 days |
| Professional+ | 14 days |
Preview deployments are still in beta as of September 2026. They work, but expect the occasional rough edge.
Step 5 — Add a custom domain
Configure in Vercel
- Go to your project dashboard → Settings → Domains
- Click Add Domain
- Enter your domain (e.g.,
myapp.example.com) - Vercel provides DNS instructions — add the CNAME record to your DNS provider
- SSL certificates are provisioned automatically with HTTP → HTTPS redirects
DNS propagation usually takes 5–10 minutes. Once the status shows “Valid” in Vercel, you’re done.
Clerk requires a custom domain
If you plan to add authentication (Part 1 teases this), note that Clerk does not support *.vercel.app domains. Set up a custom domain before integrating Clerk or similar auth providers.
Step 6 — Monitor and analyze your production app
Vercel Web Analytics
The old “$20/month” pricing is gone. Vercel Web Analytics is now available on all plans with 50,000 events/month included, then $3 per 100,000 events. An optional Plus add-on is $10/month.
To set it up in Astro:
npm i @vercel/analytics
Add the component to your layout:
---
// src/layouts/Base.astro
import Analytics from '@vercel/analytics/astro';
---
<html lang="en">
<head>
<meta charset="utf-8" />
<Analytics />
</head>
<body><slot /></body>
</html>
Then enable it in the Vercel dashboard: Analytics → Enable.
Speed Insights and runtime logs
- Speed Insights basic is free on all plans. Plus is $10/project/month for advanced metrics.
- Runtime Logs are available on Pro+ plans for debugging serverless function execution.
Convex monitoring
In the Convex Dashboard:
- Logs tab — monitor function execution in real time
- Health & Insights — performance metrics and error tracking
- Usage Analytics — database operations and function call counts
From the CLI:
npx convex insights # quick health check (v1.32.0+)
npx convex deployment usage # usage vs limits
Convex env vars are not Vercel env vars
Convex function secrets (API keys for auth, rate limiting, etc.) live on the Convex deployment, not in Vercel. Set them per-deployment:
npx convex env set SENDGRID_API_KEY 'your-key'
npx convex env list
npx convex env default set MY_KEY 'value' # project defaults for new deploymentsUp to 512 variables, values up to 8 KiB each. If you add auth or rate-limiting components from Part 1, their env vars must be set on each deployment (dev + prod + previews).
Verify the deployment and troubleshooting
Verify your deployment
- Visit your Vercel production URL — the app loads without errors
- Open the app in two browser tabs and confirm real-time sync works (send a message in one, see it in the other)
- Check Convex Dashboard → Logs — you should see function calls from the production URL
- Run
npx convex deployment usageto confirm activity on the production deployment - Check the browser devtools Network tab for WebSocket connections to your Convex URL
Common errors and fixes
Build fails with missing CONVEX_URL
Part 1’s astro:env config makes astro build hard-fail if CONVEX_URL isn’t set at build time. npx convex deploy --cmd injects it automatically.
If the build still fails:
- Confirm
CONVEX_DEPLOY_KEYis set in Vercel’s build environment variables (not just runtime) - Verify the deploy key scopes to the correct deployment
- As a fallback, specify the env var name explicitly:
npx convex deploy --cmd-url-env-var-name CUSTOM_CONVEX_URL --cmd 'npm run build'Preview deployments write to production data
This happens when you only have a Production CONVEX_DEPLOY_KEY. Every preview build gets the production Convex URL.
Fix: generate a separate Preview deploy key and add CONVEX_DEPLOY_KEY scoped to the Preview environment in Vercel. See Step 4.
Realtime works locally but not in production
- Open browser devtools on the production URL and check the Network tab for WebSocket connections
- Verify the
CONVEX_URLin the deployed bundle matches your production deployment - Check the Convex Dashboard → Logs tab for incoming requests
- Confirm the production deployment exists and is active in the dashboard
Mixed deploy keys error
Since Convex CLI v1.30.0, using --preview-create with a non-preview key throws an error. Don’t mix preview flags with production keys. Keep production and preview builds separate.
Stale convex/_generated/ after upgrades
After upgrading Convex or changing your schema, regenerate the types:
npx convex dev # regenerates and watches for changes
npx convex codegen # one-shot regenerationThen commit the updated convex/_generated/ directory.
Auth providers and *.vercel.app domains
Clerk and Auth0 must allow your production Convex URL. Clerk does not support *.vercel.app domains — you need a custom domain before adding auth. Plan this early if you intend to follow Part 1’s auth next steps.
Costs and limits
Both platforms have genuine free tiers, but with caveats worth knowing upfront.
Convex pricing
| Plan | Price | Included | Key limits |
|---|---|---|---|
| Free & Starter | $0/month | 1M function calls, 0.5 GB DB storage | S16 concurrency (16 concurrent queries), 40 deployments |
| Professional | $25/developer/month | 25M function calls | Daily backups, custom domains, log streaming, 300 deployments |
| Business & Enterprise | $2,500/month minimum | Custom | BAA, SLA, dedicated support |
Overage on Free/Starter: $2.20 per additional 1M function calls, $0.22/GB storage.
EU hosting adds a 1.3x multiplier on paid resource pricing, and included free-tier usage does not apply to EU deployments. If you’re cost-sensitive and in Europe, start with US East and migrate later if latency matters.
Re-verify pricing at publish time
Convex pricing has been evolving. Check convex.dev/pricing for the latest numbers before deploying.
Vercel pricing
| Plan | Price | Key details |
|---|---|---|
| Hobby | $0/month | Personal, non-commercial use. 1M edge requests, 100 GB Fast Data Transfer |
| Pro | $20/month | Includes $20 usage credit. Extra seats $20/month each |
Vercel Hobby is non-commercial
The Hobby tier is for personal projects that don’t make money. If your side project generates revenue (even ad-supported), you technically need Pro at $20/month. Check vercel.com/pricing for current terms.
Self-hosting escape hatch
Convex is now open-source (get-convex/convex-backend, ~12.5k stars). You can self-host with Docker or a prebuilt binary, using SQLite or Postgres as the backend. This is the escape hatch if you outgrow the free tier or need full control.
For detailed setup, see self-hosting Convex with Docker Compose and Convex self-hosted vs. cloud free tier benchmarks.
If you want to self-host the frontend too, providers like Hetzner offer affordable European VPS. Check out hosting Astro on your own VPS and self-hosted alternatives to Vercel like Coolify for that path.
Conclusion
You’ve deployed your Astro + Convex app to Vercel with a production-ready setup. Here’s what you have:
- Production deployment with proper typed deploy keys scoped to the right environment
- Preview deployments isolated from production data — each PR gets its own Convex backend
- Custom domain with automatic SSL
- Monitoring via Vercel Web Analytics (free, 50K events/month) and Convex Dashboard logs
- Clear cost picture — both free tiers are real, with known upgrade paths
The development workflow stays simple: develop locally with npm run dev and npx convex dev, push to GitHub, and Vercel handles the rest. Preview deployments give you a staging environment per pull request without extra infrastructure.
If Vercel isn’t the right fit, you can also deploy your Astro site to Cloudflare or try deploying static Astro to Bunny.net. The Convex setup stays the same — only the frontend hosting changes.
Start with Part 1: Build the App

