GPT-4o Image Input: Resolution, Tiling and the Token Cost Before You Send
9 min read · updated August 11, 2026
An image costs input tokens, and the count is computable from its dimensions before you send it. OpenAI documents the resize-and-tile procedure exactly, which means you never have to guess and never have to discover the price from an invoice.
The documented formula
OpenAI’s vision guide specifies the procedure for detail: "high" in four steps. Every image goes through all four; nothing here is approximate.
- Fit within 2048 × 2048. If either side exceeds 2048, scale the image down preserving aspect ratio until both sides fit. If it already fits, nothing happens.
- Scale the shortest side to 768. Preserving aspect ratio again. This step scales both down and up — a small image is enlarged to meet it.
- Count 512 × 512 tiles. Divide each dimension by 512 and round up, then multiply. A partial tile is a whole tile.
- Apply the token formula. For the GPT-4o family, 85 base tokens plus 170 per tile.
tokens = 85 + 170 × ceil(w′/512) × ceil(h′/512) where (w′, h′) are the dimensions after steps 1 and 2.
Two constraints sit outside the formula and are worth knowing before you build an upload path. The accepted formats are PNG, JPEG, non-animated GIF and WebP, and there is a documented per-image size limit measured in megabytes rather than pixels — an image can be well inside the dimension rules and still be rejected for being a heavyweight PNG. Images can be supplied either as a URL the API fetches or as a data: URI carrying base64, and the base64 form inflates the payload by about a third on the wire, which is a request-size problem rather than a token problem: base64 length has no effect at all on the token count, because the count is computed from the decoded image’s dimensions.
Note also what is not in the formula: content. A blank white rectangle and a dense page of text at the same dimensions cost exactly the same. Image tokens are a function of geometry alone, which is what makes the cost computable in advance and is why there is no equivalent of the “this text tokenises badly” problem that affects written input.
Three images, worked
A 1024 × 1024 screenshot
step 1 1024 × 1024 already fits inside 2048 × 2048 → unchanged
step 2 shortest side is 1024; scale to 768
factor = 768 / 1024 = 0.75
1024 × 0.75 = 768 → 768 × 768
step 3 ceil(768/512) = 2 ceil(768/512) = 2
tiles = 2 × 2 = 4
step 4 85 + 170 × 4 = 85 + 680 = 765 tokens765 input tokens — roughly a thousand words of English prose, for one square screenshot.
A 2048 × 4096 phone photo, portrait
step 1 4096 > 2048, so scale to fit
factor = 2048 / 4096 = 0.5
2048 × 0.5 = 1024 → 1024 × 2048
step 2 shortest side is 1024; scale to 768
factor = 768 / 1024 = 0.75
2048 × 0.75 = 1536 → 768 × 1536
step 3 ceil(768/512) = 2 ceil(1536/512) = 3
tiles = 2 × 3 = 6
step 4 85 + 170 × 6 = 85 + 1020 = 1105 tokensA 1800 × 1200 landscape photograph
step 1 both sides ≤ 2048 → unchanged
step 2 shortest side is 1200; scale to 768
factor = 768 / 1200 = 0.64
1800 × 0.64 = 1152 → 1152 × 768
step 3 ceil(1152/512) = 3 ceil(768/512) = 2
tiles = 3 × 2 = 6
step 4 85 + 170 × 6 = 1105 tokensTwo things fall out of putting these side by side. First, the phone photo at 8.4 megapixels and the landscape shot at 2.2 megapixels cost exactly the same, because after step 2 they land in the same tile grid. Uploading the full-resolution original bought nothing. Second, the rounding-up in step 3 makes the cost a step function: 1152 pixels wide costs three tiles across, and so does 1025. Cropping 1152 down to 1024 saves 170 tokens and loses very little.
The low-detail flat rate
Set detail: "low" and none of the above applies. The image is reduced to a fixed low-resolution representation and costs a flat 85 tokens for the GPT-4o family, whatever its dimensions.
{
"role": "user",
"content": [
{"type": "text", "text": "Is there a person in this frame?"},
{"type": "image_url",
"image_url": {
"url": "https://example.com/frame-00871.jpg",
"detail": "low"
}}
]
}85 against 765 is a factor of nine, and for a large class of tasks it is the right trade. Presence detection, scene classification, dominant colour, rough layout, is-this-a-receipt — none of these need full-resolution tiles. What low detail cannot do is read text, count small objects, or notice fine structure. If you are running frames from a video through a model, this parameter is the difference between a viable pipeline and an unaffordable one.
The default is detail: "auto", which lets the model choose. That is convenient and makes cost unpredictable per request, which is a poor trade for a batch job. Set it explicitly wherever the bill matters.
Why gpt-4o-mini’s numbers look wrong
gpt-4o-mini uses the same geometry and much larger constants — its documented per-image token counts are far higher than GPT-4o’s for the same picture. This looks like an error and is not. The mini model’s per-token price is a small fraction of GPT-4o’s, and the image token counts are scaled so that the resulting cost per image lands in a comparable place. The tokens are the billing unit, not a measure of how much the model looked at.
The practical consequence is that you cannot compare image cost across models by comparing token counts. Multiply by the per-token price first. It is also why image tokens can consume the context window faster than you expect on the smaller model: they are counted against the window at their nominal value, not their price-adjusted one.
What to do before you send
- Resize client-side to the tile grid. The server is going to scale the shortest side to 768 regardless. Doing it yourself first cuts upload time and bandwidth and changes the token count not at all. Sending a 12-megapixel original is pure waste.
- Aim at tile boundaries. Because step 3 rounds up, dimensions just past a multiple of 512 are the expensive ones. If you control the crop, land on or just under the boundary.
- Compute the cost before the call. The formula is six lines of code and turns image spend from a surprise into a number you can put a limit on. Multiple images multiply — each one is counted independently and they add, which is the mechanism behind multiple images in one request.
- Watch the window, not just the bill. Ten high-detail images is on the order of ten thousand tokens of context gone before your prompt starts, against the budget described in GPT-4o’s context window.
- Split a large image rather than shrinking it. Step 2 scales the shortest side to 768 whatever you send, so a very tall document scan loses detail in the direction you care about. Cropping it into two or three overlapping sections and sending them as separate images costs more tokens and preserves the resolution that makes small text legible — which is usually the actual goal.
- Decide detail per call site, not per application. The same pipeline often has both kinds of question in it: a cheap filter pass at
detail: "low"deciding which frames are worth looking at, and adetail: "high"pass on the survivors. That two-stage shape is where the nine-to-one ratio between the two rates turns into a real saving rather than a table of numbers.