DEV Community

Anas Sheikh
Anas Sheikh

Posted on

Changing an Environment Variable on Vercel Doesn't Do Anything Until You Actually Redeploy

This causes a specific, recurring kind of confusion, someone updates an API key or a config value in their hosting dashboard, refreshes the live site expecting the new behavior, and sees the old value still very much in effect, with no error, no indication anything's wrong, just a value that appears to be stuck.

Why This Happens

Next.js resolves environment variables at different times depending on how they're used, and that distinction matters far more than it initially seems to.

NEXT_PUBLIC_ variables get inlined into the client JavaScript bundle at build time. This was covered in an earlier post about these values leaking into the browser, but the same mechanism has a second, less dangerous but equally confusing consequence, the actual value gets baked directly into the compiled JavaScript during the build step. Once that bundle exists, the value inside it is fixed, permanently, until a new build produces a new bundle. Changing the environment variable in your hosting dashboard afterward has zero effect on a bundle that's already been built and deployed.

Server-only variables read at request time genuinely do update immediately, since process.env.SOME_SECRET read inside a Server Action or route handler is evaluated fresh on every request, at runtime, not baked into anything at build time.

Statically generated pages sit in between. A page generated at build time, using generateStaticParams or simply being a static route with no dynamic data source, has its output, including any environment variable value referenced during that generation, fixed at that build moment. Even a server-only variable, if it's used to generate static content rather than read fresh on each request, won't reflect a later change until the next build regenerates that static output.

A Concrete Example of the Confusion

// next.config.ts
const nextConfig = {
  env: {
    API_BASE_URL: process.env.API_BASE_URL,
  },
};
Enter fullscreen mode Exit fullscreen mode
// Somewhere used inside a page that gets statically generated
const apiUrl = process.env.API_BASE_URL;
Enter fullscreen mode Exit fullscreen mode

Someone updates API_BASE_URL in the Vercel dashboard, pointing to a new endpoint, expecting the live site to immediately start hitting it. If this value feeds into anything statically generated, the already-deployed static output still references the old URL, since it was baked in at the previous build, and nothing about updating an environment variable in a dashboard triggers a new build on its own, that value change and an actual redeploy are two completely separate events.

Why Nobody Warns You About This Upfront

Most environment variable tutorials focus entirely on setup, getting a value into your app at all, and rarely cover the lifecycle question, when exactly does a change to that value actually take effect. It's a genuinely reasonable mental model to assume an environment variable behaves like a live configuration switch, flip it, see the effect immediately, since that's how environment variables often work in simpler, non-static-generation contexts. Next.js's mix of build-time and runtime resolution breaks that mental model in ways that aren't obvious until you've specifically been burned by it.

The Actual Rule

If a value is used anywhere that gets pre-rendered, NEXT_PUBLIC_ variables always, statically generated pages sometimes, changing it in your hosting dashboard requires an actual new deployment before the change takes effect anywhere. If a value is read purely at request time, inside a Server Action, a route handler, or a dynamically rendered page with no static generation involved, a dashboard change genuinely does take effect on the very next request, no redeploy needed.

How to Actually Tell Which Case You're In

Ask whether the specific code reading this variable runs during the build (page generation, next.config.ts, anything feeding generateStaticParams) or during an actual live request (a Server Action, a route handler, a dynamically rendered page). Build-time usage needs a redeploy for any change to matter. Request-time usage picks up a dashboard change immediately.

When in doubt, just redeploy after any environment variable change. This is the safe, low-effort default, a redeploy after an env var update costs a few minutes and completely eliminates the ambiguity, versus spending real time debugging why a "clearly correct" configuration change appears to be having zero effect on the live site.

Why This Matters More for Secrets Rotation Specifically

This has real security implications too, not just convenience ones. If you rotate a compromised API key or secret by updating it in your hosting dashboard, and any part of your app statically baked the old value in, that old, compromised value can remain live and in use until an actual redeploy happens, well after you believed the rotation was already complete. Treating "updated the environment variable" and "the new value is actually live everywhere it matters" as two separate, sequential steps, not one single action, matters especially in exactly this scenario.


If you've ever updated an environment variable and been confused why the change didn't seem to take effect, genuinely curious whether this was the actual cause, or something else entirely. Drop your experience in the comments.

Get the templates: https://pixelanas.gumroad.com


Anas, full-stack Next.js developer building SaaS products and premium templates. X: @ASheikh69751

Top comments (0)