- Published on
Mentoring Mid-Level Engineers — How to Help Them Cross the Senior Threshold
- Authors

- Name
- Sanjeev Sharma
- @webcoderspeed1
Introduction
The mid-level to senior transition is the hardest in an engineering career because the skill gap isn't primarily technical. Mid-level engineers can write good code. What they often struggle with is the expanded scope of ownership: considering how their change affects other systems, proactively communicating blockers and trade-offs, designing for maintainability rather than immediate correctness, and driving work to completion without being prompted. Effective mentoring maps the specific gap between where someone is and where they need to be, then creates deliberate practice opportunities to close it.
- What Mid-Level Engineers Typically Need to Develop
- Fix 1: Structured Growth Plan With Specific Behaviors
- Fix 2: Teach Through Review, Not Solutions
- Fix 3: Delegate With Clear Context, Not Just Tasks
- Fix 4: Career Conversations That Are Actually Useful
- Fix 5: The "I Do, We Do, You Do" Model
- Mentoring Checklist
- Conclusion
What Mid-Level Engineers Typically Need to Develop
Common gaps between mid-level and senior:
Technical ownership:
→ Mid: "My code works"
→ Senior: "My code is deployed, monitored, documented, and the on-call
engineer knows how to debug it"
System thinking:
→ Mid: Designs the solution for the requirement
→ Senior: Designs the solution AND considers failure modes, edge cases,
scale implications, and maintainability in 2 years
Communication:
→ Mid: Updates when asked
→ Senior: Proactively flags blockers, trade-offs, and scope changes
Ambiguity handling:
→ Mid: Asks for clarification on every ambiguous requirement
→ Senior: Makes reasonable assumptions explicit, proceeds, and verifies
Debugging approach:
→ Mid: Follows stack traces to fix the immediate error
→ Senior: Asks "why did this condition exist?" and fixes the root cause
Code review:
→ Mid: Checks correctness
→ Senior: Considers architecture, observability, error handling, and
the reviewer's ability to understand the change
Fix 1: Structured Growth Plan With Specific Behaviors
// growth-plan-template.ts
interface GrowthGoal {
behavior: string
currentState: string
targetState: string
practiceOpportunities: string[]
milestoneIndicator: string
}
const seniorGrowthPlan: GrowthGoal[] = [
{
behavior: 'System impact thinking',
currentState: 'Designs solutions that work for the immediate requirement',
targetState: 'Proactively identifies how changes affect adjacent systems before coding',
practiceOpportunities: [
'For the next 3 PRs: write a "this change affects..." comment before starting',
'Lead a design review for a medium-complexity feature',
'Review another engineer\'s design and identify 3 downstream considerations',
],
milestoneIndicator: 'Points out downstream impacts unprompted in design discussions',
},
{
behavior: 'Proactive communication',
currentState: 'Updates status when explicitly asked',
targetState: 'Sends daily async update on multi-day work, flags blockers same day',
practiceOpportunities: [
'On current project: send daily async update (Slack or GitHub comment) without being asked',
'Flag blockers within 2 hours of identifying them, not at end-of-day standups',
],
milestoneIndicator: 'Teammates and manager comment that they always know where things stand',
},
{
behavior: 'Full ownership of shipped features',
currentState: 'Considers work done when PR is merged',
targetState: 'Adds monitoring, documentation, and on-call runbook before marking done',
practiceOpportunities: [
'For the next feature: write the runbook before deploying',
'Add a CloudWatch alert for the feature you shipped last month',
'Update the team wiki with your system\'s operational documentation',
],
milestoneIndicator: 'On-call engineers can debug issues in their systems without asking',
},
]
Fix 2: Teach Through Review, Not Solutions
// When a mid-level engineer makes a mistake in code review,
// resist the urge to just fix it for them
// ❌ Ineffective mentor response:
// "This will cause N+1 queries. Change it to:
// const users = await User.findAll({ include: ['orders'] })"
// ✅ Effective mentor response:
// "What happens to this query when there are 1000 orders?
// Let's look at the SQL this generates together."
// → Engineer discovers the issue
// → Engineer researches eager loading
// → Engineer fixes it with understanding they'll retain
// Scaffolded questions instead of answers:
const mentoringQuestions = {
'performance issue': 'How many database queries does this code make per request? What happens at 10,000 users?',
'error handling': 'What happens if $service is unavailable? How does the caller know something went wrong?',
'observability': 'When this fails at 3 AM, what information will the on-call engineer need?',
'design review': 'What will this code look like if we need to change the business logic in 6 months?',
'testing': 'How do you know this works? What would need to be true for it to fail silently?',
}
// The goal: engineer asks themselves these questions without the mentor present
Fix 3: Delegate With Clear Context, Not Just Tasks
Ineffective delegation:
"Can you work on the rate limiting feature?"
→ Engineer builds a rate limiter but misses that it needs to be distributed,
didn't consider the UX for rate-limited users, doesn't know the scale requirement.
Effective delegation:
"I'd like you to lead the rate limiting feature. Here's the context:
- Business requirement: prevent abuse on the signup endpoint
- Scale: needs to work across 10 server instances (distributed)
- Users affected: 0.1% of users (only abusive requests)
- You'll need to handle the UX for rate-limited users (what message, retry info)
- Dependencies: Redis is available, existing middleware setup is in auth.ts
- Success criteria: I should be able to add a rate limit to any endpoint in 5 minutes
Questions for you before you start:
1. What are the different ways to implement this?
2. What are the trade-offs?
3. What information do you need that you don't have?
Check in after your design doc, then again after the first working version."
The delegation includes: context, constraints, success criteria, explicit unknowns,
and specific check-in points — not just the task.
Fix 4: Career Conversations That Are Actually Useful
Useless career conversation:
Manager: "Where do you want to be in 5 years?"
Engineer: "Um... senior engineer? Maybe staff someday?"
Manager: "Great, keep doing good work!"
→ Nothing changes
Useful career conversation:
Manager: "I've noticed you're technically strong, and I want to help you move toward senior.
The specific gaps I see are: [1, 2, 3].
Here's what I think doing senior-level work on those gaps looks like: [specific behaviors].
I'd like you to lead the next architectural decision — here's what I'll look for:
you should proactively identify trade-offs before I ask, and you should write
a brief document capturing the decision rationale. I'll give you feedback after.
Does that sound like a fair way to practice this?"
The useful version:
- Names specific gaps (not "think bigger")
- Describes the target behavior concretely
- Creates a specific opportunity to practice
- Commits to specific feedback
- Gets buy-in from the engineer
Fix 5: The "I Do, We Do, You Do" Model
Scaffolded skill transfer:
Stage 1: I Do (you observe)
→ Senior engineer leads a design review
→ Mid-level engineer watches, takes notes, asks questions afterward
→ Explicit teaching points: "Notice I asked about failure cases before
discussing the happy path. I do this because..."
Stage 2: We Do (you lead, I support)
→ Mid-level engineer leads the next design review
→ Senior engineer is in the room, can interject if needed
→ Debrief after: "What questions did you ask? What did you miss?
Next time, consider asking about..."
Stage 3: You Do (independent)
→ Mid-level engineer leads design review independently
→ Shares notes with senior for async feedback
→ Senior validates and identifies any remaining gaps
This model works for: code review, incident response, design reviews,
stakeholder communication, technical interviews they're running.
Mentoring Checklist
- ✅ Growth plan documents specific behaviors (not "be more senior")
- ✅ Teach through questions, not answers — engineer makes the discovery
- ✅ Delegation includes context, constraints, success criteria, and check-in points
- ✅ Career conversations name specific gaps and create specific practice opportunities
- ✅ "I Do, We Do, You Do" model for transferring new skills
- ✅ Feedback is specific and behavioral ("I noticed you...") not evaluative ("you're good/bad at...")
- ✅ Regular 1:1s focus on growth, not just status updates
Conclusion
Mentoring mid-level engineers is a design problem: identify the gap, create deliberate practice opportunities, and give feedback that closes the gap over time. The common mistake is vague encouragement ("keep thinking about the bigger picture") that doesn't tell someone what to actually do differently. Specific behaviors, specific observations, specific practice opportunities — those are what move someone from "strong mid-level" to "works at senior scope." The investment pays off in team throughput and in engineers who stay because they're growing.