Here's my five latest blog posts - or you can browse a complete archive of all my posts since 2008.

Choosing the Right Path

Srijan Singh pinged me on LinkedIn earlier today with a question:

I’m in my early career as a backend dev at IBM, and something I often wonder about is choosing the right path: whether to stick with a big company and learn deeply, or test myself in a startup environment (remote vs in-person adds to the mix too). Since you’ve navigated such diverse experiences, I’d love to hear how you’d approach that decision early on.

I quite enjoy getting these kinds of questions, but as Scott Hanselman wrote way back in 2010:

 If you email someone one on one, you’re reaching that one person. If you blog about it, you get the message out on the web itself and your keystrokes travel farther and reach more people. Assuming you want your message to reach as many people as possible, blog it. You only have so many hours in the day.

So here’s my answer to Srijan’s question, as a blog post.

Let’s start with the simple answer, which is how I did approach that decision early on… I didn’t, really. I was lucky enough that I didn’t really have to think about it. I loved working with computers, writing code, and building websites, and if I was getting paid money to do that I was happy. I landed my first graduate role in 2000, via one of my housemates who was working as a recruiter; three years later one of our clients, Spotlight, asked me to work for them full-time; fifteen years after that, I got head-hunted by Skills Matter to become their CTO; they went bankrupt in 2019, I set up my own company, Ursatile, and I’ve been independent ever since. To put this another way: I’ve had exactly two job interviews in my life, and one of those was to stack shelves in a grocery store when I was sixteen years old.

That probably doesn’t help, right? 😆

Looking back over 25 years of working in software, though, I think there are three things that matter:

  • The problem. Are you helping people? Are you making somebody’s day better? Are you building something that’ll make your end users happier? Or is your entire working life about making the CEO’s stock go up another point?
  • The people. Who are you working with? Are they competent? Are you learning from them? Do you enjoy their company? Do they respect your ideas?
  • The process. How does stuff actually get done? Everything from prioritisation and planning to what text editor you use. I enjoy working with some technology because it makes it easy for me do good work. I do not enjoy working with some other technology, because it makes it hard for me to do good work.

You don’t need all three. I’ve had bits of my career when I’ve been working with awesome groups of smart, kind people, using great tech to solve cool problems. I’ve also had bits of my career when I’ve been using painful tech to solve pointless problems, but the people made it worthwhile - and, occasionally, periods where I honestly didn’t care for the people or the problem, but was learning so much along the way that I probably stuck around longer than I should.

Think about longevity. You’re building solutions, relationships, and skills. Will the things you’re building last for a decade, or will they be obsolete by the end of the year? Can you take those things with you out into the wider world, or do they only have value in the context of your current role?

Remember to take stock once in a while. You might find the job that used to tick all three boxes is down to two, and then one… and when you’re down to one, you’re in danger, ‘cos if that one disappears too… well, congratulations. You’re stuck using tech you don’t enjoy to solve problems you don’t care about with people you don’t like.

Now, obviously there’s a huge amount of context to consider here. The tech jobs market is the worst I’ve ever seen; more of my dev friends are out of work right now than at any point since the first dotcom bubble, 25 years ago. If you’re supporting a family or paying off debts and you have a steady paycheque, maybe just keep your head down, keep doing what you do, wait for things to pick up. But if you’re early in your career, you’ve got a bit of financial security and you’re unhappy with how you’re spending your working days? Do something different. Bored of working in the enterprise? Find a startup. If you’re burning out working in a startup, get a comfortable, predictable job in a big company. If you’re remote, and tired of being at home all the time, find a job with a nice office; if the commute is making you miserable, try remote. When you try something, give it at least a year - but if you’ve lasted a summer and a winter, learned the ropes, learned the industry, and you’re still miserable? Probably time to move on.

Really, though, the important question when it comes to career progression isn’t “where do I see myself in five years”, it’s “am I going to quit my job today?” That’s the question that actually makes things happen. If the answer’s “hell, no, I’m happy”? Awesome. Go to work. If the answer’s “yes, today’s the day!” - well, good luck with it.

But if the answer’s “I don’t know”? Well, time to gather some more data.

"Choosing the Right Path" was posted by Dylan Beattie on 02 September 2025 • permalink

On The Road Again...

I’ve spent most of the summer so far writing a new course; if you follow me over on BlueSky - and you should - then you’ll have noticed I’ve been posting - skeeting? bleeting? I still don’t know what to call posting on BlueSky. Let’s go with bleeting. I’ve been bleeting about CSS a lot, because my new course is CSS for Software Engineers. The video course is going to be available on Dometrain later this year, I’ll be running it as a workshop at various conferences, and I have a funny feeling there might even be a book at the end of it… but that’s taking up pretty much all my time, not to mention brain capacity, and hasn’t left a whole lot of time for YouTube videos and stuff.

But, it’s nearly September (yeah, really), which means it’s nearly conference season again, and I’m going to be bouncing around Europe for the next few months talking about all kinds of things - machine learning, text encoding, Rockstar, open source, and, yep, CSS.

Now, here’s the thing. When folks like me get invited to speak at these kinds of events, the organisers really appreciate it when we make a bit of noise about it, post it on social media, blog about it, make videos… and I get it; marketing is tough, every bit of coverage might help shift a few more tickets, and the algorithms that drive social media apparently love short form portrait videos… but, y’know, I’m forty seven years old, I listen to Bon Jovi and I still don’t really understand what TikTok is for; somebody like me making a video on my phone about a .NET developer conference and hoping it’ll go viral is… I believe they call it “cringe”.

But then I remember a few years ago I was in Tartu, in Estonia, where I was giving the keynote at digit.dev, and somebody recognised me in the street from my YouTube videos and we got chatting… turns out they’re a developer, they love code, they really liked my conference talks, and they had no idea that I was the keynote speaker at a multitrack international conference taking place right in the city where they live. And Tartu’s not a big place; it’s got about 100,000 people.

So here’s the deal. I’m going to tell you where I’m going, on the off-chance that you’re local, and you have some training budget left, because it would really suck if there was an awesome event happening right there in your home town and you didn’t know about it.

If you want a whole “ten reasons you can’t afford to miss OpenTechDevConDays 2025”… well, nah. Not really my jam. They have marketing people for that.

For what it’s worth, I do try to make sure that every event I’m involved with is excellent; I put a huge amount of work into preparing talks and workshops, I bring stickers to give away, and I try to make sure I have as much time as I can to meet people, hang out and chat about what you’re all working on.

So here’s where I’m going to be. I’m obviously not expecting any of you to come along to all of these - although I’ll be very impressed if you do - but if I’m going to be in your neighbourhood, and if you can persuade your company to buy a ticket, then come along and say hi.

I did mention I’ll be giving away Rockstar stickers, right?

September 8-12th I’ll be at NDC Copenhagen, where I’m running a brand new workshop about all the amazing things modern CSS can do. I’ll be giving a talk about algorithms and why they’re not as scary as they look, and probably eating quite a lot of barbecue at Warpigs.

September 25th I’ll be Edinburgh at ScotSoft 2025 talking about plain text: weird and wonderful stories about teletype machines, Hungarian Scrabble, how emojis actually work, and what “PIKE MATCHBOX” has to do with driving in the Soviet Union.

October 3rd I’ll be in Dordrecht in the Netherlands with Fronteers; that one’s a one-track evening conference, so should be a lot of fun; we haven’t finalised all the details for that one yet, but keep an eye on https://www.fronteers.nl/ for more news.

October 9th + 10th, I’ll be in Riga for Zabbix Summit. Zabbix is an open source observability and monitoring platform, so the event’s all about infrastructure, automation and devops; I’m going to be talking about the history and future of free software and how we might be able to create a truly sustainable model for open source development.

Then I’m in Portugal for two weeks; October 13-16 is the Azure Developer Summit in Lisbon, a brand new event organised by Microsoft in partnership with NDC and Techorama, all about Azure, AI, .NET, C# - and then 20-24 October it’s NDC Porto, which has a different format this year; instead of one-hour conference sessions it’s all hands-on workshops. I’m doing two days about modern CSS, plus a session about building a ray tracer in JavaScript, and another one about how to build your own programming language using C# and .NET and parsing expression grammars.

Then I’m home for two days, then a Eurostar to Rotterdam and on to Utrecht, where by a happy coincidence Techorama is in town the same week as Tweakers Summit. ***Monday 27th October*** I’ll be at Techorama with a one-day Introduction to Distributed Systems with .NET workshop, Tuesday 27th I’ll at Techorama in the morning and then heading to DeFabrique to close the Tweakers Summit, then I’m back at Techorama on Wednesday.

And then November 5-7 I’m at Øredev in Malmö, where I’ll be telling the story of how I built a Rockstar interpreter in web assembly using C#, and rocking the party stage with The Linebreakers.

Oh, and if you’re thinking “wow, that’s not nearly enough travelling, this guy isn’t even trying any more”, I’m also going to the Euroblast festival in Cologne at the end of September, and heading to Yorkshire for the Whitby Goth Weekend at the end of October. Not performing or anything, just going along to watch bands and have fun. You know. Like a normal person.

So that’s, what, nine tech events - and two music festivals - in seven countries in two months. It’s going to be . Come along and say hi.

Right now, though, I gotta get back to writing about how CSS flexbox actually works, which turns out to involve way more mathematics than you might think.

"On The Road Again..." was posted by Dylan Beattie on 20 August 2025 • permalink

CSS Has 239 Different Ways To Make Something Blue

I’m making a new video course for Dometrain at the moment, and it’s all about CSS - one of the three pillars of the open web, along with HTML and JavaScript. I love CSS, I’ve been working with it literally since it was invented, but I absolutely understand why so many developers don’t enjoy working with it.

CSS has had to incorporate conventions and standards from a wider range of disciplines than any other mainstream technology. Modern CSS incorporates ideas from mechanical typesetting dating back centuries, conventions around information design from hundreds of years of printing and publishing, fifty years of innovations from digital publishing and computer graphics, twenty years of getting stuff wrong on the web while we were still figuring out how to get it right - right up to things like how to account for the “dynamic island” on the latest iPhone handsets.

To say it’s accumulated a few idiosyncrasies along the way would be an understatement. Yesterday, while putting together the module about how the various colours models work in CSS, I found myself wondering how many different ways there are in modern CSS to give a box a blue background.

I got to 239. Two hundred and thirty nine different ways to say “the box is blue”.

You’ve probably heard of named colours (color: blue;), and hex codes (color: #0000ff). Hex codes can also be written as three digits (#00f), four digits (#00ff), and eight digits (#0000ffff).

Then there’s the rgb() function, which can take each colour component as a decimal or as a percentage. There’s hsl(), which takes hue, saturation, and lightness, along with a bunch of new colour models - hwb(), lab(), lch, oklab() and oklch() - all of which also take a hue component.

Except hue in CSS is an angle - the colour’s position on a colour wheel - and CSS already has a unit system in place for angles, that’s used for rotations and transformation, so the colour models just reuse that. Which means you can write the hue component as degrees (with or without deg), radians, gradians (the cursed unit. 400 grads in a circle. Why does it even exist? I don’t know.), or turns. So if any colour specification involves hue, there are five different ways to write it.

Add in two different ways to specify alpha transparency - / 100% and / 1.0 - and you end up with well over two hundred different ways to say “the box is blue”… and this is just using the modern CSS colour syntax; we’re not even getting into the legacy rgb() and hsl() function syntax, their aliases rgba() and hsla(), or any of the wonderful things you can do with calc() and relative colours.

OK, let’s be fair here. If the language designers hadn’t reused CSS angular units for hue, we’d be looking at more like 40, maybe 50 syntax variants. Pick a lane for how you want to specify transparency, you’re down to 20 or so. You’re very unlikely to use the LAB or LCH colour models in production unless you know exactly what you’re doing, so that’ll chop it down further; in reality, you’re not going to encounter more than handful of these variants, and the vast majority of sites out there just use hex codes for everything.

But, y’know, if you’ve got the whole chaotic evil vibe going on, why not spec all your colours as oklch, lightness and chroma as arbitrary decimals, hue in grads, and give everything an alpha channel that’s randomly a percentage or a decimal, even for colours which are fully opaque?

I think you’ll all agree that color: blue; looks kinda dumb, but color: oklch(0.452 0.31 292grad / 100%); is clearly the work of a genius.

Check out the whole list over at https://dylanbeattie.net/miscellany/blues.html

"CSS Has 239 Different Ways To Make Something Blue" was posted by Dylan Beattie on 30 July 2025 • permalink

Naming Things is Hard... Renaming Things is Harder

You know those little things that you just sort of ignore, over over and over again, until finally one day the planets align and you’re like “No! I’m not putting up with this any more! There must be a way to fix it!”

canon-eos-m200

Welcome to my cameras. I have two Canon EOS M200 cameras, which I use for streaming, recording training videos, teaching online workshops, all kinds of stuff. One is black, one is white, they are otherwise identical. They’re both connected to my main PC using Elgato Cam Link 4K HDMI capture devices, which for the remainder of this article I will call camlinks because they don’t have a better generic name.

They’re also connected using micro-USB, which means I can use Canon’s Remote Shooting utility to control things like the F-stop, white balance, and ISO. The cameras themselves are permanently mounted around my desk — one is above my main screen, the other one’s built in to a teleprompter — so it’s kinda hard to fiddle with the settings menu.

The problem is that when I go to fire up the EOS utility, it asks me to pick which camera I’m using… am I using the Canon EOS M200, or the Canon EOS M200? And then there’s the fact that both of the dongles show up in Windows as “Cam Link 4K”, which means setting up video sources in programs like OBS Studio normally involves picking the wrong camera at least once.

Well, this morning I had that fateful nerd thought… “I should fix this. How hard can it be?” Well, grab your razor and strap in, friends… we’re going yak shaving! Now, most of the time, if you want to rename a thing in Windows, you right-click it, and choose “Rename”, and give it a new name.

That doesn’t work in Device Manager. I mean, sure, rename a file, but why would anybody ever need to rename a camera? OK, no big deal. Those names have got to come from somewhere. Probably the registry. So I fire up regedit, Ctrl-F, “Cam Link 4K”, hit “Find Next”:

And I wait, and wait, and wait a bit, and then I get bored because this is a Ryzen 9950X3D with 128Gb of RAM and I didn’t spend that kind of money so I could sit around and wait for things, dammit!

I tried writing a Powershell script to do the same thing — trawl the registry, look at all the keys and subkeys and entries and values — but it did that infuriating thing where it takes so long to not do anything that it wasn’t clear after 30 seconds whether the program worked, but hadn’t matched anything, or I’d screwed up the matching logic.

Ok, much better approach: let’s dump the entire system registry to a text file and then I can edit it properly. File, Export, registry.txt, takes about a second. Done.

I now have a 540Mb text file full of bits of Windows registry. It looks like this:

[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\termbus.inf_amd64_7ccf415b3c0cf753\Descriptors\TI_COMPAT_DEVICE]
"Configuration"="TS_INPT_DEVICE.NT"
"Manufacturer"="%msft%"
"Description"="%ts_inpt_device.devicedesc%"

[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\termbus.inf_amd64_7ccf415b3c0cf753\Descriptors\TS_BUS]

[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\termbus.inf_amd64_7ccf415b3c0cf753\Descriptors\TS_BUS\TS_INPT]
"Configuration"="TS_INPT_BUS.NT"
"Manufacturer"="%msft%"
"Description"="%ts_inpt_bus.devicedesc%"

[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\termbus.inf_amd64_7ccf415b3c0cf753\Strings]
"msft"="Microsoft"
"ts_inpt_device.devicedesc"="Remote Desktop Input Device"
"ts_inpt_bus.devicedesc"="Remote Desktop Input Bus Enumerator"

[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\termkbd.inf_amd64_b0e97bc9e5ad246d]
"Version"=hex:ff,ff,09,00,00,00,00,00,6b,e9,36,4d,25,e3,ce,11,bf,c1,08,00,2b,\
  e1,03,18,00,c0,17,1d,14,c2,c9,01,7e,04,f4,65,00,00,0a,00,00,00,00,00,00,00,\
  00,00
"Provider"="Microsoft"
"SignerScore"=dword:0d000003
"FileSize"=hex(b):70,34,01,00,00,00,00,00
"StatusFlags"=dword:00000112
@="termkbd.inf"

Each chunk is in this format:

[HKEY_LOCAL_MACHINE\SYSTEM\Path\To\Registry\Key]
"Name"="String Value"
"AnotherName"=dword:12345678
"ThirdName"=hex(b):aa,bb,cc,dd,ee,ff,11,22

So I want to find every chunk that contains any entry whose value contains "Cam Link 4K" or "Canon EOS M200", and then extract:

  • The first row of that chunk, which is the path to the registry key I need to edit
  • The entry itself

Then — in theory — I’ve got a handful of registry entries in a file, which I can edit in VS Code or something, import it into regedit, and presto! rename all the things.

First idea: pull it into VS Code, replace all the \n with a marker __EOL__ so I get every block on its own line, delete all the lines that don’t contain "Cam Link 4K" or "Canon EOS M200", turn all the __EOL__ back into \n, and then do the rest by hand.

Yeah… VS Code won’t do that.

image-20250726170311811

TextPad wouldn’t do it either…

But it's OK. We solved this problem. We solved it BEFORE I WAS BORN. The beardy wizard people who created Unix knew all about editing files that wouldn't fit in memory, because they built Unix for computers that had an ENTIRE MEGABYTE of RAM... which you had to share with the rest of the university.

— Dylan Beattie (@dylanbeatt.ie) 26 July 2025 at 10:42

Yep, this is a job for awk. You probably don’t know what awk is. Awk is a stream-based editing utility originally created for Unix. So I asked Copilot to write me an awk script. (what, you think I can remember how to write awk? University was a long time ago, friends…)

BEGIN {
	RS = "\n\n";   # Blank lines separate records (blocks)
	ORS = "\n\n";  # Output blocks separated by two newlines
}

{
	if ($0 ~ /Cam Link 4K || $0 ~ /Canon EOS M200/) {
		n = split($0, lines, "\n")
		output = lines[1]
		for (i = 2; i <= n; i++) {
			if (lines[i] ~ /Cam Link 4K/ || lines[i] ~ /Canon EOS M200/) {
				output = output "\n" lines[i]
			}
		}
		print output
	}
}

Yeah, that’s what awk looks like. Remember, this is the language that Larry Wall looked at, went “well, golly,I can do better than that”, and… invented Perl.

Of course, it didn’t work. Me & my little electric copilot buddy had missed two rather significant details… first, the RS record separator? We’re trawling a file created by Windows regedit. It’s using \r\n, not \n. Easy fix; change `RS = “\r?\n\r?\n” `(and look, now it’ll work cross-platform if I ever need to awk the Windows registry on macOS!)

Still doesn’t work… because the Windows Registry Editor’s Export feature creates text files that are encoded as UTF16-LE, and awk don’t do UTF16. So I use VS Code to save the registry file as UTF-8, and off we go…

gawk -f filter.awk registry.txt > devices.txt

It works! devices.txt now has a little registry snippet for every single chunk of registry that includes "Canon EOS M200" or "Cam Link 4K"

"Canon EOS M200" appears 25 times in the registry. "Cam Link 4K" appears 60 times - and the exact entry "FriendlyName"="Cam Link 4K" accounts for 41 of those... crikey. That's a lot of times.

— Dylan Beattie (@dylanbeatt.ie) 26 July 2025 at 11:22

OK, let’s figure out which one goes where.

I am assuming at this point that nothing in Windows is stupid enough to actually open, connect, etc. devices based on a field called FriendlyName. If I’m wrong, things are about to get extremely hilarious indeed.

So I use Textpad’s really handy “sequence replace” feature, that’ll let you use a regex to find something and then include an incrementing sequence number in the replacement expression:

Textpad Search and Replace

The result is a registry file where every FriendlyName value is now unique - so I can in theory reboot, see which names appear in which drop-down menus and dialogs, and then edit them accordingly. In theory.

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Portable Devices\Devices\USB#VID_04A9&PID_32EF#9&39F7FE61&0&3]
"FriendlyName"="Canon EOS M200 UNIQUE12"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Portable Devices\Devices\USB#VID_04A9&PID_32EF#A&D9BD236&0&3]
"FriendlyName"="Canon EOS M200 UNIQUE13"

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{eec5ad98-8080-425f-922a-dabf3de3f69a}\0005]
"FriendlyName"="Canon EOS M200 UNIQUE14"

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{eec5ad98-8080-425f-922a-dabf3de3f69a}\0009]
"FriendlyName"="Canon EOS M200 UNIQUE15"

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\USB\VID_04A9&PID_32EF\9&39f7fe61&0&3]
"FriendlyName"="Canon EOS M200 UNIQUE38"

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\USB\VID_04A9&PID_32EF\a&d9bd236&0&3]
"FriendlyName"="Canon EOS M200 UNIQUE39"

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\USB\VID_0FD9&PID_0066&MI_00\a&1b1e3ad0&0&0000]
"FriendlyName"="Cam Link 4K UNIQUE40"

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\USB\VID_0FD9&PID_0066&MI_03\a&1b1e3ad0&0&0003]
"FriendlyName"="Cam Link 4K UNIQUE41"

Add the first line to the file otherwise regedit rejects it:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Portable Devices\Devices\USB#VID_04A9&PID_32EF#9&39F7FE61&0&3]
"FriendlyName"="Canon EOS M200 UNIQUE12"

...and so on...

Import…

img

Reboot… IT WORKED!

image-20250726172549272

Well, it worked mostly. At first, the Canon EOS Utility Launcher didn’t pick it up at all, and it turns out some of the Canon EOS utilities read the DeviceDesc value from the registry, not FriendlyName, so I edited that one too… at this point I got into a good half-hour of editing something, rebooting, seeing what had changed, edit again, reboot again, turn it off and on again… and quite a few moments where I thought I’d tried everything I could think of, including a reboot, and it still hadn’t worked…

And then, one final, glorious reboot, and there it was.

image-20250726172814992

image-20250726173048019

And you know what?

I will bet money, good, solid, chunky cash dollar money, that at some point, somebody at Canon said “er… boss, what happens if somebody buys two of the same camera, and has them both plugged in at the same time over USB?” and somebody’s boss said words to the effect of “stop derailing the planning meeting with your stupid edge cases, Chris, we have work to do and you’re not helping.”

I see you, Chris.

I see you, and I salute you. 🫡

Oh, and Microsoft: if we could get right-click, Rename… in the Device Manager? That’d be, like, just swell.

"Naming Things is Hard... Renaming Things is Harder" was posted by Dylan Beattie on 26 July 2025 • permalink

The Subtle Art Of Deprecating API Endpoints

I had an app fail in production the other day. Not seriously - only affected a couple of admin screens - but it failed because Hubspot had deprecated some of their API endpoints. (That’s nerd speak for “we were using a thing and they turned it off.”)

https://developers.hubspot.com/changelog/breaking-change-removed-support-for-referencing-custom-object-types-by-base-name

Sure, they announced in October 2024 that this particular endpoint was being deprecated. Only problem is… I didn’t see the announcement, because I didn’t even start working on this integration until April 2025 - in fact, I’d never worked with Hubspot’s API at all prior to April 2025. I followed their docs, built the integration points I needed, tested it all… and I somehow managed to build and test an integration against an endpoint which was already scheduled for deprecation, without ever having the faintest clue.

Wouldn’t it be nice if, the day they decide something’s going to get switched off, that feature was no longer available to any new customers? Sure, the folks who were already using it before the announcement; makes sense to give them six months or whatever to update their code. But seems a bit odd to me that they’d offer completely new integrations access to a feature they already know is going to shut down soon.

..then again, maybe I’m just salty ‘cos I don’t like it when other people break my stuff. I guess the lesson is to always assume that every single API request you make might randomly start returning an HTTP 400, at any point, for no good reason, and engineer around that as best you can. Fallback caching actually kept the thing running for at least a week after the endpoint in question was deprecated, which I’m kinda happy about - but I could also have wired it to actually tell somebody if it had been running on cached data for more than 24 hours.

"The Subtle Art Of Deprecating API Endpoints" was posted by Dylan Beattie on 16 July 2025 • permalink