Engineering Management
The engineering manager's actual job: people, delivery and technical judgement. Covers one-on-ones, feedback, delegation, team design, staying technical, and the failure modes that turn managers into bottlenecks.
Engineering Management is the practice of aligning technical execution with strategic outcomes through deliberate structure, clear accountability, and predictable processes. It matters when teams grow beyond a dozen engineers, when product complexity exceeds a single person’s mental model, and when delays in delivery become predictable sources of friction. It is not Agile, not Strategy, not Vendor management, but the glue that binds them—ensuring that engineering work is not just done, but *meaningful*.
Planning and Prioritization
The foundation of engineering management lies in how work is identified, shaped, and ordered. Work begins with a backlog, but not just any list: it is a living, prioritized artifact that evolves through continuous refinement. Every backlog item must have a clear *outcome*, not just a feature.
Each item is a JSON object stored in a database, with the following fields:
{
"id": "ENG-123",
"title": "Enable user onboarding via email confirmation",
"description": "Users receive a confirmation email after signup. Clicking the link verifies their email and redirects them to the dashboard.",
"status": "in-progress",
"priority": "high",
"estimated_effort": "3",
"accepted": true,
"created_at": "2025-03-15T10:00:00Z",
"updated_at": "2025-03-17T14:30:00Z",
"assignee": "[email protected]",
"acceptance_criteria": [
"User receives an email with a unique confirmation link",
"Link expires after 7 days",
"Clicking the link updates the user’s email_verified status",
"User is redirected to /dashboard after confirmation"
]
}
The priority field is not a label—it is an integer: 1 is highest, 5 lowest. It determines the order in which teams pick work. When a team pulls the next batch of work, they do so using a query:
SELECT id, title, estimated_effort, priority
FROM backlog_items
WHERE status = 'to-do'
ORDER BY priority ASC, created_at DESC
LIMIT 10;
The team then selects items for the next sprint, updating the status and assignee fields. A common failure is assuming that priority and estimated_effort are independent, but they are not. A high-priority item with a 5-point effort is often misunderstood as “urgent and complex,” but the team must explicitly track whether the effort estimate is accurate. When the team consistently underestimates effort, the backlog becomes a source of recurring delays.
Scheduling and Execution
Once work is committed, the schedule is managed through a shared calendar of milestones. Each milestone is a time-bound goal tied to a set of backlog items. The schedule is updated via a REST API:
PATCH /milestones/2025-q2 HTTP/1.1
Host: api.company.com
Authorization: Bearer abc123
Content-Type: application/json
{
"name": "Q2 2025: User Onboarding Launch",
"start_date": "2025-04-01",
"end_date": "2025-06-30",
"target_backlog_items": [
"ENG-123",
"ENG-124",
"ENG-125",
"ENG-126"
],
"status": "in-progress"
}
The team updates the milestone as work progresses. The status field is a string: "planned", "in-progress", "reviewing", "completed", "delayed". A milestone is considered "in-progress" when at least one item is assigned and the start date has passed.
The execution rhythm is driven by a recurring task run via systemctl:
systemctl enable --now schedule-check.timer
The timer triggers a script that queries the database:
#!/bin/bash
# /opt/engineering/schedule-check.sh
set -euo pipefail
# Fetch all milestones
curl -s -H "Authorization: Bearer $API_TOKEN" \
"https://api.company.com/milestones" \
| jq -r '
.[] | select(.status == "in-progress") |
select(.end_date | . <= (now | . + 86400 * 7)) |
.name + " due in less than a week: " + .target_backlog_items |
. | join("\n")
' > /var/log/schedule-check.log
# Send email if any milestone is near due date
if [ -s /var/log/schedule-check.log ]; then
mail -s "Upcoming Milestone Deadlines" [email protected] < /var/log/schedule-check.log
fi
This script runs daily and detects early warnings. The failure mode is subtle: a milestone is marked in-progress but no work has been done. The team assumes the milestone is active, but the start_date has passed and the status has not been updated. The script catches this gap.
Accountability and Work Tracking
Each engineer is accountable for a set of tasks, defined by their assignee field. When an engineer completes a task, they update the status and updated_at fields via a direct API call:
PUT /backlog_items/ENG-123 HTTP/1.1
Host: api.company.com
Authorization: Bearer $API_TOKEN
Content-Type: application/json
{
"status": "reviewing",
"updated_at": "2025-03-18T11:00:00Z"
}
The review process is not a single step. It requires a pull request, a code review, and a merge. The PR is tracked in Git. The main branch is protected, and the following conditions must be met before merging:
- All CI checks pass (tests, linter, build)
- At least one review from a peer engineer
- Changeset size ≤ 500 lines (measured via
git diff --shortstat)
A common error is failing to link the PR to the backlog item. The system does not enforce this, so engineers must remember to add a comment in the PR:
Fixes ENG-123
The system parses this text and updates the acceptance_criteria field to include a completed field:
{
"acceptance_criteria": [
{
"text": "User receives an email with a unique confirmation link",
"completed": true
},
{
"text": "Link expires after 7 days",
"completed": false
}
]
}
When all criteria are complete, the accepted field is set to true, and the item is considered done. The team then moves it to completed status and updates the milestone.
Onboarding and Role Definition
New engineers join with a defined onboarding path. The onboarding is tracked via a checklist stored in the onboarding table:
{
"employee_id": "alice",
"steps": [
{
"title": "Set up local development environment",
"completed": false,
"due_date": "2025-03-16"
},
{
"title": "Deploy first service to staging",
"completed": true,
"due_date": "2025-03-18"
},
{
"title": "Present a feature to the team",
"completed": false,
"due_date": "2025-04-15"
}
],
"completed_at": null
}
The onboarding process is not a one-time setup. Each step is a task that can be tracked independently. When all steps are completed, completed_at is set to the timestamp of the last update.
The role of an engineer is defined by a set of responsibilities, each with a clear outcome. These are not job descriptions, but executable expectations. For example:
- Frontend Engineer: "Deliver a responsive UI for the onboarding flow within 3 sprints."
- Backend Engineer: "Reduce average API latency from 250ms to 150ms across all user-facing endpoints."
These responsibilities are not abstract. They are tied to concrete metrics and checks. A frontend engineer is evaluated not on code quality alone, but on whether the onboarding flow meets performance and usability benchmarks. The team uses curl to test the flow:
curl -s -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64)" \
"https://app.company.com/onboarding" \
| grep -o "<title>Onboarding</title>" \
| wc -l
A failure occurs when the team assumes that “responsive” means “mobile-friendly,” but the actual test checks for load time, touch target size, and network resilience.
Leadership and Feedback
Engineering management is not only about systems—it is also about people. The team holds regular syncs, but the syncs are not generic meetings. They follow a strict agenda, defined in a shared document.
The agenda is a Markdown file stored in Git:
# Weekly Engineering Sync
## 1. Status Updates (15 min)
- Who is blocked?
- What is done since last sync?
## 2. Review of Open PRs (20 min)
- Pick 3 PRs to review in depth.
- Discuss trade-offs, review strategy.
## 3. Planning for Next Sprint (25 min)
- Review backlog.
- Select 10 items for next sprint.
- Assign items.
## 4. Feedback Round (10 min)
- Each person shares one piece of feedback.
- Feedback must include: what, why, and how to improve.
The sync begins with a command:
systemctl start --wait sync-meeting.service
The service runs a script that:
- Fetches the agenda from Git.
- Opens the agenda in a web browser.
- Starts a Zoom meeting.
- Logs the meeting in a database.
The feedback round is not a suggestion box. It is a structured exchange: each engineer speaks for up to three minutes. The feedback is recorded in a feedback table:
{
"id": "FB-45",
"submitted_by": "[email protected]",
"content": "The onboarding PR review process is too slow. We wait on multiple reviews, but no one tracks when reviews are due. We should add a due date to each review comment.",
"submitted_at": "2025-03-18T12:00:00Z",
"status": "pending",
"action_item": {
"title": "Add due dates to PR reviews",
"assignee": "[email protected]",
"due_date": "2025-04-05"
}
}
The action_item field is not optional. It becomes a new backlog item when the feedback is accepted. The team tracks action items in a separate view, and they are reviewed at every sync.
Failure Modes and Edge Cases
The most common failure is the silent divergence between the backlog and the actual work. An item is marked completed, but the milestone is not updated. The status field is outdated, and the team relies on memory rather than data. The system does not detect this, so a monthly audit is required.
Another failure is the misalignment between priority and effort. A priority: 1 item with estimated_effort: 8 is often treated as a high-priority, high-effort item, but the team does not adjust their sprint capacity accordingly. The result is a backlog that is always full, but never finished.
A subtle edge case: when a milestone is delayed, the team updates the end_date but forgets to update the status. The milestone remains in-progress even though it is late. The system detects this via a cron job:
# /etc/cron.daily/milestone-status-check
#!/bin/bash
while IFS= read -r -d '' milestone; do
id=$(echo "$milestone" | jq -r '.id')
end_date=$(echo "$milestone" | jq -r '.end_date')
now=$(date -I)
if [[ "$end_date" < "$now" ]] && [[ "$(echo "$milestone" | jq -r '.status')" == "in-progress" ]]; then
echo "Milestone $id is overdue: $end_date vs $now"
# Update status via API
curl -X PATCH \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"status": "delayed"}' \
"https://api.company.com/milestones/$id"
fi
done < <(pg_dump -t milestones | jq -c '.[]')
This script runs daily and updates the status of any overdue milestone. The failure mode: a milestone is delayed, but the team does not notice until the next sync.
The Unseen Mechanism
At the heart of engineering management is the connection between work, people, and outcomes. Every change to a backlog item triggers a chain of events: the status update may trigger a milestone update, which may trigger a feedback loop, which may lead to a new onboarding step, which may define a new role.
The mechanism is not centralized. It is distributed across simple tools: Git for version control, REST APIs for data exchange, SQL for querying, systemctl for automation, curl for integration. The pattern is consistent: a resource is identified by a URI, updated via PUT or PATCH, and monitored via logs and scripts.
The system works not because of tools, but because of the *mechanism*: a clear, repeatable flow from idea to outcome. When it breaks, it breaks in a predictable way: a status field is missing, a due date is ignored, a milestone is overdue but unmarked. The reader learns not just *how* to manage engineering, but *why* it works—and what happens when it fails.
This page was rewritten on 18 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.