Does converting the same HEIC twice give you the same JPG?

Yes — byte for byte. I ran 53 conversions on this converter today and got four distinct files out of them: one per input-and-quality pair, identical every single time.

53 conversions measured today 4 distinct outputs, 0 bytes differ 92–2,206 ms, same result

Short answer: the conversion is deterministic. The same HEIC at the same quality setting produces the same JPG down to the last byte — I compared the files with SHA-256, not by eye. One real photo (41,465 B, 700×476) came out as 38,078 B on all 31 runs I did of it today, with one hash: 93859de257dc44a7ff3dc41eb965d07ff84c8630ec8a3db44e24e89120713c81. Reloading the page did not change it. Opening a brand-new browser profile with an empty cache did not change it. Converting it in a different browser did not change it. Only one thing changed the bytes: the quality setting.

The practical upshot is that you never need to run a conversion twice hoping for a better result, and you can use a hash to prove two files are the same picture. What I cannot promise is that this stays true forever — if the converter's own code is updated one day, today's hash will not match tomorrow's output. Everything below was measured today on the live site.

How I tested it

I used two source files: a real iPhone photo (41,465 B, 700×476) and a synthetic 12-megapixel image (18,327 B, 4032×3024). Because the upload control ignores a second selection of the identical path, each run used a byte-identical copy with a different filename — the bytes going in were the same in every case. After each conversion I pulled the JPG out of the page and hashed it.

SetWhat I didRunsDistinct outputs
Aten conversions in a row, same page, never reloaded101
Breloaded the page before every conversion101
Cthree quality settings, three runs each93 — one per setting
Dthe same bytes under a different filename11
E + Ithe 12 MP file, three runs and then ten runs131
Fa freshly opened browser tab11
Ga brand-new browser profile with an empty cache11
Hsmall and large file interleaved, three rounds62 — one per file
—the same file in two different browsers21

That is 53 conversions and four distinct files. Every run finished with the page's error box empty, and every output kept the dimensions of its input — no cropping, no resizing, no warning.

Ten in a row: identical, and twelve times faster by the end

Set A is the plainest version of the question. I loaded the page once and converted the same photo ten times without reloading. All ten downloads were 38,078 B with the same hash. The timings are the interesting part — they moved a lot while the bytes did not.

RunConversion timeOutput
11,098 ms38,078 B
2238 ms38,078 B
3170 ms38,078 B
4132 ms38,078 B
5128 ms38,078 B
6108 ms38,078 B
7168 ms38,078 B
8130 ms38,078 B
999 ms38,078 B
1092 ms38,078 B

The first conversion in a session costs about ten times what the later ones do, because that is the one that has to get the decoder working. What matters here is that the fast runs and the slow run wrote exactly the same file. I compared the first and the tenth byte by byte afterwards: 0 of the 38,078 bytes differ.

Reloading, cold starts and a second browser

Set B reloaded the page before each of ten conversions, so every run started from a clean page. Times ran from 646 ms to 1,201 ms; all ten outputs were 38,078 B with the same hash.

Set G went further: a brand-new browser profile with an empty cache, so the decoder had to be downloaded from scratch. That run took 883 ms and produced the same 38,078 B file — I compared it with a warm run byte by byte and again found 0 differing bytes. A fresh tab (617 ms) and an interleaved run (158 ms) matched too.

Then I ran the same file in two browsers installed on this machine, each in its own fresh session: 38,078 B in 1,255 ms in one, 38,078 B in 1,716 ms in the other, same hash in both. And when I looked back at the numbers I recorded on 27 September from those same two browsers — 1,264 ms and 1,488 ms — the hash was the one I got today. So this input has produced one identical file across three days, two browsers and several dozen runs.

The one thing that does change the bytes

Quality. The page offers three settings, and each one has its own stable output — I ran each three times with a page reload in between and got the same file every time.

QualityRunsOutput sizeSHA-256 (first 16)Times
0.75330,231 B45be985b347327e6720 / 676 / 644 ms
0.85338,078 B93859de257dc44a7628 / 669 / 652 ms
0.95357,617 Bde678d5206fb5ce2745 / 740 / 653 ms

Note that the quality setting changes the size but not the speed: all nine runs landed between 644 ms and 745 ms. That matches what I measured on a much bigger set of files in the 200-file batch article.

Filenames travel into the name, not into the bytes

I made a copy of the same photo called My Photo (1) - final.HEIC — spaces, brackets, an uppercase extension. It converted in 665 ms to the same 38,078 B file with the same hash. The download was named My Photo (1) - final.jpg. So the name you give the file decides the name you get back, and nothing about it reaches the encoded picture.

No bleed between files

One worry with a converter that runs in a browser tab is whether a previous conversion leaves something behind. I interleaved the two files — small, large, small, large, small, large — in a single page session. The small file came back at 256 ms, 192 ms and 158 ms, always 38,078 B. The large file came back at 1,601 ms, 2,206 ms and 2,067 ms, always 100,826 B with hash 280de806af9863d5. Neither file's output moved when the other one was converted in between.

The 12-megapixel file also got its own run of ten: 1,457 / 1,576 / 1,318 / 731 / 651 / 647 / 684 / 710 / 612 / 606 ms, ten times 100,826 B, one hash. The first few runs are the slow ones again — the same warm-up pattern as the smaller file, and the same absence of any effect on the bytes.

Why the bytes never move

Two reasons, one structural and one that I checked in the code.

First, there is nowhere in the output to put a timestamp. I walked the structure of every output file: each one is FFE0 (JFIF), FFE2 (an ICC profile, 472 B), two quantisation tables, FFC0 (the frame header), four Huffman tables, then the scan. There is no FFE1 — no EXIF block — and the frame header declares 3 colour components. I also searched the raw bytes of the outputs for Exif, Adobe, CREATOR, Software and for the strings 2025 and 2026: zero occurrences of each. A file with no metadata block and no date field cannot differ between two runs unless the pixel data itself differs.

Second, the decoder does contain calls that look like sources of randomness — I read the file: Math.random once, Date.now 13 times, new Date 7 times, crypto.getRandomValues once. But the single Math.random is used to mint an identifier for messages sent to the worker thread; crypto.getRandomValues sits in the filesystem shim; the new Date calls are in file-status and time-zone helpers. None of them are on the path from decoded pixels to encoded JPEG. That is a reading of the code, though — the proof is the 53 runs, and they never disagreed.

What this means in practice

Determinism is not the same as losslessness, of course. The JPG is a re-encode of the HEIC and it does lose detail — I measured how much, pixel by pixel, in the quality-loss article. What is stable is that the loss is always the same loss.

What I did not test

Questions

Will converting the same HEIC twice give me two identical files?

Yes. Ten in a row on one page, ten with a reload before each, and one from a brand-new browser profile all produced 38,078 B with the same SHA-256. I compared the first and tenth byte by byte: 0 differences.

Does the filename affect the result?

Only the name of the download. A copy called My Photo (1) - final.HEIC produced the same 38,078 B hash as the original, and came back as My Photo (1) - final.jpg.

Does the quality setting change anything besides size?

Not in my runs. Each of the three settings produced its own fixed output — 30,231 B, 38,078 B and 57,617 B — repeated identically three times, at speeds between 644 ms and 745 ms that did not track the setting.

Why is the first conversion slower if the output is the same?

Warm-up. In one session the first run took 1,098 ms and later runs settled between 92 ms and 238 ms, all writing the same bytes. The slow run is the one that has to get the decoder going.

Can I get a different result by trying again?

No. 53 conversions today produced four distinct files, one per input-and-quality pair. Re-running is not a way to change the outcome — changing the quality setting is.

Does the converted file carry a creation timestamp?

No. I read the structure of the outputs: JFIF, an ICC profile, quantisation tables, frame header, Huffman tables, scan — no EXIF block at all, and no date strings in the bytes. That is also why two runs can be identical.

Is the JPG the same quality as the HEIC?

No — determinism is not losslessness. The output is a re-encode; how much it costs is measured in the pixel-by-pixel article.

Try it: open the converter, convert the same HEIC twice and compare the two files — they should be the same size to the byte.

First published: 30 September 2026