Case study Travel publishing
Motohorek, a fourteen-year blog frozen without losing a page
Fourteen years of a site moved with all 79,200 of its addresses listed and hashed before a single page changed.
473 posts, 79,200 addresses enumerated and hashed, two independent captures, and a static mirror that keeps the navigation the API never exposed.
The numbers
The blog stands still, every address it had still answers, and the gap between the two captures is a number, not a hope.
- 473 posts, 19 pages before the move counted from the site itself, not from a sitemap
- 79,200 addresses hashed the inventory, before any write enumerated, probed, deduped and frozen before anything moved
- 9,263 media items the archive's own index at a mean of 7.2 registered sizes each, about 2.0 to 2.2 GB of originals
- 108 rows in the gap after packing the difference between the two captures, named and measured rather than claimed as parity
The decision
The fork in the road was a beta CMS carrying production against a template rewrite across five hundred addresses. The owner closed it in one sentence: the site is kept and frozen, and nobody edits WordPress again.
A site nobody edits is exactly what a frozen mirror is for. No CMS, no beta, no template parity work.
The constraint
Nothing was lost has to be a comparison, not an assurance. So every address was enumerated, probed and hashed before the first DNS record moved.
The navigation answers 401 from the REST API and lives only in the rendered HTML, so a mirror is the only capture that has it.
Two captures, never one
The structured capture reads the site's own REST API into JSON. The byte-level capture crawls the rendered site into a browsable mirror plus a WARC.
Parity audits then run against the live site, page by page, and media is imported with its registered sizes rather than its display size.
What shipped
A mirror that serves the posts, the pages, the 55 categories, the 812 comments and the navigation, with the inventory and the audits beside it.
The links page at links.motohorek.life was already static, eleven languages and 33 links, and was left untouched.
What the numbers say
The inventory is the difference between a claim and a check: 79,200 addresses, each one probed and hashed, so a missing page is a row rather than a rumour.
The 108-row gap is published, not hidden. On a migration of this size a zero would have been the suspicious number.
What was decided, and what was not
-
Patch the old site, or enumerate and rebuild?
ChoseEnumerate first, then rebuild
NotCopy the files as they lay
Nobody could say what was there. Listing and hashing 79,200 addresses is the only way to know that a page which disappears was never there, rather than lost in the move.
-
Hide the gap, or name it?
ChoseName the 108 rows that did not resolve
NotPublish a clean total
A total that hides its exceptions is a claim, not a count. The gap is in the receipts, so the next person starts where this one stopped.
-
Shrink the media, or keep the originals?
ChoseKeep the originals and pack them
NotRe-encode everything smaller
Re-encoding is lossy and irreversible. The archive went from 2.0 to 2.2 GB packed, which is cheap next to losing a photograph.
How this was measured
- Every URL was listed and hashed before the move, so the count is an inventory rather than an estimate.
- Media was counted from the archive's own index, not from a crawler.
- The 108 rows that could not be resolved are named in the receipts rather than dropped from the total.
1 kept and a frozen. We won't edit the Wordpress site going forward.
Receipts
- motohorek.lifethe frozen mirror, live
- links.motohorek.life11 languages and 33 links, untouched by the migration
- the inventoryevery address hashed into a frozen list before anything moved
What this page does not claim
- The mirror serves what the crawl captured; anything the old site generated per visitor is gone by nature.
- The 108-row gap names addresses the structured capture did not have. They are recorded, not silently dropped.
- Media sizes were sampled rather than measured end to end: the mean is honest, the total is an estimate.
When it happened
- the plan frozen and the site captured before anything moves
- 79,200 addresses probed; the 108-row gap named but not claimed
- the decision recorded: keep the links page, freeze the blog