Golden Paths, Part 2: The Second and Third Path

TL;DR - The first golden path is an adoption project; the second and third are a portfolio problem, and the dangers invert. You stop worrying that nobody will come and start drowning because everyone did. The rules that got the first road shipped will sink the second: saying yes to every request produces paved-road sprawl, forking the template per team produces ten half-roads instead of three excellent ones, and every path you ship is a product you maintain forever. The second path should reuse most of the first one’s guts, the long tail of requests gets the escape hatch rather than a road, and you keep a boring list of what exists. Success at path one buys you demand. What you do with that demand decides whether you end up with a platform or a junkyard of templates.

When I wrote about building your first golden path, I ended on a deliberate cliffhanger: everything else - the portal, the catalogue, the second and third paths - is downstream of getting the first one right. This is the downstream post.

Here’s the situation it’s written for. Your first paved road works. A team shipped a service through it in a day, told the story in standup, and now your Slack has a queue: “can we get one of these for background workers?”, “our team is on Java, when’s the Java version?”, “we need the same thing but with a slightly different pipeline”. Congratulations - you have demand. Also, condolences: every one of those messages is a fork in the road, and most of the forks lead somewhere bad.

Paved-road sprawl versus a deliberate portfolio

The problem inverts after path one

The first path had exactly one failure mode: nobody uses it. Everything I wrote in part one - the design partner, the hours-not-sprints friction fixes, the time-to-first-deploy story - was about beating that.

The second path onwards has the opposite failure mode: everyone wants one, and you build too many. The platform team that fought for a year to be taken seriously suddenly finds that saying yes is the path of least resistance. Every yes feels like adoption. Every new template feels like progress. And eighteen months later you’re operating eleven templates, four pipelines, three “temporary” variants that became permanent, and a backlog of upgrade work nobody scheduled - the exact ticket-driven bottleneck platform engineering was supposed to kill, rebuilt one enthusiastic yes at a time.

So the discipline changes. Path one was sales. Paths two and three are product management, and the hardest part of product management is the roadmap you refuse.

The second path is mostly the first path

Before deciding what to pave next, lock in how. The most important property of your second golden path is that it isn’t a second platform.

When you built the first path, you built two things without necessarily noticing: the path itself (the “new service” template) and the foundations under it - the default pipeline, the observability wiring, the secrets integration, the base images, the deploy mechanism. Those foundations are not “the service path”. They are platform primitives, and the second path should be a thin layer over the same primitives.

Concretely, if path one was “create a new service” and path two is “create a background worker”, the delta is genuinely small: no ingress, a queue consumer instead of an HTTP handler, a liveness check that means something for a worker, different default resource requests. Everything else - CI, deploy, secrets, the metrics and logs wired in from commit one - should be literally the same components, consumed the same way.

This gives you a test I’d apply to every proposed path:

  • If the new path reuses most of the first one’s guts, it’s cheap to build, cheap to maintain, and consistent to use. Build it.
  • If the new path needs its own pipeline, its own observability story, and its own deploy mechanism, you are not building a second road. You’re building a second platform, and you should stop and ask why the primitives don’t fit. Sometimes the answer is legitimate (a data pipeline genuinely isn’t a web service). Usually the answer is that someone wants their preferences institutionalised.

There’s a compounding benefit to the reuse rule that’s easy to miss: it means improving a primitive improves every path at once. Fix the pipeline’s flaky cache step and the service path, the worker path, and the cron path all get better in the same afternoon. That’s the leverage that makes a three-person platform team serve fifty engineers. Fork the primitives per path and the leverage is gone - you’re back to linear scaling, a service desk with extra templates.

The paving bar: what earns a road

Path one’s selection criteria - high-frequency, high-pain, low-controversy - still apply, but now they need teeth, because now there’s a queue of candidates and each one arrives with an internal sponsor attached.

My bar for paving path N:

  1. It has to be a workload class, not a team’s preference. “Background workers” is a workload class; a dozen teams will create one this year. “Our team’s flavour of the service template” is a preference. Classes get roads. Preferences get, at most, an option on an existing road.
  2. It has to be recurring, with evidence. Same standard as part one: tickets, repeated Slack threads, the copy-paste trail from old repos. If a thing gets created twice a year, the path will rot between uses - the README goes stale, the pinned versions age, and the third user inherits a road with potholes. Rare things are better served by a good escape hatch and an hour of your time.
  3. The org has to have converged already. A golden path encodes an opinion the org mostly shares. If half the company writes workers in Python and half in Go and the argument is live, paving one side isn’t a golden path, it’s a land grab with a template attached. Let the argument settle first, or you’ll spend the path’s whole credibility on it. This was the “low-controversy” rule in part one; at path three it becomes the rule people try hardest to bend.
  4. You have to be able to afford it forever. This is the one everyone skips, so it gets its own section below.

Everything that fails the bar gets one of two honest answers instead of a road. Either an option on an existing path - the service template grows a flag, not a fork - or the escape hatch: the documented, supported way to go off-road. The escape hatch is not a consolation prize. For the long tail of genuinely unusual workloads it’s the correct product, and a platform team that would rather build a fourth road than polish the off-road documentation has confused output with service.

And write the “no” down. A one-paragraph note - “we’re not paving X because it fails the frequency bar; here’s the escape hatch; here’s what would change our mind” - costs ten minutes and saves you re-litigating the same request every quarter. It’s the same move as an architecture decision record, applied to the platform’s roadmap.

Sprawl is how platforms die politely

Nobody decides to build a sprawling platform. It happens one reasonable-sounding fork at a time, and each fork has a champion who is right about their own case and wrong about the portfolio.

The mechanics are worth naming, because you’ll recognise them in the room:

  • The variant that’s “just this once”. A team needs the service path minus one opinion - a different base image, a custom deploy step. Cloning the template takes an hour; adding a supported option takes a week of design. So someone clones it. Now there are two templates that were identical on the day of the fork and will never be identical again. Every primitive improvement now has to land twice, and in a year it lands once, in whichever copy the platform team remembers.
  • The path built for the demo. A stakeholder asks “do we have a path for ML jobs?” and it’s easier to scaffold one than to say “no, and here’s why”. The scaffold enters the catalogue looking exactly as done as the real paths - and the gap between looks-done and is-used is the same one that kills dashboard-first metrics programmes. A half-paved road is worse than no road: developers can’t tell it’s half-paved until they’re standing in the pothole, and the trust they lose belongs to all your roads, not just that one.
  • The zombie path. Path two was for a workload the org has since moved away from. Nobody uses it; nobody decommissions it, because decommissioning feels like admitting a mistake. It sits in the template list, aging, waiting to be found by exactly the wrong person: the new engineer who can’t tell which roads are load-bearing.

The countermeasure to all three is the same: treat the number of paths as a cost, not a KPI. Three roads that are genuinely paved - current, supported, upgraded, trusted - beat ten roads in various states of gravel every single time. When I audit a platform, the path count versus the platform team’s headcount tells me most of what I need to know before I’ve opened a single repo. Keep the portfolio boring and small on purpose - the boring-stack argument applies to the platform’s own product line, not just its components.

Every path is a maintenance contract

The part one framing was that a golden path is supported - when it breaks, it’s the platform’s bug. At one path, that’s a rounding error on your time. At three paths, it’s a standing line item, and you need to plan it like one.

Two costs dominate, and neither shows up in the “build the template” estimate:

  • The path itself drifts. Pinned dependencies age, the base image gets CVEs, the CI system deprecates a feature, your own opinions improve. A template untouched for a year is a machine for stamping out year-old mistakes. Budget real, recurring time per path - and if that budget frightens you, that’s the paving bar working as intended.
  • The instances drift from the path. Harder and more interesting: forty services were stamped from the template over two years, and they’ve all diverged - from the template and from each other. When you improve the path, how does the improvement reach them? If the honest answer is “it doesn’t, only new services benefit”, say so out loud and accept that your fleet’s consistency has a half-life. The better answer is to move as much as possible out of the template and into the primitives behind it - a shared pipeline definition, a base image, a library - where an upgrade lands on everyone without a migration. The less a path copies into each repo, the less there is to drift.

A rule of thumb I stand behind: don’t start path three while path one has an unstaffed maintenance backlog. New roads are more fun than resurfacing old ones, which is exactly why the discipline has to be explicit.

Keep the index boring

Somewhere around the second or third path, discovery becomes a real question - “what paths exist, which one do I want, who owns them?” - and you’ll feel the pull to answer it with a portal.

Resist it a little longer. I’ve written a whole post on when a developer portal is earned and when it’s a trap, so here I’ll keep it to one paragraph: at two to four paths, the index is a markdown page. Name, one-line description, what it’s for, what it’s not for, owner, escape hatch. Ten minutes to write, trivial to keep true, and it does one job the portal can’t do better at this scale: it shows the honest, small size of your portfolio without a UI implying otherwise. The portal is the index of your paved roads, and at three roads an index is a list.

When the second path is the wrong answer

The off-ramps, honestly:

  • Path one hasn’t proven itself yet. My test: a second team adopted it without you in the room, and the path survived contact. Until then, the first path is still the project. Building path two on an unvalidated path one is scaling a guess.
  • The demand is variants, not paths. If every request in your queue is “path one, but slightly different”, the product signal isn’t “build more paths”. It’s “path one’s opinions are too tight in one specific place”. Add the option, keep the road singular.
  • The demand is one team’s, once. A single team with a genuinely unusual need doesn’t need a road; roads are for routes many people travel. They need the escape hatch plus your help for a week - facilitating, not platform-building - and then they need you to leave.
  • You’re still a small org. The same threshold from part one holds. If the whole engineering team fits in one room, a second golden path is a solution ahead of its scale; a shared opinion and a good README still win.

The bottom line

The first golden path teaches your org that paved roads work. The second and third teach your platform team what it is: not a template factory, but the owner of a small, deliberate, ruthlessly maintained portfolio. Reuse the primitives so every path shares the same guts. Hold the paving bar - workload classes, recurring with evidence, converged opinions, staffed forever. Give the long tail a great escape hatch instead of a gravel road. Keep the index a boring list until it buckles. And count your paths the way you’d count anything else you have to keep alive: as a cost that has to keep earning its place.

Success at path one buys you demand. Spend it slowly.

If your platform’s template list is growing faster than your team’s ability to keep it paved, or you’re staring at a queue of path requests and can’t tell the roads from the preferences, let’s talk.