README.TXT - Notepad

How Defrag98 Works

Defrag98 is a recreation of the Microsoft Windows 98 Disk Defragmenter that runs in a browser. This document covers what the simulation does and the numbers it does it with. None of the cluster movement is a recorded animation: every pass works out what to do from the state of the drive in front of it.

The cluster grid

A drive is one flat array of clusters. Each one is in exactly one of four resting states, drawn in the palette sampled from the original legend:

  • Free space, white
  • Unoptimized data, light blue
  • Optimized data, dark blue
  • Data that will not be moved, white with a corner mark

Reading and writing are not resting states. They are per-pass highlights, green and red, recomputed on every pass and discarded afterwards, so no cluster stays green once the pass that read it is over.

In the diagrams below, # is optimized, ~ is unoptimized, . is free.

Building a fragmented drive

A fresh drive is generated on every start, stop and drive change. Two percent of clusters are scattered at random unique positions and marked unmovable. Sixty percent are then filled with data in contiguous runs of 12 to 48 clusters, dropped at random starting points that wrap around the end of the array and fill only the cells still free. The remaining thirty eight percent stay free.

Placement is capped at four attempts per cluster, so generation always terminates even when the last few runs cannot find room.

The frontier

Every pass begins by locating the frontier: the lowest index that is neither optimized nor unmovable. That is the boundary of the consolidated region at the front of the drive, and it is the only place data is ever written to.

A free hole on its own stops counting as a frontier once no unoptimized data is left anywhere ahead of it. Without that rule the defragmenter would chase gaps forever and never finish. The same pass that locates the frontier also tracks whether any unoptimized data remains, and reports completion when none does.

The three moves

With the frontier located, a pass commits to exactly one of three moves. Which one depends on what is sitting at the frontier and on one coin flip.

1. Optimize in place

The frontier holds data, and that data already belongs where it is. The pass walks forward through the contiguous run and marks it optimized, reading and writing the same cells.

before  ########~~~~~~~~....~~~~....~~~~~~~~
                ^ frontier
after   ################....~~~~....~~~~~~~~

2. Relocate forward

The frontier is free space, so data has to be brought to it. The pass picks one unoptimized run at random from further down the drive and drains it from its tail: the read head walks backward through the run while the write head walks forward into the free frontier. Relocated clusters land already optimized.

before  ########....~~~~....~~~~~~~~~~~~
                ^ frontier             ^ source
after   ############~~~~....~~~~~~~~....

Picking a run at random rather than scanning the drive back to front is deliberate. Windows 98 relocated whole files from wherever they happened to live, so the green read head jumped around the map. Draining one run from its tail reproduces that while keeping a single file's clusters moving together.

3. Evict out of the way

One pass in four, when the frontier holds data, the run is shoved somewhere else instead of being optimized. It reappears in a random free run further down the drive, still unoptimized, clearing the frontier so incoming data has room. This is what the real utility did before writing into a region.

before  ########~~~~~~~~....~~~~....~~~~~~~~
                ^ frontier      ^ destination
after   ########....~~~~....~~~~~~~~~~~~~~~~

Eviction is a probability, not a rule, which is what guarantees the defrag terminates: optimizing in place always stays reachable. If no free run exists ahead of the frontier the eviction is abandoned and the pass optimizes in place instead.

Evicted clusters flash green as they are read but nothing flashes red. The red write highlight is reserved for the consolidation zone, so red always means progress.

One move per pass, on purpose

A pass never mixes modes, and it never re-picks its source run halfway through. Both rules exist for the same reason: the green and red highlights have to read as solid contiguous blocks. Interleaving two modes would scatter them into confetti, which looks like a screensaver rather than a disk utility.

A pass moves at most 24 clusters, the ceiling the real utility used, and the actual count is rolled fresh each time somewhere between 1 and 24. It is clamped at the bottom because a random number generator can return exactly zero, and a pass that moves nothing would stall the whole run.

How long each pass takes

Nothing runs on a fixed timer. After each pass the next one is scheduled using the cost of the work just shown: one head seek, plus transfer time for every cluster moved, divided by the drive's I/O rate.

delay = (200ms + 60ms * clusters moved) / iops

Because the cluster count varies from 1 to 24, so does the delay. The drive works in fits and starts, the way a mechanical one does, instead of ticking to a beat.

Each of the four drives gets its own capacity and I/O rate:

Drive Capacity Clusters iops Pass Full run
C: 2048 MB 16384 2 130 to 820ms ~8m 18s
D: 1024 MB 8192 3 87 to 547ms ~2m 46s
E: 512 MB 4096 1 260 to 1640ms ~4m 09s
F: 2048 MB 16384 8 33 to 205ms ~2m 04s

The table is easy to read backwards. E has the slowest disk in the set and its individual passes are the most laborious, up to a second and a half each, but it holds a quarter of C's clusters and gets through them in half C's time. C takes the longest of the four, and F is the one to pick to watch a drive finish quickly.

The estimate

The time remaining is built from the same cost model rather than measured. Every data cluster has to move once, and evictions mean a quarter of that work gets done twice, so the total is inflated to cover the re-moves and divided by the average pass.

moves = (clusters * 0.6) / (1 - 0.25)
passes = moves / 12.5
seconds = passes * (200ms + 60ms * 12.5) / iops

It is an estimate in the 1998 sense. It assumes an average pass throughout and knows nothing about how this particular drive happened to be generated, so it is approximately as truthful as the original was.

Drawing 16384 clusters

The grid is painted to a canvas, never to DOM nodes. Layout is width driven with a fixed cell size, cells slightly taller than they are wide as Windows 98 drew them, so a wider window means more columns rather than bigger clusters.

The canvas itself is only as tall as the visible area. It sits pinned inside a spacer element that carries the full height of the grid, so the spacer owns the scrolling while the canvas backing store stays small. That matters because a 2 GB drive at these proportions is far taller than the roughly 4096 pixels per side Safari on iOS and iPadOS will paint, and a full height canvas renders blank past that point.

Each pass repaints only the cells that changed and fall inside the visible window. Scrolling repaints the window once. The view also follows the frontier on its own, snapping to the next region as the visible one finishes, exactly like the details pane in the original. Scroll away yourself and it stops following until the frontier is comfortably back in view.

Where it departs from the real thing

One number is openly artistic: a cluster stands for an eighth of a megabyte, which makes a 2 GB drive 16384 clusters. Real 512 byte clusters would put roughly 2048 of them in a megabyte and turn the grid into an unreadable haze, so the coarser scale keeps it dense and scrollable instead. The pass ceiling and the run lengths scale by the same factor, so the pacing and the proportions of the sweep are unchanged.

There is also no filesystem underneath: no FAT, no directory entries, and no files. Runs of clusters stand in for files, which is enough to make the movement look right and not remotely enough to defragment anything.

What it never does

Defrag98 has no access to your storage. It cannot read, move or modify a single real file, and it never asks for permission to try. Every drive it shows you, every letter, every capacity and every cluster in the grid is invented in the page and thrown away when you close the tab. Nothing is uploaded and nothing is scanned.

Your own disk, incidentally, almost certainly does not need defragmenting. Modern filesystems handle it themselves, and solid state drives have no seek time worth saving, which is why watching a defrag is nostalgic rather than useful.

Defrag98 is a nostalgia project by Dennis Morello, built in TypeScript and React. Changes are recorded in the release notes.

Back to Defrag98 - Changelog - Privacy policy