Create technical strategies and roadmaps that align engineering investment with business outcomes. Covers strategy formulation, roadmap formats, balancing innovation with maintenance, communicating technical investment to non-technical stakeholders, and avoiding the roadmap theater trap.
Engineering leaders use technical strategy and roadmapping to align teams around long-term engineering goals, translate business ambition into execution plans, and ensure that investments in technology deliver value over time. This page is a guide to doing it well—practically, consistently, and with precision across engineering organisations of any size. It matters when a company is growing fast, entering new markets, shifting from product-led to platform-led engineering, or when technical debt has begun to slow innovation. It is the compass for quarterly and annual planning, the foundation of cross-team coordination, and the backbone of engineering capacity decisions.
Technical strategy begins with a clear articulation of *why* the engineering organisation exists beyond shipping features. The goal is to answer: What are we building, why now, and how will we know we succeeded?
The strategy must span three horizons:
To define these horizons, leaders draft a *strategic statement* using a standard template:
## Vision
We are building a resilient, scalable, and extensible platform that empowers teams to deliver value to customers at pace.
## Guiding Principles
- Platform-first: Every service is a first-class citizen in the platform.
- Observability by default: All systems emit structured logs, metrics, and traces.
- Autonomous teams: Teams own end-to-end delivery of their services.
- Incremental innovation: We ship small, frequent improvements to production.
## Strategic Objectives (2025)
1. Reduce mean time to recovery (MTTR) from 4 hours to 1 hour by Q3 2025.
2. Achieve 99.9% uptime for core APIs across all regions.
3. Enable self-service deployment for 80% of services.
4. Migrate 70% of monolith services to event-driven microservices.
## Key Initiatives (2025–2026)
- Build internal developer portal (IDP) with API discovery, documentation, and onboarding.
- Launch unified logging and tracing pipeline using OpenTelemetry.
- Implement platform-wide service mesh with traffic splitting and canary rollout.
- Establish a cross-team observability guild to define standards and tools.
This document is not a static artifact. It lives in version control, with a strategy/ directory in the engineering repository, and is reviewed quarterly. A strategy/README.md links to all active initiatives, with each initiative in its own strategy/2025-01-01-initiative-id/ directory.
A roadmap is the operational translation of strategy. It connects strategic objectives to concrete work. The roadmap must answer: What will we build, when, and how will we measure progress?
Each initiative is represented as a roadmap.json file in its directory, with the following structure:
{
"id": "idp-2025",
"title": "Internal Developer Portal",
"description": "A self-service platform for onboarding, discovering, and using services.",
"start": "2025-01-01",
"end": "2025-09-30",
"owner": "[email protected]",
"status": "in-progress",
"dependencies": [
"observability-2025",
"service-mesh-2025"
],
"milestones": [
{
"title": "Discovery Phase",
"due": "2025-02-15",
"status": "done",
"description": "User research, stakeholder interviews, and prototype validation."
},
{
"title": "Design and API Specification",
"due": "2025-04-30",
"status": "in-progress",
"description": "Finalized UI design, API contracts, and user journey maps."
},
{
"title": "First Release (v1.0)",
"due": "2025-07-15",
"status": "planned",
"description": "Core search, service catalog, and onboarding wizard."
}
],
"metrics": [
{
"name": "Time to onboard a new developer",
"target": "≤3 days",
"baseline": "7 days",
"unit": "days",
"source": "survey, onboarding logs"
},
{
"name": "Percentage of services documented in IDP",
"target": "≥80%",
"baseline": "40%",
"unit": "%",
"source": "IDP analytics"
}
]
}
The roadmap is maintained using a simple workflow:
git add strategy/2025-01-01-initiative-xyz/ and commit with git commit -m "Add IDP initiative".scripts/refresh-roadmap.sh, which:roadmap.json files into a single roadmap.json at the root.npx markdown-to-html --input strategy/roadmap.md --output public/roadmap.html.git add public/roadmap.html && git commit -m "Update roadmap view".The refresh-roadmap.sh script uses standard tools:
#!/bin/bash
# scripts/refresh-roadmap.sh
set -euo pipefail
# Collect all roadmap.json files
cat <<EOF > roadmap.json
{
"title": "Engineering Roadmap 2025",
"updated": "$(date -Iseconds)",
"initiatives": [
EOF
find strategy/ -name "roadmap.json" -exec cat {} + | jq -s '. | add' >> roadmap.json
# Append closing bracket and format
echo " ]" >> roadmap.json
echo "}" >> roadmap.json
# Generate HTML
npx markdown-to-html \
--input strategy/roadmap.md \
--output public/roadmap.html \
--title "Engineering Roadmap 2025"
# Copy to web server
cp public/roadmap.html /var/www/html/roadmap.html
status values: planned, in-progress, reviewing, done, reviewed, live.reviewed state before marking an initiative as done, with a checklist:A roadmap is only effective when it guides team capacity and investment. The alignment process begins with a *capacity planning session*.
Each team provides a capacity.json file:
{
"team": "platform",
"period": "2025-Q1",
"total-person-days": 140,
"allocated": [
{
"initiative": "idp-2025",
"person-days": 40,
"owner": "[email protected]",
"priority": "high"
},
{
"initiative": "observability-2025",
"person-days": 35,
"owner": "[email protected]",
"priority": "medium"
},
{
"initiative": "service-mesh-2025",
"person-days": 25,
"owner": "[email protected]",
"priority": "high"
}
],
"available": 40,
"unallocated": 40,
"notes": "Team is onboarding 3 new engineers in April."
}
A central capacity.yaml file aggregates these:
capacity:
period: 2025-Q1
teams:
- name: platform
total: 140
allocated: 100
available: 40
initiatives:
- id: idp-2025
days: 40
owner: [email protected]
- id: service-mesh-2025
days: 25
owner: [email protected]
- name: observability
total: 100
allocated: 35
available: 65
initiatives:
- id: observability-2025
days: 35
owner: [email protected]
summary:
total_capacity: 240
total_allocated: 135
available_capacity: 105
utilization_rate: 0.56
The capacity.yaml is validated using scripts/validate-capacity.py, which checks:
id and owner.import json
import yaml
def validate_capacity(path):
with open(path, 'r') as f:
data = yaml.safe_load(f)
total_capacity = sum(t['total'] for t in data['teams'])
total_allocated = sum(t['allocated'] for t in data['teams'])
if total_capacity < total_allocated:
raise ValueError(f"Over-allocated: {total_allocated} allocated, {total_capacity} capacity")
allocated_ids = set()
for team in data['teams']:
for i in team['initiatives']:
if i['id'] in allocated_ids:
raise ValueError(f"Duplicate initiative ID: {i['id']}")
allocated_ids.add(i['id'])
return data
When capacity is constrained, leaders must decide which initiatives to prioritize. The process:
The outcome is a *priority list* used in planning meetings. The most common failure is treating all initiatives as equally important, leading to under-investment in high-value work.
A strategy without measurement is a plan without feedback. Each strategic objective must have a defined *indicator* and *signal*.
For example, the objective “Reduce MTTR from 4 hours to 1 hour by Q3 2025” implies:
The signal is generated by a daily generate-metrics.sh script:
#!/bin/bash
# scripts/generate-metrics.sh
set -euo pipefail
# Fetch incidents from database
psql -c "
SELECT
service,
avg(extract(epoch from (resolved_at - created_at))) as mttr_seconds
FROM incidents
WHERE created_at >= current_date - interval '30 days'
GROUP BY service
ORDER BY mttr_seconds DESC
" > metrics/mttr.json
# Compute monthly averages
psql -c "
SELECT
date_trunc('month', created_at) as month,
avg(extract(epoch from (resolved_at - created_at))) as avg_mttr_seconds
FROM incidents
WHERE created_at >= current_date - interval '1 year'
GROUP BY month
ORDER BY month
" > metrics/mttr-monthly.json
This output is ingested by a monitoring tool (e.g., Grafana, Prometheus, or a custom dashboard) and presented in a monthly engineering review.
The most common failure is *signal drift*: the metric is collected but not interpreted. Teams stop reviewing the dashboard, and the signal becomes stale. To combat this:
When a signal exceeds its threshold, it triggers a *strategy review*:
This creates a feedback loop: strategy informs execution, execution generates data, and data shapes future strategy.
Finally, the roadmap must answer *what* to build. The decision process uses a simple model:
decision-records/ with a standard template.A strategic decision is recorded as a decision.md file in the decision-records/ directory:
# DR-2025-04-15: Choose Platform for Developer Portal
## Status
- Draft → Review → Final
## Context
- Platform team needs to build a developer portal.
- Current options: self-built, using Retool, or using OutSystems.
- Team has 12 months and 4 engineers to deliver.
## Options
1. Build from scratch with React and Node.js.
2. Use Retool with custom components.
3. Use OutSystems with low-code workflows.
## Evaluation
| Metric | Option 1 | Option 2 | Option 3 |
|----------------------|----------|----------|----------|
| Development speed | 3 | 5 | 4 |
| Maintenance cost | 4 | 2 | 3 |
| Integration complexity | 3 | 4 | 5 |
| Team familiarity | 4 | 3 | 2 |
## Decision
- Choose Option 2: Use Retool.
- Rationale: Best balance of speed and maintainability, with existing team expertise.
## Consequences
- Shorter time to first release.
- Higher onboarding cost for new team members.
- Increased technical debt in Retool-specific logic.
This pattern—standardised decision records—ensures that strategic choices are visible, traceable, and revisitable.
Technical strategy and roadmapping are not one-time activities. They are continuous practices that shape how engineering teams work. The core patterns are:
These practices, when applied rigorously, ensure that engineering leaders do not just plan—but lead.
This page was rewritten on 17 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.
We use cookies for analytics (Google Analytics) and advertising (Google AdSense) to improve your experience and support free content. Privacy Policy