A practical framework for delivering technical and behavioral feedback that drives change. Covers the SBI model, timing, peer feedback, performance reviews, and how to have the conversations that most managers avoid.
Engineers receive feedback constantly—code reviews, 1:1s, post-mortems, architecture reviews—but much of it fades into silence. Feedback that lands is rare. This page details how to give feedback that engineers *actually hear*, meaning they understand, act on, and remember it. It applies when you’re mentoring a junior engineer, reviewing a pull request, or leading a team-wide retrospective. The goal is not just to deliver feedback but to ensure it sticks.
Feedback is effective when the recipient can answer: *What should I change? Why does it matter? How do I start?* The process begins with clarity and ends with action. The most common failure is feedback that arrives as a list of comments, but vanishes into email or Slack. The engineer reads it once, nods, and forgets. To fix this, focus on three phases: *preparation, delivery, and follow-through*.
Before sending a comment, ensure it is specific, actionable, and tied to context.
For example, instead of “Consider error handling,” write:
> In src/api/user.service.ts, the getUserById function returns null on failure but does not log or propagate the error. Add a logger.error call before return null, and consider re-throwing the error after logging. This will help catch missing users during onboarding.
This version includes:
Feedback is not one-size-fits-all. Match the medium to the depth and urgency of the message.
| Medium | Best for |
|---|---|
| GitHub PR comment | Code-level feedback, with links to files, lines, and builds |
| Slack message | Quick, contextual, collaborative feedback |
| Detailed, multi-part feedback with references, history, and expectations | |
| In-person 1:1 | Deep, reflective feedback on growth, behavior, or project direction |
For code reviews, use GitHub-style PR comments with inline code suggestions. When commenting on a file, use the native file diff view to pin feedback directly to code. Clicking a comment should jump to the line, and the comment should show the surrounding code context.
When reviewing a complex change, add a summary comment at the top of the PR with:
Example:
## Summary: Add user session persistence via Redis
This PR adds Redis-backed session storage to the API service. Sessions are now persisted across server restarts and scaled horizontally.
✅ Implemented session middleware with Redis integration
✅ Added session cleanup task (runs every 5 minutes)
✅ Added `session:ttl` config key in `config/app.json`
✅ Tests pass in CI (see logs)
### Checklist
- [x] All tests pass
- [x] Documentation updated
- [ ] Performance benchmarks added
- [ ] Monitoring alerts configured
### Related
- #142: Session lifetime requirements
- docs/session-handling.md
This structure gives the reader immediate context and a clear path forward.
Feedback that sticks must be scorable and repeatable. Use a consistent format so engineers can internalize it.
A proven structure is the "What, Why, How" format:
> What: What change is needed? > Why: Why does it matter? > How: How should it be implemented?
Example:
> What: Move config/app.json to config/*.json and use environment-specific overrides. > Why: Currently, app.json is duplicated across environments, leading to configuration drift. With this change, we can have config/development.json, config/production.json, and config/staging.json, each overriding the base. > How: Use fs.readJsonSync('config/app.json') to load base config, then merge in config/${env}.json using deepmerge. Add NODE_ENV check in server.js.
This format makes feedback self-contained. The engineer can act on it without additional conversation.
Feedback without evidence is opinion. To make feedback credible, include logs, traces, and real data.
When reviewing a performance issue, include a trace of a request from a monitoring tool. For example:
{
"traceId": "a5c3b1d2-8e4f-9a7b-1c6d-2e8f3a4b5c6d",
"spans": [
{
"name": "GET /api/users",
"duration": 124,
"startTime": 1450,
"tags": {
"http.method": "GET",
"http.status_code": 200,
"user.id": "1234",
"db.query.count": 3
},
"logs": [
{
"timestamp": 1500,
"message": "Querying users from DB"
},
{
"timestamp": 1580,
"message": "Fetching user profiles (3 queries)"
}
]
}
]
}
In the feedback, link to the trace and write:
> The /api/users endpoint takes 124ms, but 60% of that time is spent fetching profiles. Consider caching user profiles in Redis, or batching the three profile queries into one. The trace shows three DB queries, each taking ~15ms, suggesting a bottleneck in the user profile service.
This connects the feedback directly to observable reality.
Feedback that is not followed up becomes noise. Set up triggers to ensure action.
feedback:awaiting-responsefeedback:reviewedfeedback:approvedfeedback:needs-implementationAfter sending feedback, assign the PR to the author and set a due date.
Use pull request templates to guide authors and reviewers. A standard template includes:
## Description
<!-- Describe the change in a few sentences -->
## Related Issues
<!-- Link to issues, tickets, or specs -->
## Implementation Notes
- [ ] Added tests
- [ ] Updated documentation
- [ ] Performance impact measured
- [ ] Configuration changes required
## Review Checklist
- [ ] Code style matches project standard
- [ ] All tests pass
- [ ] Documentation updated
- [ ] CI artifacts attached
This ensures reviewers don’t miss steps and authors know what to expect.
When feedback is given in a 1:1, record the session and share a summary within 48 hours. Use the same "What, Why, How" structure.
Example summary email:
> Subject: Follow-up: 1:1 on career growth — next steps > > What: You want to grow into a senior role over the next 6 months. > Why: You’ve shown strong technical depth but need more ownership and cross-team collaboration. > How: > - Lead one architecture review per quarter > - Mentor one junior engineer > - Write a decision record for a major design choice > - Share a talk at a team meetup > > Please update your career plan doc with these goals by Friday. I’ll check in at the next 1:1.
Even with good practices, feedback can silently fail. Recognize and act on common failure modes.
Failure Mode 1: Feedback is read but never acted on.
cron jobs or watch scripts.Example watch script to check for overdue feedback:
#!/bin/bash
# Run daily via cron
echo "Checking for overdue feedback..."
for pr in $(git log --since="7 days ago" --grep="feedback:" --format="%H"); do
pr_url=$(git log -1 --format="%B" $pr | grep "https://github.com" | head -n1)
pr_author=$(git log -1 --format="%an" $pr)
pr_title=$(git log -1 --format="%s" $pr)
# Check if feedback was given more than 5 days ago
feedback_date=$(git log -1 --format="%ad" --date=short $pr)
days_since_feedback=$(date -d "$feedback_date" +%s | awk -v today=$(date +%s) '{print (today - $1) / 86400}')
if (( $(echo "$days_since_feedback > 5" | bc -l) )); then
echo "Overdue feedback: $pr_title ($pr_url)"
echo "Author: $pr_author"
echo "Feedback given $feedback_date"
echo "Send reminder to $pr_author"
fi
done
Failure Mode 2: Feedback is misunderstood or misinterpreted.
Example:
> Before: > ``ts > function calculateTotal(items) { > let total = 0; > items.forEach(item => { > total += item.price * item.quantity; > }); > return total; > } > ` > > After: > `ts > function calculateTotal(items) { > const total = items.reduce((sum, item) => sum + (item.price * item.quantity), 0); > return total; > } > ` > > The reduce` version is more idiomatic and slightly faster. Use it in all price calculations.
Failure Mode 3: Feedback is ignored in favor of other priorities.
P0: critical, P1: important, P2: nice to have.Each feedback item includes:
new, in-progress, review, doneUse kubectl to query feedback status from a Kubernetes-based feedback tracker:
kubectl get feedbacks -o wide --show-labels
Example output:
NAME STATUS OWNER DUE DATE LABELS
user-auth-v2 in-progress jen 2024-08-15 priority=p1,area=auth
api-pagination done alex 2024-07-20 priority=p0,area=api
cache-strategy new maria 2024-09-01 priority=p2,area=performance
Feedback is not a one-off activity. Integrate it into routines.
Use a feedback log in a shared document. Each entry includes:
This creates a living record of team growth, decisions, and learning.
Feedback that engineers *actually hear* is not just delivered—it is anchored in context, structured for action, and followed up with care. It becomes part of how the team works, not just how it communicates.
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