High memory usage when processing many images
Issue
When using generateText or streamText with many images (e.g., in a loop or batch processing), you may notice:
- Memory usage grows continuously and doesn't decrease
- Application eventually runs out of memory
- Memory is not reclaimed even after garbage collection
This is especially noticeable when using experimental_download to process images from URLs, or when sending base64-encoded images in prompts.
Background
By default, the AI SDK includes the full request and response bodies in the step results. When processing images, the request body contains the base64-encoded image data, which can be very large (a single image can be 1MB+ when base64 encoded). If you process many images and keep references to the results, this data accumulates in memory.
For example, processing 100 images of 500KB each would include ~50MB+ of request body data in memory.
Solution
Use the experimental_include option to disable inclusion of request and/or response bodies:
import { generateText } from 'ai';import { openai } from '@ai-sdk/openai';
const result = await generateText({ model: openai('gpt-4o'), messages: [ { role: 'user', content: [ { type: 'text', text: 'Describe this image' }, { type: 'image', image: imageUrl }, ], }, ], // Disable inclusion of request body to reduce memory usage experimental_include: { requestBody: false, responseBody: false, },});Options
The experimental_include option accepts:
requestBody: Set tofalseto exclude the request body from step results. This is where base64-encoded images are stored. Default:true. Available in bothgenerateTextandstreamText.responseBody: Set tofalseto exclude the response body from step results. Default:true. Only available ingenerateText.
When to use
- Batch processing images: When processing many images in a loop
- Long-running agents: When an agent may process many images over its lifetime
- Memory-constrained environments: When running in environments with limited memory
Trade-offs
When you disable body inclusion:
- You won't have access to
result.request.bodyorresult.response.body - Debugging may be harder since you can't inspect the raw request/response
- If you need the bodies for logging or debugging, consider extracting the data you need before the next iteration
Example: Processing multiple images
import { generateText } from 'ai';import { openai } from '@ai-sdk/openai';
const imageUrls = [ /* array of image URLs */];const results = [];
for (const imageUrl of imageUrls) { const result = await generateText({ model: openai('gpt-4o'), messages: [ { role: 'user', content: [ { type: 'text', text: 'Describe this image' }, { type: 'image', image: imageUrl }, ], }, ], experimental_include: { requestBody: false, }, });
// Only store the text result, not the full result object results.push(result.text);}