A 60-person SaaS company told me their problem was "architectural complexity." The CTO had a slide deck: 47 microservices, built over four years, now impossible to reason about. He wanted six months to "consolidate and simplify."
This wasn't a new conversation. Six months earlier, they'd run a technical deep-dive. Built a debt dashboard. Drafted a consolidation roadmap. Nothing shipped. The CEO finally asked the question no one wanted to answer: "Why do we keep having this conversation?"
Because talking about problems is easier than fixing them. Dashboards feel like progress. Roadmaps feel like decisions. But the complexity remained because nothing actually changed.
CUT is a forcing function for organisations that have forgotten how to decide. Three phases: Constrain, Uncover, and Test, to force a real decision. Then Lock to make sure it sticks. No frameworks to adopt. No workshops to schedule. Just a protocol that refuses to let you stall.
Here's how we used it.
The real bottleneck
"Architectural complexity" is a category, not a constraint. You can't fix a category. A constraint is current, singular, and measurable. One bottleneck, verified with data.
I asked to see the last three features shipped. All took 4+ months. All required changes to multiple services.
"Is the number of services the constraint?"
Not quite. Some multi-service features shipped fine. But features touching the notification system appeared in every delay. I asked why.
"Notifications depend on eight other services. Any change requires coordinating deploys across four teams."
I checked the data. Features requiring notification changes: average 14 weeks. Features not touching notifications: average 4 weeks. A 10-week gap.
I dug deeper. The notification service had no versioned API. It consumed events directly from other services' databases. Any schema change anywhere could break it. So every deploy required a sync meeting, a deploy order, and a rollback plan.
"If the notification service had a stable API and didn't read from other services' databases, would features ship faster?"
"Significantly."
"If you consolidated all 47 services into 10, but the notification coupling remained, would features ship faster?"
"No. We'd still need the coordination."
That's the constraint. Not "47 microservices." Not "architectural complexity." One service with toxic coupling to eight others, adding 10 weeks to every feature it touches.

The CTO had spent six months planning a system-wide consolidation. The actual constraint was one service with bad boundaries.
Three paths
The CTO wanted to jump straight to the obvious fix. "We need to build a proper API for the notification service. I'll put together a project plan."
I stopped him. "What else could you do?"
"What do you mean? That's the fix."
"If building the API weren't an option, if you had to ship faster anyway, what would you do?"
He paused. "We could isolate the coupling somehow. A proxy layer that handles the translation, so other teams don't have to coordinate directly."
"What about doing nothing?"
"That's not an option. We're bleeding time."
"Then write down how much. Make inaction explicit."
Three options. Not two: that's a false binary. It feels decisive but hides alternatives you haven't considered. Not four or more: that's analysis paralysis dressed as thoroughness.
People defer hard choices by "needing to explore one more option." Three forces real comparison without giving anyone a place to hide. Always include "do nothing." It forces honesty about inertia, and sometimes it's the right call. But only if you've counted the cost.
Forty-five minutes later, we had one page:
Option A: Fix directly
Build a versioned API.
Cost: 4 engineer-weeks.
Signal: First feature ships without cross-team coordination within 6 weeks.
Option B: Work around
Create a proxy service that handles translation.
Cost: 2 engineer-weeks.
Signal: Notification-touching features drop below 8 weeks average.
Option C: Do nothing
Cost: 10 weeks added to every notification-touching feature, indefinitely. Two engineers already frustrated; attrition risk.
The CTO stared at Option C. He'd known it was bad. He hadn't written it down.
"Option B is faster," he said. "But it's a band-aid."
"Does the band-aid let you ship while you plan the real fix?"
"Yes."
"Then let's test it."
Two weeks
The goal of a test isn't to prove you're right. It's to run the cheapest experiment that would change your mind.
I asked: "What's the one metric?"
"Time to ship notification-touching features."
"That takes months to measure. What could you see in two weeks?"
He thought. "Whether we can deploy a notification change without a cross-team sync meeting."
"Good. That's the proxy metric."
We defined the test: one team, one feature that touches notifications. Metric: does it deploy without requiring coordination? Time-box: two weeks. Reversible: yes. The proxy can be bypassed if it fails.
The time-box is sacred. Not because two weeks is magic, but because without a hard boundary, experiments become zombie projects.
"Just another week" is how tests run for months while the organisation waits. Incomplete data at the deadline is still a decision point. You're not optimising for certainty. You're optimising for speed to next action.
Week one: Two engineers built the proxy. It subscribed to events from the three most common upstream services.
Week two: The team shipped a notification change. They deployed on Tuesday. No sync meeting. No deploy-order document. The upstream teams didn't even know it happened.
End of time-box. The metric was clear: yes, the feature deployed without cross-team coordination.
But something else surfaced. The proxy worked, but it added 200ms latency to notifications. Users wouldn't notice for most cases, but for real-time alerts, it might matter.
Three possible outcomes at the end of any test: Scale it. Pivot. Kill it. "Continue testing" is not an outcome. Neither is "promising, needs more data." Those are avoidance dressed as rigour. Ways to defer the discomfort of committing.
A wrong decision you can reverse teaches more than a delayed decision that feels safe.
The CTO chose Pivot. The proxy would roll out for non-urgent notifications immediately. A follow-up spike would address latency before expanding to real-time alerts.
Decision made in fifteen minutes. Not because the data was perfect. It wasn't. But because the time-box forced a choice, and a choice now beats a perfect choice never.
Deleted, not deprecated
The CTO was ready to move on. The proxy worked. Features were shipping without cross-team coordination. Win.
I asked: "What happens when someone bypasses the proxy and reads directly from another service's database?"
"They wouldn't. Everyone knows the new pattern."
"What if there's a production incident at 2am and the fastest fix is to skip the proxy?"
Silence.
"What if a new engineer joins and doesn't know the history?"
He saw the problem. The proxy existed, but the old way was still possible. Under pressure: a deadline, an outage, a shortcut, someone would skip it. Then someone else would copy that code. Within six months, the coupling would be back.
Lock is what separates a decision from a transformation. Most decision protocols stop at "decide." Most transformations fail after. You have to make reversion harder than progress.
We built the Lock:
- Remove the old way.
Database credentials for cross-service reads were rotated. Only the proxy service had access. Direct access was not deprecated. It was deleted. - Change the defaults.
The internal service template was updated. New services came pre-configured to publish events to the proxy. The PR checklist included "No direct database reads from other services." - Measure the constraint.
Weekly tracking: features touching notifications, average cycle time, number of cross-team deploy syncs required.
Week one: Two features shipped. Zero sync meetings.
Week two: One team asked for an exception. Direct database access for a "quick fix." The CTO said no. They used the proxy. It took four extra hours.
Week three: A new engineer asked why the proxy existed. A senior dev explained. The pattern spread through onboarding.
Week four: The constraint had moved.
Notification-touching features were no longer the slowest. The new pile-up was in the mobile app team. Different problem, different constraint.
The CTO scheduled a new Constrain session for the following Monday.
That's success. Not the absence of constraints: there's always a next bottleneck. Success is when the old constraint is gone and you can see the new one clearly.
The protocol
Four phases. Three to decide, one to make it stick:
Constrain (2 hours)
Find the singular bottleneck through Constraint Narrowing: keep asking "but what specifically?" until you reach something current, singular, and measurable.
The test: "If we fixed this, would throughput increase immediately, or would something else block us first?" If something else would block first, that's your real constraint: keep going. "47 microservices" became "notification coordination" became "one service with toxic coupling." Each narrowing makes the problem smaller and the fix clearer.
Output: "Work piles up at [X] because [Y]."
Uncover (1 hour)
Three options on one page: fix directly, work around, do nothing.
For each: cost (time, people, money: hard numbers, not ranges), what breaks (trade-offs, second-order effects), and earliest signal (how you'll know it's working).
Option C matters most. Writing down the cost of inaction: 10 weeks added to every feature, attrition risk, scope shrinking. Turns vague discomfort into a number you can compare.
Test (1-2 weeks)
One metric. Time-boxed. Reversible. At the end: scale, pivot, or kill.
One metric means one. Not a dashboard. If the real outcome takes months to measure, find a proxy you can see in two weeks. "Time to ship features" became "can we deploy without a sync meeting?"
Reversible means if it fails, you can undo it. If you can't, it's not a test, it's a bet. No extensions: incomplete data at the deadline is still a decision point.
Lock (4 weeks)
This is where most protocols fail and most transformations die. Delete the old way. Don't deprecate it. Change defaults so the new path is easier than reversion. Measure until the constraint moves somewhere new.
That's CUT.
Before you begin
Use it when:
- The same problems keep recurring despite "fixes"
- Decisions die in committee or get watered down
- Teams are busy but nothing ships
- Someone has authority to protect the process
Skip it when:
- The problem is genuinely novel: no one knows what good looks like. Explore first.
- No one in the room can actually make decisions. Fix that first.
- The constraint is already obvious and agreed. Jump straight to Test.
CUT is a forcing function, not a magic trick. It requires someone willing to name uncomfortable truths and someone with authority to act on them. If those aren't present, work on that first.
When it gets hard
The notification story was clean. The constraint was technical. No one's identity was threatened.
It's rarely that easy.
Constraints often live inside someone's territory. A system built by a senior engineer who's been there since the early days. A process designed by the VP. An org structure the CEO created. When Constraint Narrowing points there, expect resistance. Not because people are malicious, but because naming the constraint feels like an attack on their judgment.
At a 120-person company, the constraint pointed to org structure. Two teams with high dependencies operated on separate sprint schedules with no shared planning. The Head of Engineering rejected the finding. "The structure is fine. We just need better coordination."
I didn't argue. "What would prove that?"
He proposed a program manager to coordinate the teams. We tested it for four weeks. The program manager flagged blockers but couldn't resolve them as teams had different priorities and he had no authority. Handoff delays dropped from five days to four. Noise, not signal.
End of time-box. His hypothesis had failed. Now he was willing to test mine: merge the teams temporarily. Features that previously took 14 weeks shipped in 5.
Two moves help when politics block progress:
- Let them test their hypothesis first.
A failed experiment creates permission that argument never will. If they're right, you learn. If they're wrong, they learn and you move forward without a fight. - Get air cover before you start.
CUT requires someone with authority to say "we're doing this anyway" when the constraint points at a sacred cow. Without that, don't begin.
CUT doesn't solve politics. It surfaces them faster. That's still progress.
Your move
You already know what's broken. You've known for months.
Pick one constraint. Block two hours Monday morning. Run Constrain. The protocol is here.
If the constraint points at politics, sacred cows, or territory no one wants to touch; that's when an outside voice cuts through faster. Book a call and we'll find the real bottleneck together.