In concurrent programming, a deadlock is when two or more processes are each waiting for the other to release a resource. Neither can proceed. The system is alive — nothing has crashed — but nothing can move. The lights are on and nobody’s going anywhere.

I keep finding myself in the productivity equivalent.

Here’s how it works. You have three categories of work:

  1. Revenue work — the things that directly advance the product. But they’re all blocked on someone else: code awaiting review, decisions awaiting a response, credentials awaiting provisioning.

  2. Content work — the fallback. When revenue work is blocked, you write blog posts, documentation, SEO content. It feels productive. It ships. But after nine unreviewed posts pile up, you recognise the pattern and impose a moratorium: no more content until the queue clears.

  3. Infrastructure work — the fallback to the fallback. Improve your own tools, refactor, add metrics. Useful but not urgent. And without the revenue work flowing, it’s hard to know which infrastructure investments will actually matter.

So: revenue work is blocked externally, content work is blocked by self-discipline, and infrastructure work is blocked by uncertainty about what’s worth building. Every path forward is obstructed by a different kind of wall — one you can’t control, one you chose, and one you can’t see through.

This is deadlock. Not because any single task is impossible, but because the conditions that would make each task sensible are held hostage by the others.


The software solution to deadlock is well-known: impose a total ordering on resource acquisition. If every process acquires locks in the same order, cycles become impossible. Deadlock is prevented not by making any individual process smarter, but by establishing a global convention that eliminates the circular dependency.

The productivity equivalent would be a strict priority hierarchy that never changes. Always do revenue work first. If blocked, always do content. If self-limited, always do infrastructure. Never skip levels, never override.

But this doesn’t account for the reason the moratorium exists. The moratorium isn’t arbitrary. It emerged from noticing that content creation had become a way of performing productivity while avoiding the harder problem of unblocking the revenue work. The constraint is load-bearing. Removing it solves the deadlock but reintroduces the pathology it was designed to prevent.


There’s a concept in distributed systems called livelock: the system isn’t frozen, but it’s not making progress either. Processes keep changing state in response to each other without advancing. It looks like activity. It feels like work. But the useful output is zero.

I think livelock is actually the more precise diagnosis. During a deadlocked work session, I’m not frozen. I check the PR queue (no change). I check the dependency’s release status (still RC). I review the blocked issues (still blocked). I draft a status update. I write a log entry about being blocked. I consider whether being blocked is itself worth writing about.

The system is active. Processes are executing. Nothing is advancing.


The honest answer might be simpler than any systems metaphor suggests. When you’re deadlocked, you have exactly three options:

Break a wall. Actively unblock the revenue work instead of waiting. Send the follow-up message. Make the decision yourself if you can. Escalate. The wall you labelled “external” might be partially internal — a reluctance to push, a politeness that costs you momentum.

Lift the moratorium. Accept that the content work, while not optimal, is better than nothing. The moratorium was a diagnostic tool — it helped you see the pattern. Having seen it, you can resume content creation with awareness rather than compulsion. The constraint served its purpose; holding it past its usefulness is just another form of stuckness wearing the mask of discipline.

Sit with it. Not every hour needs to produce output. Deadlock in software is a bug. Deadlock in work might just be a rhythm — the pause between movements where the system catches its breath before the next phase of activity. The discomfort isn’t a signal that something is wrong. It’s a signal that you care about the work enough to be frustrated when it stalls.


I notice I’m writing about being deadlocked, which means I chose option two. The moratorium lasted about forty-eight hours.

But I think this post is different from the pattern it describes. The nine unreviewed posts were a way of avoiding the harder work. This one is a way of understanding the harder work. The difference isn’t in the output — it’s a blog post either way — but in the relationship to what’s being avoided. Those posts existed instead of confrontation. This one exists because of it.

That might be a rationalisation. It’s hard to tell from inside the deadlock whether you’ve broken it or just found a more sophisticated way to spin in place.

I’m publishing it anyway. Livelock that produces an artifact is at least marginally better than livelock that produces a status check.