Every time you convert a photo, pull a frame out of a video or pack files into an archive, a service we run does the work. In September we rewrote it from top to bottom. This post measures what that changed, properly, including the parts that are not flattering and the two things measuring it made us fix.
We built the version from before the rewrite, the rewrite itself and today's version, side by side on the same machine. Then we ran the same twelve jobs through each, the kind people actually do: re-encoding a phone photo, shrinking a camera file, turning a recording into an MP3, packing a folder. Five timed runs each, the middle one counts.
All twelve jobs, before and today
Here is every result on one axis, comparing the version from before the rewrite with the one running today. It is logarithmic, because the gains range from a few percent to fifty times, and anything slower would sit to the left of the line.
How many times faster each job is today
Convert 50 PNGs to JPEG in one go
Re-encode a 12 MP JPEG
ZIP four photos and videos
Resize a 24 MP photo
Take a still from a video
Convert a 12 MP photo to PNG
Pack 40 MB of logs as tar.xz
Convert a Word document to PDF
Convert 3 minutes of WAV to MP3
Convert a 12 MP photo to WebP
Convert a 12 MP photo to AVIF
Convert a 1080p MOV to MP4
How we measuredHide the method
Every version was built from source and measured on 3 October 2026: before is commit f1c2d0a6, after is d0e9ebcb, and today is the current version, which includes the two fixes this post describes. The old version needed a two line patch so it would fetch test files from this machine, and it was built against today's libraries because it predates our lock file.
Apple M2, 8 cores, 8 GB, a working desktop rather than an idle bench machine. Each job ran once to warm up and then 5 times per version, with the versions interleaved so background noise lands on all of them alike. The figure is the median, measured from sending the request to the last byte of the result. Production runs on a different machine, so read the ratios, not the seconds.
51x
faster converting fifty images in one go
41x
faster re-encoding a 12 megapixel photo
24.3x
smaller WebP files, at the same speed as before
Three groups stand out. Images got dramatically faster. Archives got faster where media was involved. And the jobs that hand straight over to a well known encoder, video, audio and documents, barely moved, because the encoder was never the problem. We will take them in that order.
Watch any of them run
A ratio is easy to read past. So here are the measured times played side by side. Pick a job and press start; "Real time" plays the medians exactly as they were measured.
Before and after, started at the same moment
4000 x 3000 JPEG, 2.3 MB, to JPEG at quality 85. 34x faster after the rewrite.
0 ms
Before the rewrite
After the rewrite
Why did one JPEG take seven seconds?
Re-encoding a 12 megapixel JPEG at quality 85 took 7.08 s before the rewrite and takes 173 ms today. The encoder is the same library at the same setting, and the two files differ by fewer than a hundred bytes. The difference is entirely in how the result was written to disk.
The old service handed the encoder a plain file. A JPEG encoder writes its output in very small pieces, and without a buffer in between, each of those pieces becomes its own request to the operating system. Millions of tiny writes, each one cheap, add up to seconds. The rewrite puts a buffer between the encoder and the file, so the same bytes reach the disk in a few hundred large writes.
Before
After
Fifty images is the same story fifty times. Converting fifty 1080p PNGs to JPEG took 36.8 s before and 716 ms after, because every one of them went through that same JPEG writer. That makes it the biggest win in the table, at 51 times.
The slowest part of the old converter was not converting. It was writing the answer down.
A still from a video, and a resize
Taking one frame from 45 seconds into a minute long video went from 1.79 s to 213 ms. The old service asked the video tool to decode from the start and throw frames away until it reached 45 seconds. The rewrite asks it to jump to 45 seconds first and decode from there. In the tool's own terms, the -ss option moved in front of the input. One argument, the same frame, 8.4 times faster, and the further into a long video you go, the bigger the gap gets.
Shrinking a 24 megapixel photo to 1920 pixels wide went from 1.71 s to 163 ms. The rewrite uses a resizing library that works on many pixels per instruction, plus the same buffered writer.
Why did zipping photos and videos get so much faster?
Packing two photos and two videos, 86.9 MB in all, into a zip took 1.87 s before and takes 107 ms today. The old service compressed everything it put in a zip. Photos and videos are already compressed, so that work bought almost nothing: the zip came out the same size. The rewrite recognises files that do not compress and stores them as they are. The archive is the same size and opens the same way. It is the same reasoning behind the light setting Nemi uses when you download a folder as one zip.
Packing 40 MB of log files as .tar.xz is 1.5 times faster, because the compressor now uses more than one core. On a file that small it can only split the work into two blocks, so two cores is all it gets; bigger archives can be split further. Every .tar.xz it writes carries a CRC64 checksum, multithreaded or not, so a damaged copy is caught when it is unpacked.
The one that got slower, and how we fixed it
Converting a 12 megapixel photo to WebP took 361 ms before the rewrite and 802 ms right after it: twice as slow. Part of that was deliberate. The old service ignored the quality slider and always wrote lossless WebP, which is quick to make and enormous. The rewrite did what the slider said, and lossy encoding is real work.
But slower was not good enough, so while writing this post we looked at where the time went. Almost all of it was in one setting. The WebP encoder has a dial for how hard it searches for the smallest file, from 0 to 6, and we were on its default of 4. We tried every step on the test photo and on four real camera photos of 8 to 21 megapixels. Step 2 encodes about twice as fast as step 4, and the files land between 4 percent smaller and 7 percent larger, with picture quality the same to within a rounding error. The steps above it spend their time on a search that buys a few percent of file size on a photo. Turning on more threads made no difference.
The same photo as WebP: before, after the rewrite, and today
Time
4000 x 3000 JPEG, 2.3 MB, to WebP at quality 80
File size
How we measuredHide the method
Every version was built from source and measured on 3 October 2026: before is commit f1c2d0a6, after is d0e9ebcb, and today is the current version, which includes the two fixes this post describes. The old version needed a two line patch so it would fetch test files from this machine, and it was built against today's libraries because it predates our lock file.
Apple M2, 8 cores, 8 GB, a working desktop rather than an idle bench machine. Each job ran once to warm up and then 5 times per version, with the versions interleaved so background noise lands on all of them alike. The figure is the median, measured from sending the request to the last byte of the result. Production runs on a different machine, so read the ratios, not the seconds.
So today a WebP takes 352 ms, against 361 ms before the rewrite, and the file is 810 KB instead of 19 MB. Same speed, a file you would actually put on a web page.
What did not change, and why that is fine
Converting a 1080p MOV to MP4 took 13.1 s before and takes 13.1 s today. Three minutes of WAV to MP3, and a 41 page Word document to PDF, moved by about ten percent. These jobs are almost entirely the encoder's own work, the encoder runs with the same settings in every version, and the files come out the same to within a few bytes. There was nothing for a rewrite to win here.
The video work in the rewrite went elsewhere: real progress while an encode runs instead of a bar that guesses, and a limit on how many heavy encodes run at once, so a queue of videos no longer starts one encoder per core with every encoder trying to use every core. If what you need is a smaller video rather than a faster one, our guide to making a video small enough to send has the settings.
AVIF is in the same group for a different reason. It is 1 times as fast, but the comparison is not like for like: the rewrite also changed the encoder's speed setting, so it is a slightly different file made faster, not the same file.
The full table
Every median for all three versions. Switch to the log scale to compare the small ones.
Every job, before, after the rewrite and today
Re-encode a 12 MP JPEG
4000 x 3000 JPEG, 2.3 MB, to JPEG at quality 85
41x faster
Resize a 24 MP photo
6000 x 4000 JPEG, 4.5 MB, to 1920 px wide JPEG at quality 85
11x faster
Convert a 12 MP photo to WebP
4000 x 3000 JPEG, 2.3 MB, to WebP at quality 80
1x faster
Convert a 12 MP photo to AVIF
4000 x 3000 JPEG, 2.3 MB, to AVIF at quality 70
1x faster
Convert a 12 MP photo to PNG
4000 x 3000 JPEG, 2.3 MB, to PNG
2.3x faster
Take a still from a video
60 s 1080p H.264 MP4, 61 MB, frame at 45 s to JPEG
8.4x faster
Convert a 1080p MOV to MP4
20 s 1080p30 H.264 MOV, 18.9 MB, to H.264 MP4 (crf 23, preset medium)
1x faster
Convert 3 minutes of WAV to MP3
3 min 44.1 kHz stereo WAV, 31.8 MB, to MP3 at 192 kbps
1.1x faster
Convert a Word document to PDF
28 KB DOCX (41 pages once rendered) to PDF via pandoc and WeasyPrint
1.2x faster
Convert 50 PNGs to JPEG in one go
50 PNGs at 1920 x 1080, 172 MB, to JPEG at quality 85, returned as a ZIP
51x faster
Pack 40 MB of logs as tar.xz
40 text files, 40 MB, to tar.xz at level 6
1.5x faster
ZIP four photos and videos
2 JPEGs and 2 videos, 86.9 MB, to ZIP
18x faster
How we measuredHide the method
Every version was built from source and measured on 3 October 2026: before is commit f1c2d0a6, after is d0e9ebcb, and today is the current version, which includes the two fixes this post describes. The old version needed a two line patch so it would fetch test files from this machine, and it was built against today's libraries because it predates our lock file.
Apple M2, 8 cores, 8 GB, a working desktop rather than an idle bench machine. Each job ran once to warm up and then 5 times per version, with the versions interleaved so background noise lands on all of them alike. The figure is the median, measured from sending the request to the last byte of the result. Production runs on a different machine, so read the ratios, not the seconds.
How should you read these numbers?
Every job ran five times per version, with the versions interleaved, and every output was checked before a timing counted. Three things are worth keeping in mind.
- Read the ratios, not the seconds. This is an ordinary 8 GB M2 with other work running, and production is a different machine.
- Every run is kept. The harness, the test files and each individual timing are saved, so we can repeat the measurement whenever the service changes.
- Conversion runs on hardware we operate. Your files are not sent to an outside conversion company, as the security page sets out.
If you want to see what the converter can do now, the format explorer lists every pair it supports, and Convert is where you use it. The help page on converting files walks through the panel step by step.
Questions people ask
Is WebP better than JPEG?
For photos on a web page, usually yes: a lossy WebP is typically smaller than a JPEG that looks the same, and every current browser shows it. JPEG still opens in more older software, so it is the safer choice for email attachments and print. In our benchmark a 12 megapixel photo became a 0.8 MB WebP at quality 80; the two formats' quality scales do not mean the same thing, so compare them by eye, not by the number.
Why is my WebP file bigger than the JPEG?
Often it is lossless WebP, which keeps every pixel exactly and barely shrinks a camera photo. Before our rewrite, Nemi's converter wrote lossless WebP whatever quality you picked, and a 12 megapixel photo came out at about 20 MB. Today it follows the quality setting, and the same photo is about 0.8 MB.
How fast is Nemi's file converter?
It depends on the job. In our benchmark of twelve ordinary jobs, converting fifty images in one go is 51 times faster today than before the rewrite, and re-encoding a 12 megapixel JPEG about 41 times faster. Video, audio and document conversions, which are almost entirely the encoder's own work, stayed about the same.
Why does zipping photos and videos not make them smaller?
Photos, videos and most audio are already compressed, so compressing them again finds almost nothing to remove. Nemi's converter recognises those files and stores them in the archive as they are, which made zipping 87 MB of photos and videos about 17 times faster, with an archive of the same size.
How do I take a still from a video quickly?
Ask the video tool to jump to the moment first and decode from there, instead of decoding from the start and throwing frames away. In ffmpeg that means putting the -ss option in front of the input. That one change made taking a frame 45 seconds into a video about 8 times faster in Nemi's converter.
Are my files sent to another company when I convert them in Nemi?
No. Conversion runs on hardware we operate, not at an outside conversion company, as our security page sets out. You choose whether the result is downloaded to your device or saved in your workspace next to the original.
Where the numbers come from
- The measurements (12 jobs, 3 versions, 5 runs each):
lib/blog/data/conversion-bench.json - The harness, fixtures and the patch the old version needed:
scripts/blog-bench/README.md - Every individual run, with the tool command lines:
scripts/blog-bench/results-2026-10-03.json - Before the rewrite:
commit f1c2d0a6 - The rewrite:
commit d0e9ebcb - Today:
commit fc6cfd7d