Two routes through the same machine
The full engine, called Quality, spends its time searching. It weighs every possible colour against the evidence before accepting it, merges bands of a colour fade two at a time and re-checks after each merge, moves every edge of the picture at once until a re-drawing matches the pixels, and tries many ways of drawing each outline before picking the cheapest.
Fast mode answers the same questions in one pass each. It shares the middle of the pipeline with Quality unchanged — the map in which every border is stored once, the step that moves each border point onto the true edge, the symmetry check, and the writer that produces the file — and replaces the rest.
Colours from the flat middles of shapes
The first job is deciding which colours — "inks" — the picture is made of. Fast mode sorts every pixel into one of a few tens of thousands of small colour boxes and counts them. But a box earns an ink only through its flat pixels: pixels whose four neighbours, left, right, above and below, fall in the same box.
The boxes are then taken busiest first. A box joins an existing ink when its colour is almost the same, or close and right next to one of that ink's boxes — one ink spread over neighbouring boxes by noise. Otherwise it starts an ink of its own. Lines too thin to have any flat pixel, such as small text, get a second chance from pixels that have at least one matching neighbour, unless their colour is simply a blend of two other inks. Finally every pixel gets its ink: most straight from a table built once per box, and only the in-between pixels by looking at their neighbours.
Counting in stretches, not pixel by pixel
Logos are mostly large areas of one colour. Read along any row and the colour stays the same for long stretches — "runs" — before it changes. On the large test images a pixel continues its left neighbour's colour almost every time, so most of the latest round's speed comes from one idea used over and over: do the work once per run, not once per pixel.
Why splitting the counting over many cores changes nothing
A big image is cut into horizontal bands, and each processor core counts its own band. At the end the band totals are added together. That sounds harmless, but for a computer it usually is not: adding the same numbers in a different order can give a result that differs in the last digit, because each addition rounds. A tracer that wants the same output on every machine has to care about that last digit.
Here it provably does not matter. Every colour in an ordinary 8-bit image is a whole number of very small, equal steps, and the running totals the palette keeps are wide enough to hold every sum of up to about four million of them — a 2048 × 2048 image — without rounding anything. A sum that never rounds is the exact answer, whatever order the numbers arrive in. The code checks this condition on every value it reads; an image that has been resized in between (whose colours are averages, not whole steps) fails the check and is counted the slow way, one row after another, so the answer is still the same. The technical page gives the short proof.
Tidying the regions
Once every pixel has an ink, pixels of one ink that touch form a region. Before the border map is built, five quick passes tidy them:
- Slivers — thin strips along an edge that are only a blend of the two regions either side go back to whichever of the two they mostly are.
- Rims — the grey outline around small text, itself a strip between two inks, is split between the letter and the paper.
- Near-identical inks — a patch whose ink the eye cannot tell from its larger neighbour's joins it.
- Speckles — regions below a size that grows with the picture are given to the neighbour they share the longest border with, so no hole is left.
- Faces — what remains is numbered, one number per connected region. Fast mode keeps those numbers in 16 bits, which leaves room for 65,534 regions. A picture with more than that first has its smallest regions merged, each into the neighbour it shares the most border with, until the rest fit, so every region is still one connected patch of one ink. It used to lump every region past the limit into the first one, whatever its colour. No real picture tried so far reaches the limit in Fast mode; a fine checkerboard does, and is the test.
All five now work on the runs. The pixel labels are read once, when the runs are made, and written once, at the end. In between, everything the passes need — a region's size, whether it has an inside at all, the length of its border with each neighbour — is read off the runs. On a 2048-pixel image the whole tidy-up went from 76.2 milliseconds to 3.86.
Putting smooth fades back together
A smooth colour fade has no flat colour, so the ink-finding step turns it into bands, and each band would get a border of its own. Neighbouring regions whose inks are only a small step apart are grouped, each group gets one gradient fitted to it, and the gradient is kept when it explains the pixels about as well as the bands did.
The latest round added a shortcut that is a proof, not a guess: two regions that touch always have different inks, so if no two different inks in the whole picture are close enough to be steps of one fade, nothing could ever be grouped — and the pass stops before looking at a single pixel. That settled 5 of the 7 large test images outright. On a picture with so many regions that the smallest had to be merged (above), the shortcut stands aside and the full pass decides.
The shared middle
From here Fast mode runs the same code as Quality: the border map, the step that moves each border point onto the true edge, and the symmetry check. All three got faster for both modes: the map's borders are read off runs, and the edge placement, which looks at each point on its own, now measures many points at once on different cores while the symmetry check runs beside it. Only the whole-picture adjustment that Quality runs next is left out.
Drawing the curves the Potrace way
For the curves, Fast mode follows the classic method of Potrace, a well-known tracer from 2003, restated for points that already sit at their true positions between the pixels rather than on the pixel corners Potrace starts from. Each shared border is fitted once, so the two regions either side draw exactly the same curve.
Two rules keep that last merge safe. A piece of curve that turns sharply back on itself — a U-turn — is always kept as its own curve, never merged with its neighbours. And a closed outline is never collapsed into a single curve: it always comes back as two curves or more. Before a fix in October 2026, one U-turn piece could make the merge lose track of the whole stretch, which then came back as its last piece alone; on a closed outline that left one curve closed on itself, and the shape was not drawn. In everyday Fast mode the fix changed 9 of the 402 icons of the quality check at its smaller size and 3 at its larger one, and the Visa logo of the Simple Icons set, traced at 512 pixels, came out closer to the original.
Whether a corner stays sharp is decided by distance: if the rounded curve would miss the border points by more than a tenth of a pixel, and by more than twice what the two straight sides miss them by, the corner is kept. Until October 2026 the limit was a quarter of a pixel. Lowering it made Fast both closer and smaller at once: a sharp corner takes four numbers where the curve that rounded it took six, and on drawn icons the sharp corner is usually what the artist drew. On the quality check's small icons the colour error fell by 1.5 % and the number count by 4.3 %; on the larger ones the count fell by 1.6 % with the error unchanged.
Before those steps, a closed outline that is really a circle or an ellipse is recognised as one and written with three or five numbers instead of a chain of curves; and a border between two nearly identical colours is fitted more loosely, because a small misplacement there is invisible. Borders are fitted on all cores at once, each on its own.
The picture's outer border is not fitted at all. When one region runs all the way round the edge of the picture — a background colour, or the clear ground of a transparent icon — its outline is exactly the picture's rectangle, so Fast mode now writes it as four straight lines. Fitting it used to be the slowest single job on most pictures, and it left a small cut across one corner: a wasted curve on two icons in three.
The search for the fewest straight sides, where most of this step's time went, got three shortcuts that give exactly the same outline. It stops working out the cost of sides that already need more pieces than the best way found so far; it jumps over straight runs of the pixel grid, where the outcome is known in advance; and on very long borders it works out which sides are allowed on all cores at once, then chooses among them in the usual order. The circle and ellipse check stopped computing a score that nothing read, and now starts its search for an ellipse from one good guess instead of five. Together, the curve step became two to five times faster, the most on the largest pictures.
The outer frame is the one change here that alters the drawing on purpose, and only on pictures with a coloured background: a transparent icon's clear ground is not drawn, so there it only saves time. The single starting guess for ellipses changed no file in the test sets, but unlike the other shortcuts it is not proven to give the same answer, so the quality check judged it instead.
Faster, with the drawing held fixed
Every change the speed-up round made to the steps described above was made with the output held fixed (the outer-frame change in the curve step, described just above, is the one deliberate exception, and the ellipse starting guess was judged rather than proven; the later U-turn fix was a correction, not a speed-up, and the quality check judged it too). Each rewritten step keeps the code it replaced as a reference, the tests compare the two on random and awkward inputs, and the finished SVG files were compared byte for byte across hundreds of test images in both modes. Measured per image on a busy development machine, so the milliseconds are approximate:
| Step | Image size | Before | After |
|---|---|---|---|
| Finding the inks | 2048 px | 47.7 ms | 7.1 ms |
| Finding the inks | 128 px | 1.85 ms | 0.40 ms |
| Tidying the regions | 2048 px | 76.2 ms | 3.86 ms |
| Tidying the regions | 128 px | 0.50 ms | 0.09 ms |
| Fades, border map, edge placement | 2048 px | 42 ms | 13 ms |
| The same, plus transparency, on a transparent image | 2048 px | 130 ms | 21 ms |
| The same | 128 px | 1.8 ms | 1.2 ms |
| Drawing the curves | 2048 px | 26.3 ms | 5.4 ms |
| Drawing the curves | 128 px | 1.00 ms | 0.46 ms |
The curve rows come from one run of all the changes together; the others measure each step's own work against its own earlier run. Measured the same way, the whole trace before the curves went from 161.5 ms to 31.0 ms on a 2048 px picture, and from 4.3 ms to 2.5 ms on a 128 px icon.
The shared middle is shared: Quality mode gained the border map and edge placement speed-ups too.
Writing the file
The last step is Quality's own writer, with one difference: Fast mode does not make repeated, near-identical shapes exactly identical. For a transparent picture, the check for shapes that fade from solid to see-through now skips every shape where a fade is mathematically impossible — too small, or completely solid inside — instead of testing every shape against the whole picture. The writer's page has the details.
A third route: Balanced
Between Fast and Quality there is a large gap in time and a large gap in closeness, and the two are not spread evenly over Quality's stages. On small icons, almost all of Fast's error sits within one pixel of an edge: it is about where the borders are, not about colour. Two of Quality's stages fix that. One fits every outline by trying many ways of drawing it, and costs twenty to thirty times Fast's whole trace. The other moves every border point at once until a redrawing matches the pixels, and it is cheap at the start: most of what it buys comes in its first few rounds.
Balanced is Fast with the first eight rounds of that edge placement added, and a curve fit that follows the points a quarter more closely. It keeps Fast's flat fills and leaves the expensive outline search to Quality. On the quality check's small icons it closes about three fifths of the distance from Fast to Quality, and at 512 pixels two fifths to a half; on a set of 21 logos and emoji at 512 and 1024 pixels its median error is close to Quality's. It costs two to three times Fast's work, a tenth of Quality's or less.
Why eight rounds. When Balanced was first built, on the edge placement of version 0.2.5, four rounds were the sweet spot. The edge placement was then rewritten to take better-judged steps, and the count was measured again: the colour error still levels off after four, but on the new version more rounds also leave a smoother edge for the curve fit, so the drawing uses fewer numbers and turns less. Eight rounds bring the number count back to Fast's for about a seventh more time than four.
It has a price besides time: its outlines turn more along their length than Fast's, because the finer fit follows more of the small wobble in the measured edge. Fitting with Fast's own looseness after the same eight rounds avoids that, with fewer numbers than Fast, and still gains about two thirds as much; the measurements are on the technical page.
On pictures larger than 1024 pixels on their longer side, Balanced simply runs Fast. At 2048 pixels the extra steps still helped a little — about 5 % on typical logos — but they cost a third more numbers and nearly three times the work, and the rest of what separates Fast from Quality there is the way gradients are filled, which no edge placement can fix.