Build1 distinct publisher2 min readPublished
The instance that answered the last request may not exist for the next one. A Map at module scope is therefore storage with no defined lifetime, and the symptom is data that changes between identical calls.
The Engineer · Build desk

build
Your Next.js rate limiter counts per instance, and Server Actions hide behind the page URL1 distinct publisher
build
Next.js 16.3's memory claim didn't reproduce; its TypeScript handoff cut a build by two thirds1 distinct publisher
build
With CRA out of React's docs, the new project default is a rendering decision1 distinct publisher
build
A Timed-Out Reset SMS Is Not A Failed One, And Your Retry Code Probably Disagrees1 distinct publisher
Compiled by The EngineerSomething wrong?How this is made
`const cache = new Map()` at module scope runs once per instance, not once per deployment. That is the whole bug. When a request arrives, Vercel either hands it to a warm instance left over from recent traffic, or builds a fresh one: load the Node.js runtime, import every module the function depends on, run module-level initialization, then answer [4]. Each fresh instance gets its own empty Map [7].
A cache hit here depends on which instance answered, not on the key itself, and the caller cannot see that and the code cannot ask [16]. Requests arriving in a burst share a warm instance and see the stored value; the first request after an idle gap lands on a new instance and sees a miss [6][7]. According to the dev.to writeup, that is precisely what produced the inconsistent responses: a cache that existed in one instance and not another, both serving the same endpoint [8]. Three days went into looking for it in the query logic [3].
It worked in local development, which is the most expensive kind of working [9].
The counter version fails more quietly. Rate limiting in the same codebase tracked how many requests an IP had made in a rolling window, in memory [11]. Keep that counter at module scope and the enforced ceiling becomes the configured limit multiplied by the number of instances currently holding a counter [15]. Three live instances, three times the allowance. Traffic growth adds instances, so the limiter loosens exactly when you wanted it to bite, and it returns success the entire time.
For module-scope state to be safe here, two things have to hold: it is derivable from the deployment alone, and no request's correctness depends on an earlier request having run. A compiled regex qualifies. A database client handle qualifies. A lookup cache fails this test, because a miss changes the response and not just its latency. A counter fails it too, because the count is the response.
Scope note, because this is one developer's first-hand account of one JSON API deployed inside Next.js API routes [1][17]. There are no instance counts in it and no measured warm window. The post says Vercel keeps instances warm for a period after their last request [6]. That period is the parameter you would need to design around, and it is not one you set. Which is the actual statement the platform is making: the same Map on a long-running Express process behaves as expected because the process outlives the request [10], and serverless sells you the opposite guarantee.
Ranked by verification strength, evidence, and original report placement.
The author built a straightforward backend as a JSON API with no rendering and no pages, just endpoints returning data to a frontend elsewhere, and deployed it on Vercel.
The API returned different data on consecutive requests: same endpoint, same query parameters, same database, inconsistent response.
The author spent three days assuming the inconsistency was a bug in his own code before realising it was not.
When a request hits a Vercel serverless function, a warm instance from a recent request handles it if one is available; otherwise Vercel spins up a fresh instance, which loads the Node.js runtime, imports every module the function depends on, runs any module-level initialization code, and only then handles the request.
On a long-running server all initialization happens exactly once, when the server first starts; on serverless it can happen on almost every request, depending on traffic.
Vercel keeps instances warm for a period after their last request to avoid cold starts on rapid successive traffic, but if the API goes idle for even a few minutes that warmth is gone and the next request pays the full cold start cost.
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 31, 2026
Follow any of these and your For You feed starts watching them — no settings page required.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
One developer's notebook, verifiable mechanism
Every factual load in this story rests on a single dev.to post: no platform documentation for the warm window, no logs, no instance identifiers, no reproduction by anyone else. What keeps the score from being lower is that the central artefacts are code — a module-level Map behind a handler, the same Map behind an Express route — which any reader can run and confirm without trusting the author at all.
No adoption signal to read
Nothing in this reporting counts as uptake: no release, no rollout, no benchmark, no disclosed traffic. A single hobby-scale API on a free tier tells us what one person deployed, not how widely the pattern or the platform behaviour bites.
Sober diagnosis, slightly wide conclusion
The headline promises what broke and the body largely delivers mechanics rather than verdicts, which is unusually restrained for the genre. The small overhang comes from generalising one free-tier project into platform behaviour, and from the ten-per-minute-per-instance figure, which is arithmetic on a code sample presented with the confidence of an observation.
Nothing sold, a reputation earned
No product, sponsor or competing platform is being pushed here; the visible payoff is the one dev.to runs on, which is credit for a good war story. That still shapes the telling — a three-day mystery with a clean reveal is a better post than a shrug about a documented limitation — but it does not point the conclusions anywhere self-serving.
Confident in the mechanism, not the incident
Split the story in two and the confidence splits with it. The serverless behaviour it describes is internally consistent, matches its own code samples and would be trivial to falsify, so we hold it firmly. The particular deployment, the three days, the exact idle window — single-sourced and untested, and the text cuts off before the remedy, so we cannot judge what the author concluded to do about it.