Last February a startup CTO messaged me at 11pm: "Production just blew up, our build pipeline is eating everything." The cause was not some elaborate architecture. A wrong rewrites rule in vercel.json, an environment variable missing from the Preview environment, and a DNS record pointing the apex domain to the wrong target. Three small things, three hours of crisis. Vercel is easy to learn. Using it well is a separate skill.
This piece is for developers about to do their first vercel deployment. I am writing what I wish someone had told me before I lost a few nights to the docs. Read it once, then go ship something.
What Vercel actually solves
Treating Vercel as just a Next.js host misses the point. The real job is this: it pulls your code from Git, runs the build, ships the static output to a global CDN, and runs the dynamic parts as edge or serverless functions. Every PR gets its own preview URL on top. So you write a frontend, and Vercel hands you a CI/CD pipeline, a CDN, a serverless runtime, and a staging environment in one package.
You used to need Nginx tuning, S3 plus CloudFront, and Lambda glue code to get the same result. Each of those is a specialty on its own. Vercel collapses all of it into a git push. Not for free, of course; we will get to that.
Beyond Next.js it works with React, Vue, Svelte, SvelteKit, Astro, Nuxt, Remix and plain static HTML. The platform auto detects the framework and chooses a build command. You can override that whenever you need to.
The first ten minutes
Before you click anything on the dashboard, clean your repo. Decide on the main branch. Make sure .gitignore excludes .env, node_modules, .next, and dist. If Vercel sees committed node_modules your build cache will misbehave in ways that are hard to debug.
On vercel.com hit New Project, connect your Git provider, pick the repo. Framework detection usually works. Do not skim the Build & Output Settings panel; check the build command and the output directory. If you are in a monorepo, you must set the Root Directory or you will be wondering why the wrong app is deploying.
The first connection makes main your production branch. Every other branch automatically gets a preview deployment. This matters because the moment you push a feature branch, Vercel gives you a URL like https://--.vercel.app. You can hand that to designers, QA, or stakeholders. I will come back to why this changes how teams work.
The vercel.json that matters
Most of Vercel runs zero config. You do not strictly need a vercel.json. But once you ship to real users you will want it for redirects, rewrites, security headers, and function configuration.
A realistic, minimal version:
{
"redirects": [
{ "source": "/old-blog/:slug", "destination": "/blog/:slug", "permanent": true }
],
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "X-Frame-Options", "value": "DENY" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" }
]
}
],
"functions": {
"app/api/*/.ts": { "maxDuration": 30, "memory": 1024 }
}
}One pitfall: confusing redirects with rewrites. A redirect changes the user's URL. A rewrite quietly serves a different resource under the original URL. Mixing them up will tank your SEO.
The functions block matters more on the Hobby plan, where function duration caps at 10 seconds. Pro lifts it to 60 seconds, Enterprise up to 900. If your API depends on a slow third party, set maxDuration intentionally instead of letting it crash.
Render strategy: ISR, SSG, SSR, Edge
This is where most people overthink. My rule: assume static, fall back to dynamic only when forced.
Is your blog post updated maybe once a day? SSG, with ISR set to revalidate: 3600 if you want freshness. A dashboard tied to a user's session? SSR is mandatory. A small piece of geo personalization? Edge runtime is a fit. But fair warning: Edge does not support every Node API. Older Prisma versions, bcrypt, anything touching fs will explode. I keep Edge for tiny, latency critical functions like auth checks, geo redirects, A/B routing.
One honest take: ISR is more powerful than people give it credit for. Used well, it is almost as fresh as SSR and almost as fast as SSG. With revalidatePath you can also invalidate on demand when an editor publishes new content. For most marketing sites, that is the right default.
Before reaching for SSR, ask yourself if every request really needs a fresh render. The answer is no more often than you think.
Environment variables and secret discipline
Vercel splits environment variables into Production, Preview, and Development. Skipping that distinction is a real mistake. Add a DATABASE_URL only to Production and your previews crash. Add it only to Preview and prod runs without a database. Document which keys belong where.
What I do in practice: production database only in Production, staging database in Preview and Development, third party keys (Stripe, OpenAI) as sandbox keys in Preview and live keys only in Production.
A subtler trap: any variable starting with NEXT_PUBLIC_ is shipped to the client and baked into the bundle at build time. If you change it later, the build still serves the old value to anyone with a cached copy. Think twice before putting an API key behind that prefix.
Once you cross 30 or 40 secrets, the Vercel UI starts to feel cramped. Tools like Doppler and Infisical sync nicely with Vercel and centralize the mess. For a small project, the built in panel is more than enough.
Domain and DNS pitfalls
Pointing a domain looks like a two minute job. Often it is not. Vercel hands you a target like cname.vercel-dns.com. For an apex (say poitim.com) you set an A record to 76.76.21.21; for www you set a CNAME. If your DNS provider supports ALIAS or ANAME, you can use a CNAME like value at the apex. Cloudflare flattens this automatically.
First mistake: leaving TTL at 24 hours. When you are configuring a fresh domain, drop TTL to 300 seconds so propagation is fast. Raise it back later.
Second mistake: not deciding between www and apex. Pick one as canonical and 308 redirect the other to it. Otherwise Google sees two sites and your SEO fragments.
Third, this happened to me twice: if SSL has not provisioned in 24 hours, your DNS is wrong. Vercel only issues the certificate after seeing valid records.
Teams and preview workflow
Solo, preview URLs feel like a nice extra. With a team, they become the spine of the workflow. Each PR gets its own URL. QA tests there. The designer reviews there. The client signs off there. Coordinating those three handoffs is itself work.
Worth saying clearly: do not run that coordination through Slack threads alone. Which PR is on which preview, which feature belongs to which sprint, who still owes a review; that information needs a home. Our project board is built for this kind of orchestration, with deployment tasks, preview URL tracking, and approval chains in one place. The task tracker is also useful for pre deploy checklists that everyone actually sees.
Mistakes that cost hours
Here are the things that have cost me real time on Vercel, in no particular order.
Stale build cache is the most annoying. You add a package, the build passes, deploy succeeds, but the old version keeps running. On Redeploy, the "Use existing Build Cache" checkbox is on by default. Turn it off when something feels off. Almost everyone gets bitten by this once.
Wrong Root Directory in a monorepo is the second classic. You have apps/web with the Next.js app, but Vercel tries to build from the repo root. The build technically passes but the wrong project gets shipped. Settings, General, Root Directory, fix it.
Serverless function size limits are real. 50 MB on Hobby, 250 MB on Pro, compressed. A heavy Prisma client plus a few dependencies blows past Hobby. Move things to serverComponentsExternalPackages in next.config.js or trim the dependency tree. A misconfigured Sentry source map upload can balloon function bundles too; check that early.
Timezones are a quieter trap. Vercel functions run in UTC. If your code does new Date() expecting local time you get wrong values in production. Do all date math in UTC, convert to the user's zone only at render time.
Observability and what comes next
You shipped. It works. Now what happens when production breaks at 2am? Vercel Analytics gives you basic traffic shape on the free tier. For real visibility you want Sentry, Axiom, or a similar log pipeline. Function logs in the Vercel dashboard are kept for an hour and then gone, so route them somewhere durable for any serious debugging.
Add an uptime monitor right after your first production deploy. UptimeRobot, BetterStack, Checkly, anything. Vercel itself rarely goes down, but the third party APIs you depend on absolutely do, and Vercel will not warn you about that.
Using Vercel well starts with the docs but ends with a few late nights learning what the docs do not say. This post is the digest of a few of those nights. If you want to bring some order to your team's deploy process, you can try the Poitim live demo or look at our team management features. See you on the next ship.