Prioritizing Features vs Platform Work in Go
Product roadmaps highlight customer features.
Go platforms need module upgrades, linter baselines, observability, and reliability work that customers never click.
Tech leads negotiate a portfolio where both ship - or stakeholders consciously accept the cost of deferral.
Summary
Frame platform items as risk reduction and velocity investments with dates and owners.
Use cost-of-delay: what happens if Go 1.26 or a CVE fix waits another quarter.
Allocate explicit capacity (percentage or engineers), not leftover nights and weekends.
Pair every deferred platform item with a named risk on the register.
Review the balance monthly with product and engineering leadership.
Recipe
Roadmap row template for a quarterly review.
| Initiative | Type | Customer visible? | Risk if deferred 90d | Capacity | Decision |
|------------|------|-------------------|----------------------|----------|----------|
| Invoice export API | Feature | Yes - renewal | Medium revenue | 2 eng x 3 wk | Ship Jul |
| Go 1.26 monorepo bump | Platform | No | High - CVE + GC drift | 1 eng x 2 wk | Ship Aug wk1 |
| golangci-lint v2 baseline | Platform | No | Medium - review drag | 0.5 eng x 2 wk | Ship Sep |
| gRPC retry middleware | Platform | Indirect (fewer 5xx) | Medium - incident repeat | Bundled w/ export | Ship Jul |When to reach for this:
- Quarterly planning with mixed feature and platform backlogs
- Post-incident requests for "more reliability"
- Security mandates on
govulncheckfindings - Monorepo toolchain drift across services
Working Example
Negotiation brief for deferring a feature to land a module upgrade window.
## Decision brief: Aug platform week
**Context:** Security requires Go 1.26.1 by Aug 15. Export API targets Aug 1.
**Options:**
1. **Parallel (recommended):** 1 platform engineer on upgrade; feature team unchanged.
- Export slips 0 days; upgrade completes Aug 12.
2. **Serialize:** Feature first, upgrade Aug 15-30.
- Export on time; CVE exception request required; overtime risk.
3. **Defer upgrade:** Feature on time; accept audit exception + unknown incident risk.
**Recommendation:** Option 1 - hire/loan 1 platform engineer from infra for 10d.
**Ask:** Product approves infra loan; EM confirms staffing by Fri.// Platform work still ships customer-visible metrics when framed right.
// Example: export platform upgrade health to dashboard product can see.
var platformUpgradeReady = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "go_toolchain_upgrade_ready",
Help: "1 when all modules on target Go version",
})What this demonstrates:
- Options ranked with dates and compliance impact
- Parallel track avoids false feature-vs-platform dichotomy
- Metrics can make platform progress visible without customer UI
Deep Dive
How It Works
Feature vs platform definitions
| Type | Examples | Value narrative |
|---|---|---|
| Feature | New API, UI workflow | Direct revenue, retention |
| Platform | Go bump, shared auth lib, CI speed | Risk down, velocity up |
| Reliability | Retries, circuit breakers, SLO fixes | Fewer incidents, trust |
Cost-of-delay prompts
| Deferred item | Typical cost |
|---|---|
| Go minor upgrade | CVE exceptions, harder future jumps |
govulncheck fixes | Audit findings, incident exploit window |
| Lint baseline | Slower review, inconsistent style debt |
| Observability gaps | Longer MTTR, blind launches |
| Module unmaintained | Sudden replace directive fire drill |
Capacity models
| Model | When it works |
|---|---|
| 70/30 feature/platform split | Mature product with SRE partnership |
| Dedicated platform team | 10+ Go services, shared libs |
| Rotation ("platform week") | Small teams, quarterly hygiene |
| Ticket tax (10% every sprint) | Continuous small upgrades |
Negotiation Scripts
For product: "This upgrade is not polish. It closes a CVE window and keeps export work unblocked on supported stdlib APIs."
For executives: "Deferring saves 10 engineer-days now; costs 30+ if we miss the audit date and freeze releases."
For engineers: "We are not asking to stop features. We need one engineer for two weeks with a named done condition."
Gotchas
- Invisible platform work - No roadmap row means surprise deferrals. Fix: Platform epics with same visibility as features.
- Heroic weekends - Teaches org that platform is free. Fix: Capacity line or explicit deferral risk acceptance.
- Vague "tech debt" - Product tunes out. Fix: Tie items to CVE, MTTR, or cycle time metrics.
- All-or-nothing upgrades - Big-bang terrifies product. Fix: Phase by module group with incremental value.
- No done definition - Platform work expands forever. Fix: Exit criteria: all modules on 1.26, CI green, canary stable 48h.
- Ignoring dependencies - Feature needs new auth lib version platform has not shipped. Fix: Dependency graph in planning doc.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Feature-only quarters | Short survival crunch | Post-incident without root-cause platform fix |
| Platform-only freeze | Major migration (language) | Competitive feature window |
| OKR-linked platform | Exec team buys risk KPIs | No observability to measure |
| SRE-owned platform | Clear production ownership | Greenfield pre-production |
FAQs
What ratio of platform to feature is right?
No universal ratio.
Track incident MTTR, upgrade lag, and review time; adjust quarterly.
How do I justify golangci-lint upgrades?
Cite review hours saved and bugs caught by new linters with one example from your repo.
Should product own platform items?
Product shares prioritization; engineering owns technical urgency.
Joint OKRs on reliability work for customer-facing services.
What if security overrides the roadmap?
Treat as mandatory platform with communicated feature slip options.
Document executive decision.
How small teams survive
Use rotation: one engineer per sprint on platform tax; cap at 20% unless incident.
Can platform work be outsourced?
Upgrades and CVE fixes need org context.
Outsource spikes, not ownership of module graph.
How do I prevent platform team becoming bottleneck?
Publish self-service runbooks and release notes; office hours over gatekeeping.
What metrics convince executives?
Days since supported Go version, open critical CVEs, deploy frequency, change fail rate.
Should features fund platform?
Sometimes via tax on large epics (5% for shared lib updates).
Transparency prevents resentment.
When is deferral correct?
When cost-of-delay is low and risk register entry is accepted by named executive.
Related
- Estimating Go Work: Modules, Risk & Unknowns - sizing platform epics
- Release Notes for Internal Go Platform Changes - communicating platform ship
- Planning Go Version Upgrades Across a Monorepo - upgrade sequencing
- Tech Leads Bridge Engineering and the Business - stakeholder framing
Stack versions: This page was written for Go 1.26.x (Green Tea GC default, go fix modernizers - verify patch at build), chi (latest - verify at build), gin (latest - verify at build), echo (latest - verify at build), google.golang.org/grpc (latest - verify at build), sigs.k8s.io/controller-runtime (latest - verify at build), kubebuilder (latest - verify at build), tinygo (latest - verify board targets at build), wazero (latest - verify at build), and golangci-lint (latest - verify linter set at build).