<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Oleksandr | CalculatorAI</title>
    <description>The latest articles on DEV Community by Oleksandr | CalculatorAI (@calculatoraiapp).</description>
    <link>https://dev.to/calculatoraiapp</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4064358%2F51b52a41-06ed-424b-b8f3-33cd77816d03.jpeg</url>
      <title>DEV Community: Oleksandr | CalculatorAI</title>
      <link>https://dev.to/calculatoraiapp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/calculatoraiapp"/>
    <language>en</language>
    <item>
      <title>77% of my Google crawl budget was spent re-downloading the same 222 files</title>
      <dc:creator>Oleksandr | CalculatorAI</dc:creator>
      <pubDate>Wed, 05 Aug 2026 15:42:32 +0000</pubDate>
      <link>https://dev.to/calculatoraiapp/77-of-my-google-crawl-budget-was-spent-re-downloading-the-same-222-files-7bi</link>
      <guid>https://dev.to/calculatoraiapp/77-of-my-google-crawl-budget-was-spent-re-downloading-the-same-222-files-7bi</guid>
      <description>&lt;p&gt;I run a Next.js site on Vercel with about 7,600 URLs in the sitemap. Google had indexed 2,700 and left 4,790 alone. Three thousand of those were sitting in &lt;strong&gt;Discovered – currently not indexed&lt;/strong&gt;, which means Google found the URL and never actually fetched it.&lt;/p&gt;

&lt;p&gt;That is the polite way of saying: you are publishing faster than we are crawling.&lt;/p&gt;

&lt;p&gt;So I opened the &lt;em&gt;Crawled – currently not indexed&lt;/em&gt; report to find out what the crawler was spending its time on instead.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw14zeaea2e59244pzpdm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw14zeaea2e59244pzpdm.png" alt=" " width="799" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The mistake I nearly shipped&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Looking at the example URLs on screen, it looked obvious. Non-English locales everywhere. Clearly Google was skipping my translated pages and I needed to go rework hreflang.&lt;/p&gt;

&lt;p&gt;I was about a day of work away from doing exactly that.&lt;/p&gt;

&lt;p&gt;Then I exported the CSV instead.&lt;/p&gt;

&lt;p&gt;Out of 1,000 URLs in that bucket:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;971&lt;/strong&gt; were &lt;code&gt;/_next/static/**&lt;/code&gt; or &lt;code&gt;/favicon.ico&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;those 971 URLs pointed at only &lt;strong&gt;222 distinct files&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;so ro
ughly &lt;strong&gt;77% were duplicate crawls of assets Google already had&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The locale theory was never in danger. It just happened to be what the top of the list looked like.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here is why that happens, and it will happen to you too:&lt;/strong&gt; the examples Search Console shows in the UI are sorted by last crawl date. Your newest real pages sit on top. The bulk of the bucket — which is what you actually want to see — is below the fold and you never scroll to it. Eyeball that list and you will generalise from a biased sample every single time.&lt;/p&gt;

&lt;p&gt;Export the CSV before you conclude anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What was actually happening&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vercel has a feature called &lt;strong&gt;Skew Protection&lt;/strong&gt;. When you deploy while someone is mid-session, their browser may ask for a chunk that no longer exists in the new build. Skew Protection fixes that by appending &lt;code&gt;?dpl=&amp;lt;deploy-id&amp;gt;&lt;/code&gt; to every static asset URL, so a client keeps getting the build it started with.&lt;/p&gt;

&lt;p&gt;It is a genuinely good feature and it solves a real problem.&lt;/p&gt;

&lt;p&gt;It also means that every single deploy mints a complete new set of URLs for byte-identical files. And Googlebot does not know that &lt;code&gt;main.js?dpl=aaa&lt;/code&gt; and &lt;code&gt;main.js?dpl=bbb&lt;/code&gt; are the same thing. It sees two URLs, so it fetches two URLs.&lt;/p&gt;

&lt;p&gt;By the time I looked, it had crawled &lt;strong&gt;113 distinct dpl values&lt;/strong&gt;. One font file, 39 times. The favicon, 37 times.&lt;/p&gt;

&lt;p&gt;All of that came out of the same crawl budget those 3,005 real pages were queued in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix, and the fix not to make&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Turning Skew Protection off (Vercel dashboard → Settings → Advanced) stops new ones being minted. Asset filenames are already content-hashed, so caching is unaffected. The tradeoff you accept back is the original problem: a tab left open across a deploy can hit a chunk-load error.&lt;/p&gt;

&lt;p&gt;For a content site where deploys are frequent and sessions are short, that is a trade worth making. For a long-session app it might not be.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you should not do is "fix" it with &lt;code&gt;Disallow: /_next/static&lt;/code&gt; in robots.txt.&lt;/strong&gt; I have seen this suggested and it is worse than the disease:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google needs your CSS and JavaScript to render the page and judge mobile usability. Block them and you are handing it a broken page to evaluate.&lt;/li&gt;
&lt;li&gt;It would not drain the queue anyway. robots.txt stops the fetch, not the knowing. The URLs stay known, they just get relabelled as blocked, and everything already queued stays queued.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fix it at the source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I would check on your own site&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you are on Vercel with Next.js and you have more than a few hundred URLs, go and look at how many distinct &lt;code&gt;dpl&lt;/code&gt; values Google has crawled. That number is your deploy count wearing a different hat — and unlike most SEO problems, it is entirely under your control.&lt;/p&gt;

&lt;p&gt;Which is the part I did not expect. This turned out to be the third independent reason to deploy less often, after ISR write costs and build minutes. I had been treating deploy frequency as a free variable. It is not.&lt;/p&gt;

&lt;p&gt;(This came out of building &lt;a href="https://calculatorai.app" rel="noopener noreferrer"&gt;CalculatorAI&lt;/a&gt; — a Next.js site with about 7,600 indexed URLs, which is how the numbers above got so specific.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The honest ending&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It has been a few days since I turned it off. The old URLs do not 404 — a query param on a static asset still serves the file — so they do not vanish, they just stop being referenced from any rendered page. My assumption is Google deprioritises them once they stop appearing.&lt;/p&gt;

&lt;p&gt;But I am not going to claim the queue has drained, because I do not know yet. Ask me in a month.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>seo</category>
      <category>vercel</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
