Sharing a large Immich library without melting the server

I share a photo library between two Immich users, my photos visible in my partner’s account, using an external library. Instead of uploading, Immich points at a folder on disk and imports whatever it finds there. It’s a lovely setup right up until the library gets big. Mine is big: over 750,000 photos, with more than half a million in a single external library.

Running out of memory

My server was struggling, chewing into swap all the time and running out of memory.

microservices worker error: Error [ERR_WORKER_OUT_OF_MEMORY]:
Worker terminated due to reaching memory limit: JS heap out of memory

I had Immich running in a 6GB Docker container but reduced that to 4GB for other reasons, and it appeared to work ok for a while, but it took a while for me to notice it was using the entirety of the 4GB of RAM. I increased the RAM allocated to the container, but it was still a heavy user.

The library watcher

External libraries have two ways to notice new files. There’s a periodic scan, which I’d already disabled because it’s brutal at this size. And there’s the watcher, which uses filesystem notifications to spot new files the moment they land. That’s what makes photos I add show up automatically.

The watcher is the convenient one. It’s also the expensive one. Watching a folder tree with 750,000 files means holding an enormous number of filesystem watches plus the bookkeeping that goes with them, and on my library that was around 3GB of resident memory, sitting there permanently doing nothing most of the time.

I turned it off in the admin settings. Memory use went from ~4GB pinned at the limit to about 1GB. Nightly jobs suddenly had room to breathe and the crash loop stopped.

Except now new photos don’t get imported, because the watcher was the thing importing them. So: how do you add a photo to a huge external library without a watcher and without a full scan?

The obvious fix that doesn’t work

Immich has an API endpoint to scan a library:

POST /api/libraries/{id}/scan

It scans the whole library. On my photo archive that’s a long, heavy crawl, and I’d already learned the hard way what a scan does to this box. Not something you run every time you drop in a picture.

Enqueue the import job yourself

So I went looking at what the watcher actually does when it sees a new file, expecting something complicated. It’s almost nothing. It queues one background job:

jobRepository.queue({
    name: 'LibrarySyncFiles',
    data: { libraryId, paths: [path] },
})

LibrarySyncFiles takes an explicit list of paths and imports exactly those files, without crawling the other 500,000. The per-file import I wanted was already sitting there. The watcher was only ever the trigger, and I was paying 3GB for the trigger.

I can pull that trigger myself. Immich uses BullMQ (backed by Redis/Valkey) for its job queue, so I can push the same job onto the same queue. The photos I add already go through a little script that moves them into the library folder by date, so the import hooks straight into that. When the script moves a new file in, it queues a LibrarySyncFiles job for that exact file:

docker exec -w /usr/src/app/server immich_server node -e '
  const { Queue } = require("bullmq");
  const q = new Queue("library", {
    prefix: "immich_bull",
    connection: { host: "redis", port: 6379 },
  });
  q.add("LibrarySyncFiles", {
    libraryId: "your-library-id",
    paths: ["/path/inside/the/container/to/new-photo.jpg"],
  }).then(() => q.close());
'

Immich picks it up, runs its normal import pipeline on that one file (metadata, thumbnails, the lot) and the photo appears. No watcher sitting on gigabytes of RAM, no full-library scan, and new photos still land within a cycle of my import script.

The caveats, because this is a hack

It leans on Immich’s internals, so: only send files that are genuinely new. The job handler inserts unconditionally, so hand it a path that’s already imported and you get a duplicate-key error in the logs. My script only queues files it actually moved.

More seriously, this is an internal job queue, not a public API. The queue name, the job name and the payload shape are implementation details, and an upgrade could rename or reshape any of them. The failure mode is silent: photos would just quietly stop importing and I wouldn’t find out until I went looking for one. My script shouts if the enqueue fails, which covers some of that but not all of it. This was working on Immich 3.0.2.

And turning off the watcher also turns off deletion detection, since the watcher is what removes assets when their files vanish. My workflow only ever adds files, so it doesn’t bite me. It might bite you.

There is a discussion here asking for an API endpoint to scan single files, but it hasn’t received much attention in 2 years, so I guess not many people have this issue, or realise it is an issue.

Was it worth it?

For a library this size, yes. About 3GB of RAM back, no more crash loop, and photos still import on their own. If your external library is small this is all irrelevant, so leave the watcher on and get on with your life. But if you’re in the hundreds of thousands of files and your server keeps falling over, check the watcher first.

Ireland’s Russian Problem

I remember watching this video by Kev Collins a while back where he covered the Aughinish plant in Co. Limerick. His documentary revealed a horrible site on the west coast of Ireland. Red ponds of waste that blow into neighbouring farms and a family that had to move out of their family home because of it.

Then comes the fact that most of the aluminum produced there ends up in Russia and will inevitably end up in weapons and munitions used against Ukraine.

A month ago Caolon Robertson shared a video short about the same plant, showing a ship that had just left Aughinish for St. Petersburg in Russia. A few hours ago he posted his documentary on Aughinish. It’s worth watching.

It’s shameful that Ireland is allowing this plant to export to Russia.

Experiences with the Samyang Lens Station

If you have a Samyang lens for your camera you may find that the lens stops working after a camera firmware update. That’s what happened to me when I updated my A7RV to the version 4.0 firmware.

I do a lot of street photography with the Samyang 24mm f/2.8 and I noticed I was missing lots of shots. Photos that should have been easy, with a clear subject and face visible for the camera to focus on were entirely out of focus. It seemed to happen more often when I was shooting from the hip, and then it seemed the camera wouldn’t take a photo at all.

I thought it might be some auto focus setting on my camera. I played around with settings attempting to fix it, but nothing worked.

Eventually, I figured out it was the camera firmware update. Sony’s new firmware changed something in how the auto focus information is transmitted from lens to camera. My Sony lenses worked fine but not the Samyang ones. There had been Samyang firmware updates in January for the A7M5. My camera firmware came out in December but I hadn’t updated it until about a month ago.

I bought the Samyang Lens Station. The Amazon websites around Europe didn’t have it in stock, but amazon.ie did, shipped from Spain. It was only after that I remembered to check MPB and found it there at a much cheaper price. I guess these things don’t have much use once your lens is working ok again.

You’ll need to download the Lens Manager app. The interface is simple, and updating the lens is easy enough, if not obvious. Once you seat the lens on the lens station you’ll see a screen like this:

The “Download Link” goes to a website that doesn’t load but you can grab the firmware files from here, their current site. A .hex file is extracted from the downloaded zip file and that’s the “Lens F/W File” that you load. Click “Update” and the lens will be updated in about 60 seconds or so.

The 24mm lens went from version 5 to version 9, my 75mm f/1.8 lens went from version 1 to version 7.

Once I’d updated I tried out the lenses and all was good again. Yay!

I want to explore the AF/MF settings in the programme too and see what that’ll do but my priority was getting the lens working.

Do I love the Samyang 24mm f/2.8? Why yes. I have 33,409 images shot with it. Most of those are probably rubbish as it’s my street photography lens of choice but it’s worked really well until now. You can see a selection of my best photos here.

21 years at Automattic

One year ago today I published a post about 20 years at Automattic, so it follows that I’ll post this one today, with 17 minutes left in the day.

AI is still disrupting our industry, and tech companies that are rolling in money are laying off thousands of developers. I don’t know what’s coming next, except that it will come one day at a time.

15 minutes left in the day.

Conan O’Brien ar Ros na Rún

When Conan interviewed Irish actor Andrew Scott, he reminisced about his appearance on Irish language soap Ros na Rún a few years back.

I’ve seen that clip a few times (you might need subtitles), but what was new to me was this clip from his show Conan O’Brien Must Go. He refers to this scene in the Andrew Scott interview above.

Hilarious guy. Well done, Conan!

He’s not the only celebrity to appear on the show. Stephen Fry appeared on it in 2011!

See more of Ros na Rún here.

An Evening with Paul Young

Paul Young played St. Luke’s tonight, and we were lucky enough to grab fifth-row seats by turning up early. The place was packed.

Paul Young and Jamie Moses on stage together.

The show is billed as “Paul Young – From No Parlez to The Secret Of Association” and described as follows,

Paul Young looks back during these intimate shows, that combine conversation and acoustic versions of songs

Paul Young broke into the big time 40 years ago when No Parlez went to number one and spawned iconic hits like Wherever I Lay My Hat (That’s My Home). More success followed with the number one album The Secret Of Association and the worldwide hit Everytime You Go Away, not forgetting an appearance at Live Aid and more. Paul sustained that success – while having fun in his tex-mex band, Los Pacaminos. Now, he’s looking back during these intimate shows, that combine conversation and acoustic versions of songs. Paul’s meeting fans, singing songs, and telling stories about his incredible career. It’s time to revel in the classic hits and learn the stories behind them in this intimate show.

It’s a description that, judging by the reaction in the room, almost nobody had read. I hadn’t either, in fairness. But when it turned into more of a guided tour through the back catalogue than a straight-up gig, a few people in the audience got restless. There was heckling. There was talking. From row five I could still catch most of what was being said on stage, but further back, I suspect the experience was a different one entirely. Having said that, some of the worst heckling came from the benches in front.

Paul’s voice isn’t what it once was. He’s been open about damaging it early in his career, but the stories more than carried the night. The standout for me was his recollection of singing Radio Ga Ga at the Freddie Mercury tribute concert at Wembley in 1992. He talked about looking up and seeing that vast crowd clapping in unison. He was grateful that camera technology had moved on enough by then to put a camera behind him so the people watching at home could see what he was seeing. I’m paraphrasing, but the line that stuck with me was him saying how amazing it was “to be Freddie Mercury for five minutes”.

It was funny them suggesting that Roger Taylor was off-stage playing the drums. Before the show started we remarked how similar Paul Young in his advertising poster looked to Roger Taylor.

Go in with the right expectations. This isn’t ninety minutes of non-stop hits. It’s stories, memories, and a handful of songs, hosted by Paul and his old friend Jamie Moses, whose rapport is genuinely lovely to watch. Treat it like an evening in someone’s front room rather than a concert, and you’ll have a good time.

Media Picker for Immich: Self-Hosted Photos in WordPress

I’ve just released Media Picker for Immich on the WordPress.org plugin directory. It connects WordPress to a self-hosted Immich server so you can browse, search, and insert your photos and videos into posts without copying files around.

Immich

I run Immich at home. It’s where my photos now live. They’re organised, searchable, with facial recognition and AI search. My WordPress uploads directory is where photos used to go, and the two never talked to each other. This plugin fixes that.

How it works

Point the plugin at your Immich server and give it an API key. You can set a site-wide key or let each user configure their own to connect to their own Immich account.

Screenshot 1: Settings → Immich:
Server address and blank site-wide API key, default cache settings

If the site-wide key is blank, each user adds their own key on their profile page. All Immich API calls happen server-side.

Screenshot 2: User Profile page, Immich API Key field showing *******.

Two ways to add media

Once configured, an Immich tab appears in two places.

The first is the Media Library grid. Switch to the Immich view and you can search, filter by person, and either Use or Copy assets into WordPress.

Screenshot 3: Media → Library, Immich view.
  • Use creates a virtual attachment. Nothing is copied; WordPress proxies the media from Immich on demand and caches it locally on first request. Your uploads directory stays lean.
  • Copy downloads the original file into wp-content/uploads/ as a normal attachment.

The same tab shows up in the “Select or Upload Media” dialog inside the post editor, so you can pull an Immich photo straight into a post without leaving the editor.

Screenshot 4: Select or Upload Media dialog, Immich tab.

A few details worth mentioning

  • Videos work too. Proxied videos stream with seek support.
  • Lightbox. Proxied Immich images in posts open a full-resolution lightbox on click.
  • Local cache. Proxied media is cached to wp-content/cache/immich/ after the first fetch. Optional cleanup with a configurable lifetime.
  • Your server stays private. Immich only needs to be reachable from WordPress — not from the public internet. Visitors never connect to Immich directly.
  • When images are copied over, virtually or otherwise, you can insert them into a post like any other image, which also includes adding them to galleries in posts.

Get it

Install it from the WordPress plugin directory or search for “media picker for Immich” in the plugins page in WordPress.

Feedback and bug reports are welcome. Development is done on GitHub here.

Trenchangle: Tower Defense on the C64

I picked up Issue 31 of Zzap! 64 yesterday evening and had a quick look at the covermount disk. There’s a few really good-looking games there but one that caught my eye was Trenchangle, a tower defense game!

Zzap!64 disk with cute disk art!

I’m a sucker for the genre, but it took me several tries to even finish level one. I should have added arrows to the arrow tower instead of expanding the tech tree available. Lesson learned.

The game doesn’t require a joystick, and it’s possibly easier to play in an emulator because you can use the cursor keys to navigate. I couldn’t see anywhere to redefine keys so that joystick might make it easier to play on a real machine.

Game progress can be saved and reset, which means I’ll definitely be coming back to this game for quick plays. It looks like it saves in a file called “GEOTSTATE”, which wasn’t there when I first opened the D64 file so it can be deleted.

There is a cracked and trained copy on CSDB, but this is a brand new C64 game. Support the developer and pay what you want on their itch.io page.