How to Configure `remoteImagesDownloadsDelay` for External Images in next-export-optimize-images
The remoteImagesDownloadsDelay option in next-export-optimize-images inserts a configurable pause between each remote image download to prevent CDN rate limiting during static exports.
When statically exporting a Next.js site that references external images, next-export-optimize-images downloads those assets to optimize them locally. For projects with hundreds of remote images hosted on CDNs with strict request quotas, the remoteImagesDownloadsDelay configuration property allows you to throttle the download speed programmatically.
Why Use remoteImagesDownloadsDelay?
Static exports that pull thousands of images from external CDNs can trigger rate limiting or 429 Too Many Requests errors. Without delays, the library’s default concurrency (10 parallel downloads) may overwhelm free-tier API gateways or budget CDNs. By introducing a modest pause between fetches—measured in milliseconds—you distribute traffic evenly and keep export times acceptable while respecting provider thresholds.
How remoteImagesDownloadsDelay Works Internally
The delay mechanism spans three critical points in the codebase: type definition, CLI forwarding, and the download loop.
Type Definition in src/utils/getConfig.ts
The configuration schema declares remoteImagesDownloadsDelay as an optional number within the public Config interface. According to the source at lines 111–115, the property is documented specifically for rate-limited CDNs:
/**
* In case you need to download a large amount of images from an external CDN with a rate limit,
* this will add delays between downloading images.
*/
remoteImagesDownloadsDelay?: number
CLI Integration in src/cli/index.ts
The CLI entry point reads your export-images.config.js via getConfig() and forwards the value to the downloader. At lines 240–245, the configuration object explicitly passes the delay setting:
remoteImagesDownloadsDelay: config.remoteImagesDownloadsDelay,
Download Loop Implementation in src/cli/external-images/index.ts
The actual throttling occurs inside the external-image downloader. A helper sleep function creates the pause:
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
Before each fetch operation, the code checks for the configuration value and awaits the sleep promise:
if (remoteImagesDownloadsDelay) {
await sleep(remoteImagesDownloadsDelay) // ← pause between downloads
}
Concurrency Interaction: The delay works alongside the processingConcurrency option (default 10). While concurrency limits how many images download simultaneously, remoteImagesDownloadsDelay controls how fast the next batch begins, allowing fine-grained tuning for aggressive rate limiters.
Configuring remoteImagesDownloadsDelay
Basic Configuration
Create or modify export-images.config.js in your project root and add the delay in milliseconds. A value of 300 pauses one-third of a second between each request:
// export-images.config.js
module.exports = {
// …other options
remoteImagesDownloadsDelay: 300, // pause 300 ms between each remote image download
}
Omitting the key or setting it to 0 disables the delay entirely.
Optimizing with Concurrency Limits
For strict quotas, combine the delay with a reduced concurrency limit to minimize parallel load:
module.exports = {
remoteImagesDownloadsDelay: 200, // 0.2 s pause
processingConcurrency: 5, // only 5 downloads at once
}
This configuration sends five requests, waits 200 ms, then launches the next five, keeping total throughput under typical CDN thresholds.
Dynamic Environment-Based Delays
If the delay must vary by environment (e.g., slower for production CDNs, faster for staging), export a function instead of a static object. The CLI resolves function-based configs automatically via getConfig():
// export-images.config.js
module.exports = () => ({
remoteImagesDownloadsDelay: Number(process.env.IMAGE_DELAY_MS) || 0,
processingConcurrency: 8,
})
Summary
remoteImagesDownloadsDelayis defined insrc/utils/getConfig.tsand accepts a number of milliseconds.- The CLI forwards the value from
src/cli/index.tsto the external-image downloader. - The downloader applies the delay in
src/cli/external-images/index.tsusing asleephelper before each fetch. - The option pairs with
processingConcurrencyto balance speed and rate-limit compliance. - Setting the value to
0or omitting it disables throttling.
Frequently Asked Questions
What is the default value of remoteImagesDownloadsDelay?
If omitted from export-images.config.js, the option defaults to undefined, which evaluates as falsy and disables the delay mechanism entirely. Downloads proceed at full speed limited only by processingConcurrency.
Does remoteImagesDownloadsDelay affect local image processing?
No. The delay applies exclusively to external images fetched from remote CDNs during the manifest processing phase. Local images referenced by relative paths process without artificial delays.
How do I choose the right delay value?
Start with your CDN’s documented requests-per-second limit. If the limit is 10 requests per second, a delay of 100 (ms) theoretically spaces requests evenly. In practice, use 200–500 ms to account for network jitter and headers overhead, then adjust based on whether you still receive 429 errors in logs.
Can I use remoteImagesDownloadsDelay with custom downloaders?
The delay is built into the library’s internal downloader in src/cli/external-images/index.ts. If you implement a custom download strategy, you must implement your own throttling logic; the CLI will still pass the configuration value to your handler, but the built-in sleep wrapper will not apply automatically.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →