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.
In Fast mode a pass moves at most 24 clusters, the ceiling the real utility used, and the 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 spindle speed relative to a 3600 RPM baseline, the speed of the slowest drive in the set.
delay = (200ms + 60ms * clusters moved) / (rpm / 3600)
Because the cluster count varies, 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 spindle speed:
| Drive | Capacity | Clusters | rpm | Fast pass | Fast run | Realistic run |
|---|---|---|---|---|---|---|
| C: | 2048 MB | 16384 | 4500 | 208 to 1312ms | ~13m 16s | ~61m 24s |
| D: | 1024 MB | 8192 | 7200 | 130 to 820ms | ~4m 09s | ~19m 11s |
| E: | 512 MB | 4096 | 3600 | 260 to 1640ms | ~4m 09s | ~19m 11s |
| F: | 2048 MB | 16384 | 15000 | 62 to 394ms | ~3m 59s | ~18m 25s |
RPM alone does not decide the table: capacity does too. E spins at the slowest rate in the set, 3600 RPM, the standard speed of an early Winchester hard drive. It also holds the fewest clusters, and the two cancel out exactly: it finishes in identical time to D, a bigger drive on a faster, 7200 RPM spindle. C pairs the slowest common spindle speed with a full-size drive, so it takes the longest of the four. F pairs that same capacity with the fastest spindle in the set, a 15000 RPM drive of the kind late-90s SCSI enthusiasts ran. It is the one to pick to watch a drive finish quickly. Realistic mode multiplies every drive by the same factor, so that ordering holds there too.
Drive G is the one you set up yourself. Open Settings, choose Custom drive and give it a size from 8 to 8192 MB and a speed from 3600 to 15000 RPM. It uses the same cluster scale and timing model as the four above, so the pass and estimate columns apply to it too. The values you choose stay in your browser between visits.
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) / (rpm / 3600)
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. The average pass is 12.5 clusters in Fast mode and 3.5 in Realistic, which is most of the gap between the last two columns of the table.
Two simulation modes
Settings has a Simulation mode box. Fast is the default and is what everything above describes. Realistic gives up the eight minute run for something closer to what the original put you through.
Realistic mode moves at most 6 clusters a pass rather than 24, so the write head crawls instead of jumping, and it multiplies every delay by three. Drive C goes from roughly eight minutes to thirty eight.
Then it does the part everybody remembers. Once or twice during the run, somewhere between 35 and 65 percent, the progress line reads Drive's contents have changed: Restarting..., the whole drive is read again from the top, and fresh fragmentation shows up behind the scan line. The run still finishes with the tada chime and the completion box. Closing the box leaves the drive at 100 percent. Press Start to generate a fresh disk and run it again.
None of that is invented. Windows 95 and 98 both restarted a defrag whenever anything wrote to the drive mid-run, and an antivirus scanner, a network poll or a screen saver waking up was enough to trigger it. Microsoft documented the message in KB 186978. The behavior was dropped in Windows Me.
A Realistic run can take a while. Nothing is saved between page loads, so a phone that discards the tab in the background comes back to a fresh drive.
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.
The restarts in Realistic mode take something back that the original gave you. Windows 98 paused, reread the drive and resumed where it had stopped, so you lost time rather than ground. Here a restart also refragments part of the disk. Without that the interruption would barely register in a simulation with no programs writing real files.
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 - Support this project