Photo compressor online: how long it actually takes
Every other page on this site asks what the compressor does to the photo — how many bytes, how many pixels, how much quality. This one asks how long you wait. A 3000 × 2000 photograph, 689,299 bytes, was compressed at nine byte targets from 10 KB to 500 KB, and the tool's own reported time was recorded alongside an independent wall-clock measurement. Then a 54-megapixel photograph (6000 × 9000, 11.5 MB) went through the same nine targets. Then six different content types at one target. Then the same photo at the same target five times. The question this page answers is where the time goes, and whether it is the photo, the target, or the search algorithm that decides how long you wait.
Five numbers worth knowing before you compress a photo online
- The time peaks in the middle, not at the smallest target. On the 6 MP photograph, the longest compression was 4,191 ms at a 100 KB target — not at 10 KB (1,830 ms). The 200 KB target, where the tool keeps full dimensions, took only 1,171 ms. The peak happens where the tool transitions from full-frame quality search to dimension-scaling binary search.
- A 54 MP photo takes 11.6× longer than a 6 MP photo at the same target. At 500 KB: 14,895 ms vs 1,281 ms. The pixel ratio is 9×. At 60 KB the gap narrows to 1.4× (4,939 vs 3,532 ms), because both images hit the quality floor and the search converges faster when the target is far below the source.
- Output bytes are perfectly repeatable; time is not. Five runs of the same photo at 60 KB all produced 61,310 bytes. The tool's reported time ranged from 3,294 to 3,942 ms — a 648 ms spread (19.6%). The wall-clock measurement showed the same variation. The encoder is deterministic; the browser's scheduling is not.
- Content does not set the time — pixels and scaling do. At 60 KB, a 1.44 MP line chart finished in 248 ms (full frame, 94% quality). A 16 MP vector graphic took 6,907 ms (scaled to 56%, 40% quality). The chart is simpler content, but the reason it was fast is that it never needed scaling: one encode at full resolution hit the target.
- The tool does up to 16 encodes per compression. The search algorithm runs up to 9 resolution steps and 7 quality refinement steps. When the first full-frame encode at the quality floor already fits (generous targets), it stops after 1–2 encodes. When it must search for the right scale (tight targets), it does the full 16.
Two photographs (6 MP and 54 MP), nine byte targets each, six content types at one target, and five repeat runs — 29 compressions, 58 time measurements (tool-reported and wall-clock), 58 byte verifications (report vs FileReader), and 58 dimension verifications (report vs createImageBitmap). Measured 9 November 2026.
How to read these numbers: every compression was produced by this site's own compressor
(window.exactSize), one run per target, each in a fresh browser tab. The tool reports its own
elapsed time in the verdict string ("Done in N ms — …"); that number is extracted and labelled
"tool". An independent wall-clock time was also taken by wrapping the run() call in
Date.now() before and after, and waiting for the result panel to become visible; that number is
labelled "wall". The two measurements differ by 100–250 ms because the wall-clock includes tab creation,
file loading and DOM updates that the tool's timer does not. Output bytes were read two ways
(report().resultBytes and FileReader.readAsArrayBuffer().byteLength) and agreed on
all 29 runs. Output dimensions were read two ways (report().resultWidth/Height and
createImageBitmap) and agreed on all 29 runs. Whatever phrasing brought you here — photo compressor
online, online photo compressor, compress photo online — the tool is the same browser-based compressor, and the
"online" means it runs in the browser, not that the photo is uploaded.
The time curve: one photograph, nine targets
The source is a 3000 × 2000 night photograph, 689,299 bytes, already JPEG. It was compressed to nine byte targets: 10, 20, 30, 50, 60, 100, 200, 300 and 500 KB. For each target, the tool's reported time and an independent wall-clock time were recorded, along with the output bytes, dimensions and quality.
| Target | Output bytes | Dimensions | Quality | Tool time (ms) | Wall time (ms) | Encodes | What the tool did |
|---|---|---|---|---|---|---|---|
| 10 KB | 10,210 | 623×415 | 41.41% | 1,830 | 1,982 | ~10 | Scaled to 21%, quality floor held |
| 20 KB | 20,385 | 968×646 | 40.47% | 1,577 | 1,665 | ~10 | Scaled to 32%, quality floor held |
| 30 KB | 30,716 | 1230×820 | 40.47% | 2,087 | 2,204 | ~10 | Scaled to 41%, quality floor held |
| 50 KB | 50,980 | 1653×1102 | 40.47% | 3,105 | 3,179 | ~10 | Scaled to 55%, quality floor held |
| 60 KB | 61,310 | 1831×1221 | 40.47% | 3,532 | 3,687 | ~10 | Scaled to 61%, quality floor held |
| 100 KB | 102,087 | 2482×1655 | 40.47% | 4,191 | 4,257 | ~16 | Scaled to 83%, quality floor held |
| 200 KB | 202,286 | 3000×2000 | 58.28% | 1,171 | 1,399 | ~8 | Full frame, quality refined |
| 300 KB | 297,719 | 3000×2000 | 76.09% | 1,251 | 1,467 | ~8 | Full frame, quality refined |
| 500 KB | 511,019 | 3000×2000 | 81.25% | 1,281 | 1,404 | ~8 | Full frame, quality refined |
Nine targets on the same 689,299-byte photograph. "Tool time" is extracted from the tool's verdict string; "Wall time" is an independent Date.now wrapper. "Encodes" is estimated from the search algorithm's structure: 1 full-frame test + up to 9 scale steps + up to 7 quality steps, stopping early when a step fits. The tool does not expose its internal encode count, so the ~10 and ~16 figures are structural estimates, not measured counts. Bytes: report() vs FileReader, agreed on all 9. Dimensions: report() vs createImageBitmap, agreed on all 9.
Read the tool-time column from top to bottom. The time rises from 1,577 ms at 20 KB to 4,191 ms at 100 KB — a 2.66× increase as the target loosens. Then it drops sharply: 1,171 ms at 200 KB, a 3.58× drop from the peak. Below 200 KB the tool scales the dimensions; above 200 KB it keeps the full 3000 × 2000 and refines quality only. The peak sits exactly at the transition between these two regimes.
The reason is structural. Below 200 KB, the tool must find the largest scale at which the quality floor (40%) produces a file that fits — a binary search over resolution that takes up to nine encode steps. Then it refines quality upward in up to seven more steps. At 100 KB the target is loose enough that each scale step barely misses, so the search takes many steps to converge. At 10 KB every scale step produces a large byte difference, so the search converges in fewer steps. Above 200 KB the first full-frame encode at the quality floor already fits, so the scale search is skipped entirely — only the quality refinement runs.
The 54-megapixel curve: when the source is nine times larger
The same nine targets were run on a 6000 × 9000 photograph — 54 megapixels, 11,525,365 bytes. The source has nine times the pixels of the 6 MP photograph. The question is whether the time scales linearly with pixels, or whether the target's position relative to the source changes the shape of the curve.
| Target | Output bytes | Dimensions | Quality | Tool time (ms) | Wall time (ms) | 6 MP time (ms) | Ratio |
|---|---|---|---|---|---|---|---|
| 10 KB | 10,217 | 311×467 | 40.47% | 13,043 | 13,313 | 1,830 | 7.13× |
| 20 KB | 20,403 | 445×667 | 42.34% | 6,250 | 6,310 | 1,577 | 3.96× |
| 30 KB | 30,648 | 556×834 | 40.47% | 6,350 | 6,481 | 2,087 | 3.04× |
| 50 KB | 50,414 | 723×1085 | 40.47% | 6,033 | 6,178 | 3,105 | 1.94× |
| 60 KB | 60,079 | 790×1185 | 40.47% | 4,939 | 5,136 | 3,532 | 1.40× |
| 100 KB | 101,469 | 1024×1535 | 40.47% | 8,656 | 8,844 | 4,191 | 2.07× |
| 200 KB | 203,101 | 1458×2187 | 40.47% | 12,017 | 12,156 | 1,171 | 10.26× |
| 300 KB | 307,046 | 1803×2704 | 40.47% | 13,270 | 13,404 | 1,251 | 10.60× |
| 500 KB | 509,128 | 2360×3539 | 40.47% | 14,895 | 14,972 | 1,281 | 11.63× |
The same nine targets on a 54-megapixel photograph (6000 × 9000, 11,525,365 bytes). "Ratio" is the 54 MP tool time ÷ the 6 MP tool time at the same target. The pixel ratio is 9×. At 500 KB the time ratio is 11.6× — larger than the pixel ratio. At 60 KB it is 1.4× — much smaller. Bytes: report() vs FileReader, agreed on all 9. Dimensions: report() vs createImageBitmap, agreed on all 9.
The ratio column tells the story. At tight targets (10–60 KB) the 54 MP photo takes 1.4–7.1× longer than the 6 MP photo — less than the 9× pixel ratio. At generous targets (200–500 KB) it takes 10.3–11.6× longer — more than the pixel ratio. The crossover is at 100 KB.
The explanation is that on the 6 MP photo, targets above 200 KB are full-frame: the tool skips the scale
search and does only quality refinement, which is fast regardless of pixel count. On the 54 MP photo, no
target up to 500 KB is full-frame — the photo must always be scaled down, and every encode operates on the
full 54-megapixel source before scaling. The encoding step is where pixel count matters most, because
canvas.toBlob must JPEG-encode every pixel the canvas holds. At 500 KB on the 6 MP photo the
canvas is 3000 × 2000 = 6 million pixels; at 500 KB on the 54 MP photo the first full-frame test encodes
6000 × 9000 = 54 million pixels, and every subsequent scale step encodes progressively fewer. The first
encode alone takes longer than the entire 6 MP compression.
Six content types at one target: what sets the time
The first two experiments held the source constant and varied the target. The third holds the target constant — 60 KB — and varies the source. Six files of different content types and sizes were compressed. The question is whether content complexity directly affects the time, or whether the time is determined by the pixel count and the search path.
| Image | Source | Pixels | Output bytes | Dimensions | Quality | Tool time (ms) | Wall time (ms) |
|---|---|---|---|---|---|---|---|
| Line chart (1600×900) | 28,605 | 1.44 MP | 59,762 | 1600×900 | 94.38% | 248 | 446 |
| Text screenshot (1920×1080) | 83,101 | 2.07 MP | 60,676 | 1920×1080 | 64.38% | 419 | 488 |
| Product photo (2000×2000) | 117,632 | 4.00 MP | 59,923 | 2000×2000 | 84.06% | 683 | 764 |
| Smooth gradient (2400×1600) | 2,537,877 | 3.84 MP | 61,140 | 2400×1600 | 70.47% | 865 | 944 |
| Night photo (3000×2000) | 689,299 | 6.00 MP | 61,310 | 1831×1221 | 40.47% | 3,380 | 3,595 |
| Vector graphic (4000×4000) | 84,394 | 16.00 MP | 61,275 | 2234×2234 | 40.47% | 6,907 | 7,081 |
Six images compressed to 60 KB each. Source types: JPG (night photo, product), PNG (chart, graphic, text, gradient). The fastest was the 1.44 MP line chart (248 ms, full frame, 94% quality). The slowest was the 16 MP vector graphic (6,907 ms, scaled to 56%, 40% quality). The time ratio between fastest and slowest is 27.8×. Bytes: report() vs FileReader, agreed on all 6. Dimensions: report() vs createImageBitmap, agreed on all 6.
The pattern is clear once you separate the images into two groups. The first four — chart, text, product, gradient — all kept their original dimensions. The tool's first full-frame encode at the quality floor already fit, so the scale search was skipped and only quality refinement ran. Their times ranged from 248 to 865 ms, tracking pixel count: 1.44 MP → 248 ms, 2.07 MP → 419 ms, 4.00 MP → 683 ms, 3.84 MP → 865 ms.
The last two — the night photo and the vector graphic — both hit the quality floor and were scaled down. The tool had to run the full scale binary search, and each step required encoding the full source. The 6 MP night photo took 3,380 ms; the 16 MP vector graphic took 6,907 ms. The pixel ratio is 2.67×; the time ratio is 2.04×. The time tracks pixel count within the scaling regime too, but the absolute times are 4–8× higher than the full-frame regime at similar pixel counts.
The content itself — whether the image is a chart, a photograph, or a gradient — does not appear in the encoder's timing. What appears is whether the content is compressible enough to fit the target at full frame above the quality floor. The line chart's 94% quality means the tool barely needed to compress; the night photo's 40.47% quality means the tool exhausted its quality range and had to scale. The decision to scale or not — a binary structural choice — is what sets the time, not the texture of the pixels.
Five repeat runs: is the time deterministic?
The encoder is deterministic — the same input at the same target always produces the same output bytes. But is the time deterministic? The same 6 MP photograph was compressed to 60 KB five times, each in a fresh tab, to measure the variation.
| Run | Output bytes | Dimensions | Quality | Tool time (ms) | Wall time (ms) |
|---|---|---|---|---|---|
| 1 | 61,310 | 1831×1221 | 40.47% | 3,342 | 3,500 |
| 2 | 61,310 | 1831×1221 | 40.47% | 3,294 | 3,503 |
| 3 | 61,310 | 1831×1221 | 40.47% | 3,624 | 3,675 |
| 4 | 61,310 | 1831×1221 | 40.47% | 3,942 | 4,102 |
| 5 | 61,310 | 1831×1221 | 40.47% | 3,328 | 3,385 |
Five runs of the same photograph at the same 60 KB target. Output bytes: 61,310 in every run — perfectly identical. Tool time: 3,294–3,942 ms, a range of 648 ms (19.6% of the mean). Wall time: 3,385–4,102 ms, a range of 717 ms (21.2% of the mean). The variation is from browser scheduling and garbage collection, not from the encoder.
The bytes are fixed: 61,310, 1831 × 1221, quality 40.47% — five runs, zero variation. The time is not. The tool's reported time ranged from 3,294 to 3,942 ms, a 648 ms spread. The wall-clock ranged from 3,385 to 4,102 ms, a 717 ms spread. Both measurements show the same shape: the third and fourth runs were slowest, the first and fifth were fastest.
The variation comes from the browser's event loop, not the encoder. canvas.toBlob is
asynchronous: it yields to the event loop, and the event loop may be running garbage collection, layout
passes, or other internal tasks. The encoder itself — the quantization, Huffman coding and entropy
writing — is synchronous within each toBlob call, but the gaps between calls are not under the
encoder's control. On a 6 MP photograph at 60 KB the tool does approximately 10 encode calls, and a 50 ms
delay on each call adds 500 ms to the total — enough to explain the observed spread.
The practical consequence is that the time numbers on this page should be read as order-of-magnitude indicators, not as precise predictions. A 4,191 ms measurement means "about four seconds", not "exactly 4,191 milliseconds". The byte, dimension and quality numbers are exact and repeatable; the time numbers are environmental.
Where the time goes: the search algorithm
The compressor's search algorithm has two phases. Phase one — largestScaleThatFits — finds the
largest resolution at which one encode at the quality floor (40%) still fits the target. It is a binary
search over scale from 100% down to 5%, with up to 9 iterations. Each iteration draws the source to a canvas
at the current scale and calls canvas.toBlob('image/jpeg', 0.40). Phase two —
refineQuality — takes the scale found in phase one and binary-searches quality upward from 40%
to 100%, with up to 7 iterations. Each iteration calls canvas.toBlob again at the same scale but
a higher quality.
The total number of toBlob calls is at most 1 (initial full-frame test) + 9 (scale steps) + 7
(quality steps) = 17. In practice it is fewer because the search stops early when a step fits. The
approximate counts in the first table are structural estimates based on which regime the target falls in:
- Full-frame regime (200 KB and above on the 6 MP photo): The initial full-frame test at 40% quality already fits the target. Phase one is skipped (1 encode). Phase two runs up to 7 quality steps. Total: ~8 encodes. Time: ~1,100–1,300 ms.
- Scaling regime (100 KB and below): Phase one runs its full 9 steps (every scale step misses at first, because 40% quality at full frame is 277 KB — above the target). Phase two is skipped because quality is already at the floor. Total: ~10 encodes. Time: ~1,600–4,200 ms.
- The peak at 100 KB: At 100 KB, 40% quality at 83% scale produces 102,087 bytes — just barely fitting. The scale search takes most of its 9 steps to find 83%, and then quality refinement may run a few steps before concluding that quality cannot be raised. Total: ~16 encodes — the most work the algorithm does on any target.
The time per encode is not constant. It depends on the canvas size — which shrinks during the scale search — and on the quality parameter, which affects how long the Huffman coder runs. A full-frame encode at 40% quality on 6 million pixels takes roughly 150–200 ms. A scaled encode at 40% quality on 1 million pixels takes roughly 50–80 ms. The 4,191 ms total at 100 KB is approximately 16 encodes × 260 ms per encode — but the per-encode time varies because each scale step produces a different canvas size.
How to estimate the time before you compress
- Count the megapixels. The dominant factor in compression time is the source pixel count. A 6 MP photo takes 1–4 seconds; a 54 MP photo takes 5–15 seconds. The relationship is roughly linear in the scaling regime and sublinear when the target is generous enough to skip scaling.
- Check whether the target is generous or tight. If the target is above the source's 40%-quality full-frame size — roughly 277 KB on a 6 MP JPEG, roughly 2,500 KB on a 54 MP JPEG — the tool skips the scale search and runs only quality refinement. That is the fast path. If the target is below that threshold, the tool scales, and the time rises.
- The peak is at the threshold, not at the smallest target. The longest compression is at the target just below the full-frame threshold, where the tool must search many scale steps to find a fit. At very small targets the search converges faster because each step produces a large byte difference.
- Expect ±20% variation. The same compression run twice can differ by 20% in time due to browser scheduling. The output is identical; the time is not. If the time matters — for batch processing, for user experience — measure it rather than estimating.
- Use the tool, not a server upload. Every number on this page was produced in the browser. No photo was uploaded. The time you see is the time the browser spends encoding — not network latency, not server queue time. The 200 KB page shows what the tool does to the photo at each target; the quality reducer page shows what happens when you trade quality for bytes directly; and the segment audit shows where those bytes come off inside the JPEG structure.
Questions this page gets
How long does an online photo compressor take?
On a 3000 × 2000 photograph (689,299 bytes), the compressor took from 1,171 ms at a 200 KB target to 4,191 ms at a 100 KB target. The longest time was not at the smallest target — it was where the tool transitions from keeping full dimensions to scaling them down. On a 54 MP photograph, the same targets took from 4,939 ms to 14,895 ms.
Does a larger photo take longer to compress?
Yes. A 54 MP photo took 14,895 ms at 500 KB while a 6 MP photo took 1,281 ms — an 11.6× difference on a 9× pixel difference. At 60 KB the gap narrowed to 1.4× because both images hit the quality floor and the search converged faster.
Is the compression time repeatable?
The output bytes are perfectly repeatable: five runs at 60 KB all produced 61,310 bytes. The time is not: the tool reported 3,294–3,942 ms across five runs, a 19.6% spread. The variation comes from browser garbage collection and task scheduling.
Does image content affect compression time?
Indirectly. Six images at 60 KB showed times from 248 ms (a 1.44 MP line chart at 94% quality, full frame) to 6,907 ms (a 16 MP vector graphic at 40% quality, scaled to 56%). The content does not set the time — the pixel count and whether the tool needs to scale dimensions do.
Can I reduce image size and reduce jpg file size with this tool?
Yes. The tool compresses any image format — JPG, PNG, WebP — to a byte target you specify. When you reduce jpg file size, the tool re-encodes the JPEG at a lower quality or smaller dimensions to hit the target. When you reduce image size more broadly, the same search algorithm applies: it finds the combination of quality and dimensions that produces a file at or under your target. The time measurements on this page apply to any of these use cases, because the search path — and therefore the time — depends on the source pixel count and the target, not on what you call the operation. The segment audit page shows where those bytes come off inside the JPEG when you reduce jpg file size specifically, and the compress image size page maps where the pixel error lands across 40 tiles.
Is the photo uploaded when I compress it online?
No. Decoding, encoding and the byte-target search all run inside the browser tab. Every number on this page was produced by the same in-browser compressor you can use yourself, and no request carrying image data leaves the machine.
Why is the compression time longest in the middle of the target range?
Because the search algorithm does the most work there. At generous targets the first full-frame encode fits and the search stops. At very small targets the binary search converges quickly. In between — around 100 KB on this photograph — the search takes its full nine scale steps plus quality refinement steps, because each scale step barely misses the target.
Where the numbers come from. All figures measured on 9 November 2026 with Chrome
157.0.8103.38 (headless, driven over the DevTools protocol) on Windows 11, using this site's compressor
through its published interface (window.exactSize). Experiment one: one 3000 × 2000 night
photograph, 689,299 bytes, nine targets (10, 20, 30, 50, 60, 100, 200, 300, 500 KB), one run per target in a
fresh tab. Experiment two: one 6000 × 9000 photograph, 11,525,365 bytes, same nine targets, one run per
target in a fresh tab. Experiment three: six images of different content types and pixel counts, each
compressed to 60 KB, one run per image. Experiment four: the 6 MP photograph compressed to 60 KB five times,
each in a fresh tab. For every run, the tool's verdict string was parsed to extract the tool-reported time,
and an independent wall-clock time was taken by wrapping the run() call in
Date.now(). Output bytes were read from report().resultBytes and
FileReader.readAsArrayBuffer().byteLength — agreed on all 29 runs. Output dimensions were read
from report().resultWidth/Height and createImageBitmap — agreed on all 29 runs.
The five 6 MP byte values at 10/20/50/100/200/500 KB (10,210 / 20,385 / 50,980 / 102,087 / 202,286 / 511,019)
are byte-identical to this site's runs on the same photograph on 30 October, 2 November, 4 November, 5
November, 6 November, 7 November and 8 November — eight sessions, same bytes, confirming the encoder is
deterministic. The encode count estimates (~8, ~10, ~16) are structural inferences from the search algorithm's
code, not measured counts; the tool does not expose its internal encode counter. The per-encode time estimates
are derived by dividing total time by estimated encode count and are approximate. One machine, one browser
version: the absolute times will differ on different hardware; the relative patterns — the V-shaped curve,
the pixel-count scaling, the ±20% variation — are properties of the search algorithm and the browser's
asynchronous scheduling, not of this specific machine.
Read these alongside: the 200 KB page measures where the quality floor kicks in and dimension scaling starts — the transition point that creates the time peak; the image quality reducer runs the encoder at 19 fixed quality levels without a byte target, showing the cost curve when the search algorithm is bypassed; the JPEG segment audit parses the output file's binary structure to show where the bytes come off; the JPEG size reducer splits the error by colour channel at each target; the spatial distribution page cuts the photograph into 40 tiles and maps where the error lands; the second-pass page shows that re-compressing the output returns the identical file; the KB ladder puts six byte budgets in one table; and the WebP comparison measures the same targets in two formats, where WebP's longer encode time buys more pixels per byte.