Optimize image tokens
On this page
Control your costs in production
In production, image tokens can make up a significant portion of your API bill. A single image in high mode consumes up to 1,792 tokens—equivalent to several paragraphs of text. Multiply that by hundreds or thousands of daily requests, and optimization becomes a necessity.
Strategy 1: Choose the right level of detail
The detail parameter is your primary optimization lever. The most common mistake is using high by default when low or auto suffice in most cases.
Decision matrix
| Task | Recommended detail | Estimated tokens |
|---|---|---|
| Image classification | low | ~256 |
| General description | auto | ~512-768 |
| Alt text / accessibility | low | ~256 |
| Content moderation | auto | ~512-768 |
| OCR / text extraction | high | ~1024-1792 |
| Chart analysis | high | ~1024-1792 |
| Defect detection | high | ~1024-1792 |
Strategy 2: Resize before sending
High-resolution images (4K, 8K) are rarely necessary for AI analysis. Consistently resizing your images before sending them reduces tokens without perceptible impact on analysis quality.
from PIL import Image
import io
import base64
class OptimiseurImage:
TAILLES_PAR_TACHE = {
"classification": (512, 512),
"description": (1024, 1024),
"ocr": (2048, 2048),
"comparison": (800, 800),
}
@staticmethod
def optimiser(chemin, tache="description", qualite=85):
taille_max = OptimiseurImage.TAILLES_PAR_TACHE.get(
tache, (1024, 1024)
)
img = Image.open(chemin)
# Do not enlarge small images
if img.width <= taille_max[0] and img.height <= taille_max[1]:
pass
else:
img.thumbnail(taille_max)
# Convert to JPEG to reduce size
if img.mode in ("RGBA", "P"):
img = img.convert("RGB")
buffer = io.BytesIO()
img.save(buffer, "JPEG", quality=qualite)
buffer.seek(0)
encoded = base64.standard_b64encode(buffer.read()).decode()
return f"data:image/jpeg;base64,{encoded}"
Strategy 3: Two-pass pipeline
For high volumes, use a two-pass pipeline—a fast first pass in low to sort, then a second pass in high only for images that require it:
def pipeline_deux_passes(images):
# Pass 1: fast classification (low)
classifications = []
for img in images:
response = client.responses.create(
model="grok-4.5",
input=[
{"type": "input_image", "image_url": img, "detail": "low"},
{"type": "input_text", "text": "Classify: document, photo, chart, other. One word."}
],
store=False
)
classifications.append({
"url": img,
"type": response.output_text.strip().lower()
})
# Pass 2: detailed analysis (high) only if necessary
resultats = []
for item in classifications:
if item["type"] in ("document", "chart"):
detail = "high"
else:
detail = "auto"
response = client.responses.create(
model="grok-4.5",
input=[
{"type": "input_image", "image_url": item["url"], "detail": detail},
{"type": "input_text", "text": "Detailed analysis of this image."}
],
store=False
)
resultats.append(response.output_text)
return resultats
Strategy 4: Caching
If you analyze the same images multiple times (tests, development, demo), cache the results:
import hashlib
import json
cache = {}
def vision_avec_cache(image_url, prompt, detail="auto"):
# Create a unique key
cle = hashlib.sha256(
f"{image_url}:{prompt}:{detail}".encode()
).hexdigest()
if cle in cache:
return cache[cle]
response = client.responses.create(
model="grok-4.5",
input=[
{"type": "input_image", "image_url": image_url, "detail": detail},
{"type": "input_text", "text": prompt}
],
store=False
)
cache[cle] = response.output_text
return response.output_text
Monitor and alert
Set up cost tracking to detect overruns:
def monitorer_tokens(response, seuil_alerte=5000):
usage = response.usage
image_tokens = usage.prompt_tokens_details.image_tokens
if image_tokens > seuil_alerte:
print(f"ALERT: {image_tokens} image tokens (threshold: {seuil_alerte})")
return {
"image_tokens": image_tokens,
"text_tokens": usage.prompt_tokens_details.text_tokens,
"total": usage.total_tokens
}
Key takeaways
- Choose the
detaillevel suited to the task—lowwhen sufficient - Resize images before sending to reduce consumption
- Use a two-pass pipeline for high volumes
- Cache results to avoid redundant calls
- Monitor image tokens in production to anticipate costs