A squad wants to ship a new service. They need a repo, a pipeline, a Postgres instance, a DNS record, a TLS cert, dashboards, alert routing, and an IAM role scoped tightly enough that security signs off. In a lot of organisations that takes three weeks and six tickets, and at the end the team owns a stack that resembles nothing the team next door built last month. Platform engineering is the discipline aimed squarely at those three weeks.
It is also the most over-sold phrase in infrastructure right now. Gartner's forecast that 80% of large software engineering organisations would have platform teams by 2026 — up from 45% in 2022 — has been quoted into meaninglessness, and plenty of those teams are the old ops group with a new name and a portal nobody opens. This guide covers what a platform actually contains, how to staff one, how to tell whether it is working, and the conditions under which you should not build one at all. That last part matters more than the rest.
The problem underneath the hype
Three distinct pains get bundled under one banner. They have different causes and different fixes, and conflating them is how platform programmes go wrong in month two.
Cognitive load has become the binding constraint
"You build it, you run it" was a correction to a real problem, and it worked. It also quietly transferred an enormous surface area onto product teams. A team shipping a checkout flow is now expected to hold Kubernetes scheduling semantics, Terraform state hygiene, IAM trust policies, OpenTelemetry pipelines, container image signing and at least one service mesh in working memory, on top of payment-domain logic. Cognitive load theory has a name for it: extraneous cognitive load, the mental cost imposed by the environment rather than by the problem. Team Topologies is what carried the term into how we talk about software teams. Beyond some point, adding another tool to a product team's plate subtracts capacity rather than adding it.
The control plane, node and pod model underneath a Kubernetes cluster is worth understanding in depth for the people operating clusters, and mostly noise for the six teams deploying onto them. A platform's job is deciding which details each audience has to carry.
The ops bottleneck
The second pain is queueing. A central infrastructure group becomes the only path to a production change, and every product team's lead time inherits that queue's depth. The symptom is easy to spot: ask how long it takes to get a new managed database provisioned, and if the honest answer includes the phrase "depends who picks it up", you have a queue, not a service.
Snowflakes
The third is variance. Ten teams building their own delivery stack produce ten stacks, each with its own idea of what a health check is, where secrets live, and whether rollbacks exist. Nobody can write a single runbook, and a CVE in a base image becomes ten independent remediation projects.

Platform as a product, not platform as a project
The single idea that separates platform teams that work from ones that don't: your developers are users, and they can refuse your product.
A project has a launch date and a scope document. A product has users whose behaviour you measure, a roadmap driven by what they actually do, and a failure condition called "nobody adopted it." That framing forces uncomfortable but correct decisions. You run real interviews with the teams you serve, not a survey. You track adoption per capability rather than per team. You accept that two services will stay off the paved road for good reasons. You write the documentation as part of the feature.
It also imposes a discipline most infrastructure groups have never practised: saying no. A platform that absorbs every request becomes a bespoke-work queue wearing a product's clothes. The counter-move is a published scope — these are the capabilities we support, this is the interface, here is what we explicitly do not do — and a visible path for teams who need something outside it.
Team Topologies calls the starting point the Thinnest Viable Platform: the smallest thing that genuinely reduces load on the teams you serve. Sometimes that is a well-maintained wiki page and two Terraform modules. Shipping that, and having it used, beats shipping a control plane nobody asked for.
What a platform concretely consists of
Strip out the vocabulary and a platform is five things. The order below is roughly the order you should build them.
Golden paths and service templates
A golden path is an opinionated, supported route from nothing to a running production service. It is not a mandate; it is the route so much easier than the alternative that teams take it voluntarily. In practice it starts as a scaffolder template generating a repo already wired for your conventions.
# backstage/templates/go-service/template.yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: go-http-service
title: Go HTTP service (paved road)
spec:
owner: group:platform
type: service
parameters:
- title: Service details
required: [name, owner, tier]
properties:
name: { type: string, pattern: '^[a-z][a-z0-9-]{2,29}$' }
owner: { type: string }
tier:
type: string
# tier drives SLO targets, alert routing and prod approval rules
enum: [tier-1, tier-2, tier-3]
steps:
- id: fetch
action: fetch:template
input:
url: ./skeleton # app code, Dockerfile, OTel config, a passing test
values: { name: '${{ parameters.name }}', tier: '${{ parameters.tier }}' }
- id: publish
action: publish:github
input:
repoUrl: github.com?owner=acme&repo=${{ parameters.name }}
protectDefaultBranch: true
- id: register
action: catalog:register # the service exists in the catalog from minute one
input:
repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }}
catalogInfoPath: /catalog-info.yaml
The hard part is not generating the repo. It is keeping hundreds of generated repos current as conventions change, which is why template updates need an automated propagation story (renovate-style PRs against every scaffolded repo) before you have fifty of them.
Self-service provisioning
The provisioning interface is where a platform stops being a collection of scripts. The pattern that has won is declarative: teams describe the environment they want in a file that lives beside their code, and a controller reconciles reality toward it.
# checked into the service repo; reconciled by the platform's GitOps controller
apiVersion: platform.acme.io/v1alpha1
kind: AppEnvironment
metadata:
name: payments-api-staging
spec:
tier: tier-1
runtime:
cpu: "500m"
memory: 1Gi
minReplicas: 2
dependencies:
postgres:
version: "16"
size: small # small/medium/large map to instance classes the platform owns
backupRetentionDays: 14
queue:
name: payments-events
network:
public: false # public: true additionally requires a WAF and a security review
Note what the abstraction hides and what it deliberately exposes. Instance classes, subnet layout, encryption settings and backup tooling are the platform's problem. Tier, size and public exposure are product decisions with cost and risk attached, so they stay visible. Get that line wrong in either direction and the platform either leaks complexity or hides decisions teams need to own. The account structure, network boundaries and guardrails underneath are ordinary production-grade cloud architecture decisions; the platform packages them, it does not replace them.
Paved-road CI/CD
Every service getting its own hand-rolled pipeline is the snowflake problem in its most expensive form. The fix is a small number of centrally owned, versioned pipeline definitions that repos call rather than copy.
# .github/workflows/ci.yaml in every paved-road repo
jobs:
build-test-deploy:
uses: acme/platform-workflows/.github/workflows/service-ci.yaml@v4
with:
service: payments-api
tier: tier-1
secrets: inherit # signing keys and registry creds stay in the platform org
Versioning the shared workflow (@v4) is what makes this survivable: you can ship breaking changes without breaking every repo the same afternoon. When deciding what belongs centrally versus in the service repo, walk the stages between a git commit and a production deploy and split on one rule — anything identical across services is the platform's, anything encoding domain knowledge is not.
Observability defaults
A service on the paved road should emit traces, structured logs and RED metrics without its team writing instrumentation code, and arrive with a default dashboard and an alert route derived from its tier. Best effort-to-gratitude ratio on this list, and consistently built too late.
The portal, last
An internal developer portal (Backstage being the reference implementation, a CNCF incubating project since March 2022) is a catalogue and a front door, and genuinely useful once there is something behind it. Built first, it is a directory of services nobody can act on, and the most common way platform programmes spend nine months producing nothing anyone uses.

When platform engineering is overhead, not leverage
Here is the position: below roughly 50 engineers, do not staff a dedicated platform team.
The arithmetic is unforgiving. A platform team that can carry on-call, survive one person leaving, and still do product work needs four to six people. At 30 engineers that is 15–20% of your entire capacity, permanently, serving 25 people who mostly know each other and can agree on conventions over a call. The coordination cost of introducing a team boundary — tickets, roadmaps, prioritisation meetings, the inevitable "the platform team is blocked on us" — exceeds the duplication it removes.
Below that line, you still want the artefacts. Two or three shared Terraform modules, one reusable CI workflow, a documented way to get a database, and a named part-time owner who keeps them alive will get you most of the benefit at a fraction of the cost. Call it a paved road with no team attached.
The threshold is a proxy, not a law. The real triggers are: six to eight independent stream-aligned teams, provisioning lead time that you have actually measured and found to be days rather than minutes, and at least one incident in the last quarter whose root cause was environment drift between teams. Two of those three, and it is time. Headcount alone is not. A 200-person organisation with one monolith and one deployment target does not need a platform team; a 60-person organisation with fourteen services in three clouds urgently does.
The honest counterweight: DORA's 2024 research found that organisations using an internal developer platform reported 8% higher individual productivity and 10% higher team performance, and 6% better organisational performance — while measured throughput fell 8% and change stability fell 14%. Platforms add a layer, and layers have a cost. DORA's 2025 work sharpened this into the claim that platform quality is what determines whether the investment pays back, including whether AI tooling adoption produces organisational gains at all. A mediocre platform is worse than no platform.

Team topology and sizing
Use the Team Topologies vocabulary here because it is precise. The platform team is one of four fundamental types, alongside stream-aligned, enabling and complicated-subsystem teams, and its defined relationship to stream-aligned teams is X-as-a-Service: you consume the interface, you do not collaborate on every change. Collaboration mode is for discovery and should be time-boxed; a platform team permanently in collaboration mode with its users is a staffing agency.
Sizing in practice: one platform team of five or six for the first 8–12 stream-aligned teams. Past roughly 25 consuming teams, split by capability, not by customer — one group owning the compute and delivery substrate, another owning developer-facing interfaces. Splitting by customer recreates the account-management model you were trying to escape.
Staff it with people who have shipped product, not only people who have run infrastructure. The most common composition failure is six excellent SREs and nobody who has ever run a user interview.
Measuring whether it is working
Adoption first, and voluntary adoption specifically. Percentage of services on the paved road, measured by a capability actually in use rather than by a catalogue entry, is the number that tells you whether you have a product. If adoption only rises when a VP sends an email, you have a mandate, not a platform.
Then lead time for the things the platform owns: new service to first production deploy, new database to connection string, new alert route to paging a human. Measure them as distributions, not averages; the p90 is where the pain lives.
Then DORA's five delivery metrics alongside a developer experience signal: a short recurring survey asking how much of the sprint went to work unrelated to the product. Delivery metrics without a satisfaction signal is how you miss a platform that is quietly making everyone miserable while the dashboards look fine.
What not to measure: tickets closed. It rewards the exact behaviour you are trying to eliminate.
Maturity stage | What typically exists | What to build next | What to resist |
|---|---|---|---|
Ad hoc | Shared wiki, a few copied Terraform modules, tribal knowledge | One versioned service template; one reusable CI workflow | Hiring a platform team; buying a portal |
Emerging | Golden path for the most common service shape, central pipeline definitions | Self-service provisioning for the top two or three dependencies | Expanding to every language and runtime at once |
Established | Declarative environment API, observability defaults, tiering | A portal over the catalogue; automated template upgrades across repos | Mandating migration of legacy services |
Scaled | Multiple platform capabilities with named owners, published SLOs | Cost attribution, multi-tenancy, deprecation process for old paths | Splitting the platform team by customer |
The CNCF's Platform Engineering Maturity Model is the formal version of this, scoring five aspects (investment, adoption, interfaces, operations, measurement) across four levels from provisional to optimising. Worth running once a year as a structured argument-starter.
Build, buy, or leave alone
Capability | Default choice | Why |
|---|---|---|
Service catalogue and portal | Buy or adopt open source | Undifferentiated; the value is in what you connect to it |
CI/CD execution | Buy | Runner fleets are a full-time job with no competitive upside |
Environment/resource API | Build thin, on existing primitives | This encodes your specific policies; nobody else can |
Secrets management | Buy | The failure mode is catastrophic and the market is mature |
Golden-path templates | Build | Pure local knowledge, cheap to build, expensive to outsource |
GPU and training infrastructure | Usually separate | ML workloads have a different resource and scheduling profile and rarely fit the same paved road |
How platform teams fail
The platform nobody adopts. Built from assumptions rather than interviews, solving the problem the platform team found interesting. The tell is an adoption number that plateaus at the two teams who were in the room during design. The fix is embarrassing and effective: go and pair with a product team for a week, watch where they get stuck, build that.
The mandated platform. Leadership declares migration compulsory, adoption hits 100%, and the only signal that mattered (would teams choose this?) is gone for good. Mandates are sometimes necessary for compliance capabilities like secrets handling or image provenance. Using one to rescue a product people are avoiding converts a fixable adoption problem into a permanent trust problem.
The ticket queue with a product name. The org chart changed; the interaction model did not. Requests arrive as tickets, the team triages, nothing becomes self-service because there is never slack to build it. This is the most common outcome by a wide margin. The only exit is to ring-fence capacity — a fixed share of each iteration spent turning the most frequent request type into something teams can do themselves — and to publish a wait time for everything else so the cost of the queue is visible to the people funding it.
Rebuilding Heroku, badly. The ambition creeps from "paved road for our services" to "general-purpose abstraction over all infrastructure." Heroku took years and a lot of money, and your version has four engineers and a deadline. The symptom is a platform API that has grown a field for every underlying cloud setting, at which point it is a worse YAML dialect for Terraform. Keep the abstraction narrow, keep an escape hatch, and let teams with genuinely unusual needs drop to the primitives without shame.
Where to start on Monday
Pick the single most frequent request your infrastructure group receives. Count how many times it came in last quarter and what the p90 turnaround was. If that number is large and the request is boring, that is your first golden path — build a self-service route for exactly that, ship it to two willing teams, and measure whether they use it again without being asked.
If the number is small, or the requests are all different from one another, you do not have a platform problem yet. You have an automation problem, and a couple of well-maintained modules plus a documented convention will serve you better than a team, a roadmap and a portal. Revisit when you cross six stream-aligned teams or the first drift-caused incident, whichever comes first. More context and further reading lives in our platform engineering coverage.







