Where the minutes come from
Every figure below can be recomputed from four constants and one measurement. The constants are on this page; the measurement happens on your own processor, in your own browser, immediately before a queue starts.
The two graphs, as they actually are
A tile is one pass, and a pass is not a photograph. That distinction is the whole of this page: a 500-pixel product shot is nine passes and a twelve-megapixel photograph is nearly a thousand, on the same network, at the same milliseconds each.
| ESPCN | Real-ESRGAN general x4v3 | |
|---|---|---|
| File size | 240,078 bytes | 4,866,396 bytes |
| Input shape | [batch, 1, 224, 224] — fixed | [b, 3, h, w] — dynamic |
| Magnification | 3× | 4× |
| Tile edge | 224 px | 128 px |
| Context margin a side | 8 px | 8 px |
| Stride | 208 px | 112 px |
| Milliseconds a pass | 230 ms | 1,200 ms |
| Licence | Apache-2.0 | BSD-3-Clause |
What was assumed, and what the files said
The specification this site was built from flagged its tile geometry as the largest technical assumption in it, and asked for the graphs to be checked before a minute count was quoted anywhere. They were, and three things came back.
ESPCN’s 224-pixel tile is not a choice. Two constant nodes downstream of its convolutions hold [-1, 1, 3, 3, 224, 224] and [-1, 1, 672, 672], so the graph throws at any other input size and tiling is the only way to run it on a photograph at all. The assumption was correct and is now a measurement.
ESPCN magnifies by three, not by two or four. 224 in, 672 out. The factor control on the queue is therefore not a parameter of the network: the graph runs at its own magnification and the requested factor is reached by resampling the result. A run at 2× is a 3× model pass and a reduction; a run at 4× is a 3× pass and an enlargement. The pass count — and therefore the estimate — is identical in both cases.
Real-ESRGAN’s 128-pixel tile is an assumption, and stays one. Its input shape leaves height and width free, so nothing in the file constrains the tile size. 128 is chosen here to bound peak memory — one tile in, one tile sixteen times its area out, and nothing in between the size of the finished photograph. Every Real-ESRGAN figure on this site is a consequence of that decision rather than of the graph.
Running a folder: the arithmetic in public
Cores tile a source exactly, so the pass count for one photograph is ceil(width ÷ stride) × ceil(height ÷ stride). Nothing else enters it.
ESPCN, at a 208-pixel stride
A 1,200-pixel product shot is ceil(1200 ÷ 208) = 6 tiles each way — 36 passes, about 8.3 seconds a file, and two hundred of them in roughly 28 minutes. That is a real job, and it is the one this site is built around.
Real-ESRGAN, at a 112-pixel stride
A 4,000 × 3,000 photograph is ceil(4000 ÷ 112) = 36 across by ceil(3000 ÷ 112) = 27 down: 972 passes, at 1,200 milliseconds each, which is 1,166 seconds — nineteen and a half minutes for one file. Two hundred of them is about 65 hours. That is not a job a browser tab can hold, and a site that starts it anyway is lying to the person who pressed the button.
| Source | Engine | Passes a file | 200 files | 500 files |
|---|---|---|---|---|
| 500 × 500 | ESPCN | 9 | 6.9 min | 17 min |
| 1,200 × 1,200 | ESPCN | 36 | 28 min | 1 h 9 min |
| 2,400 × 2,400 | ESPCN | 144 | 1 h 50 min | 4 h 36 min |
| 600 × 600 | Real-ESRGAN | 36 | 2 h 24 min | 6 h |
| 4,000 × 3,000 | Real-ESRGAN | 972 | 65 h | 162 h |
What it opens, what it refuses
The table above is published arithmetic and it is not your arithmetic. Before a queue starts, the tool takes three files spread across the set, cuts eight real tiles from them, runs the chosen network over those tiles and takes the median wall-clock time — on that processor, in that browser, with whatever else the machine is doing. The first pass is dropped, because a freshly compiled graph pays a one-off cost that no later tile pays.
The total pass count comes from each source’s dimensions, read from header bytes rather than by decoding five hundred photographs to find out how big they are. The result is a range from 0.85 to 1.45 of the measured median, carrying the file count and the pass total so both can be judged at once.
- The range is a starting guess. It needs real runs on a low-end laptop, and if it proves optimistic the range widens rather than the copy softening.
- A backgrounded tab is throttled by the browser and a warm laptop is throttled by its own firmware. Neither is visible to a measurement taken two seconds before the run.
- The published per-pass figures are single-threaded WebAssembly in Chromium. A different engine will differ, which is exactly why the tool measures rather than quoting.
Asked mid-run
- How long does it take to upscale 200 photos?
- With ESPCN on 1,200-pixel sources, about 28 minutes at the published figure of 230 milliseconds a pass — 36 passes a file, 7,200 passes for the set. With Real-ESRGAN on the same folder it is closer to nine hours, because that network retiles at 128 pixels and costs 1,200 milliseconds a pass. Those are the published numbers; the tool measures your own machine and replaces them before it starts.
- Why is the estimate a range rather than a number?
- Because an eight-tile sample taken in two seconds cannot know about thermal throttling forty minutes later, or about the tab being backgrounded, or about what else the laptop decides to do. The range runs from 0.85 to 1.45 of the measured median. If real runs on low-end hardware prove it optimistic the range widens; the sentence around it does not soften.
- Why does asking for 4× not take twice as long as 2×?
- Because the tiling is over your source, not over the result. Both networks magnify by a fixed amount — three for ESPCN, four for Real-ESRGAN — so a given photograph costs the same number of passes whatever factor you asked for. The requested factor is reached by resampling the network's output afterwards, which costs a fraction of a second.
- Can I make it faster?
- Not meaningfully, on this path. There is no GPU here and no second thread: multi-threaded WebAssembly needs cross-origin isolation, which breaks the advertising this network is funded by, so the single-threaded figure is the figure everyone sees. The two things that genuinely change the number are smaller sources and the smaller network.
- What is actually downloaded before the first pass?
- The WebAssembly runtime at 13,961,845 bytes, its loader at 24,218 bytes, and the graph you chose — 240,078 bytes for ESPCN or 4,866,396 bytes for Real-ESRGAN. Nothing moves until the control naming those numbers is pressed, and all of it is kept in this site's own cache bucket afterwards.
What this site is holding on your disk
The runtime is 13,961,845 bytes and its loader is 24,218 bytes, both served from this domain. The weights come from the network’s own object store. All of it lands in a cache bucket named for this site and this release, so a new release is a new bucket rather than an invalidated path.
Reading this site's cache bucket…
Reference: the numbers
- Runs, warns, refusedThree bands, two thresholds, the halved iOS envelope and the arithmetic floor beneath all of it.
- The 972-tile calculationOne twelve-megapixel photograph, counted tile by tile, and what a GPU changes about it.
- Small sources, better resultsWhy a 500 px source beats a 4,000 px one on both quality and wall-clock time.
- Run a folderEnumerate a directory, measure one model on this CPU, then work the set through one file at a time.