Aug 1, 2026

Fourteen years, and every image came home

In 2012 I posted a photo to Instagram. The link still works. The photo doesn't.

If you kept a blog anywhere between 2010 and now, you know the drill. The platform got acquired, or pivoted, or "sunset some legacy infrastructure", and the images you embedded from their CDN quietly turned into grey rectangles. My personal archive goes back fourteen years across Tumblr, Twitter, Mastodon and a couple of other places — and a depressing number of its images now live at addresses that answer with nothing at all.

Here's what I mean, from my own archive. On February 22, 2012, I published a blog post called #53: Messengers of Spring? and embedded its photo straight from Instagram's CDN, the way everyone did back then. This is that link today:

Browser error page saying the server IP address of distilleryimage1.instagram.com could not be found
distilleryimage1.instagram.com, fourteen years later

Notice it's not even a polite 404. distilleryimage1.instagram.com doesn't resolve at all — the photo is gone along with the entire piece of infrastructure that used to serve it. The post itself is still alive, imported into this engine, minus the one photo nobody can download anymore.

Here's the uncomfortable part: the post was mine. The photo was mine. The URL never was.

What the importer does about it

./blog.sh ships importers for eight sources, and they all follow one stubborn rule: media comes home. Every image, video and audio file gets downloaded next to its post, into media.nosync/<year>/<slug>/, and the post references the local copy from then on. No hotlinks, no third-party CDN, no "this content is no longer available".

A few details I'm fond of:

  • Downloads are measured on arrival. The build refuses to render an image without known dimensions — so the importer simply never writes one.
  • Failed downloads get retried. And when a file genuinely can't be fetched anymore, because the source deleted it years ago, you lose that one image — not the post.
  • The origin becomes a tag. Import an old Tumblr blog and every post lands tagged tumblr. Your old blog turns into a browsable archive instead of a zip file in a drawer.

The numbers

From a real migration of a real fourteen-year archive:

SourceItems in the archiveNotes
Mastodon6,5912,984 replies and 1,059 boosts skipped on purpose
Pixelfed333two accounts, 571 media attachments
Tumblr1,099four separate blogs, importing 1,247 media files that came home with them
Twitter5,3882008–2022, with 1,134 replies and 417 retweets in the pile — and 610 media files

Here's a handful from that archive — photos that spent years on one platform or another, and now live as files next to this post:

The Astronomical Clock in Prague at night
The Astronomical Clock — Hipstamatic, 2019
Prague Castle photographed through a tower filter
Prague Castle — Hipstamatic, 2019
The Emauzy monastery towers
Emauzy — Hipstamatic, 2019
A metal sculpture lit at night
Spholio, a sculpture at night — 2022
A photo taken on a Palm phone
Shot on a Palm phone — 2019, because the archive keeps the weird experiments too

The point

None of this is clever engineering. Downloading a file and putting it in a folder is about as advanced as computing gets. The clever part was done by every platform that convinced us it wasn't necessary.

An archive is only yours if the files are yours. Everything else is a lease — and fourteen years is long enough to watch a few landlords disappear.

Comments