← Back to list

95% of Developers Ignore This Career Skill

Most developers think their career grows when their code gets better. That is only half true.

CodeByUmar in Skill Stuff · 2026-06-08 18:04 · 53 claps · 18.5 min read paywalled
#careers #software-development #software-engineering #coding #web-development
Open on Medium ↗
Wiki topics: 💻 · Programming 🌐 · Web Development

95% of Developers Ignore This Career Skill

Most developers think their career grows when their code gets better. That is only half true.

95% of Developers Ignore This Career Skill

95% of Developers Ignore This Career Skill

The hidden career skill is not grinding more syntax, memorizing more frameworks, or collecting more certificates.

It is learning how to communicate technical judgment clearly.

Most developers are terrible at this.

Not because they are lazy. Not because they are unintelligent. Not because they do not care.

They are terrible at it because nobody teaches it seriously.

I have seen developers write excellent code and still get ignored in meetings. I have seen weaker engineers get more trust because they explained the risk better. I have seen brilliant people lose influence because their ideas sounded like complaints. I have seen teams waste weeks because nobody could clearly explain what was blocked, what was risky, what was unknown, and what decision needed to be made.

The code was not the bottleneck.

The communication around the code was.

This is the career skill most developers ignore: the ability to turn technical understanding into clear, useful, decision-ready communication.

Not corporate fluff. Not fake confidence. Not writing long documents nobody reads. Not talking more in meetings just to sound visible.

I am talking about the ability to explain what is happening, why it matters, what the tradeoff is, what could break, and what should happen next.

That skill changes your career.

Because at some point, writing code is not enough.

Good Code Does Not Speak for Itself

A lot of developers believe good work should be obvious.

It rarely is.

Your code does not walk into a meeting and explain the tradeoff you made. Your refactor does not tell the product manager which future bugs it prevents. Your test suite does not explain to leadership why the release is safer now. Your architecture decision does not automatically teach the next developer why the simple-looking alternative was dangerous.

You have to explain it.

This is where many developers lose career momentum.

They do the work, but they do not create understanding around the work. They fix the bug, but nobody learns why it happened. They improve the system, but nobody understands the risk they removed. They warn about a technical decision, but they explain it so vaguely that the team hears it as personal preference.

Then they get frustrated.

“I told them this would happen.”

Maybe they did.

But saying something once in technical language is not the same as communicating it clearly enough for a team to act on it.

I have seen developers warn about scaling issues by saying:

This implementation is not clean.

That sentence is almost useless.

What does “not clean” mean? Slow? Unsafe? Hard to test? Expensive to change? Likely to break under concurrency? Missing observability? Violating a contract? Creating migration risk?

A stronger engineer says:

This works for the demo, but it creates a production risk. The job is not idempotent, so if the queue retries after a timeout, we can charge the same customer twice. We should add an idempotency key before release.

That is different.

It is specific. It explains the risk. It connects code to business impact. It gives the team a decision.

Good technical communication is not about sounding smart. It is about reducing ambiguity.

Takeaway: if people do not understand the importance of your work, your work will be undervalued, delayed, or misunderstood.

The Career Ceiling Starts Where Explanation Stops

Early in your career, you can grow by completing tickets.

You get assigned work. You implement it. You fix bugs. You ask for help. You learn the codebase. You ship features. This stage is important, and there is nothing wrong with it.

But eventually the game changes.

The team does not only need someone who can finish a task. It needs someone who can understand a messy situation and create clarity.

Why is this bug happening? Which solution is safer? What should we build first? What is the tradeoff between speed and maintainability? Why did the deployment fail? What is the real blocker? What is unknown? What can wait? What decision needs to be made today?

Developers who can answer these clearly start getting trusted with bigger work.

Developers often get stuck, even if they write good code.

That is harsh, but true.

Your manager cannot promote a private genius easily. Your tech lead cannot depend on someone who only understands things inside their own head. Your team cannot safely give ownership to someone who disappears into a problem for three days and returns with a pull request nobody can review.

Communication is not separate from engineering.

It is how engineering scales beyond one person.

A senior engineer is not just someone who knows more. A senior engineer makes the team less confused.

That sentence matters.

You can be technically strong and still create confusion. You can write clever abstractions that nobody understands. You can make correct decisions that nobody can evaluate. You can solve hard problems while leaving the team unclear about why the solution is safe.

That is not senior behavior.

Senior behavior creates shared understanding.

Takeaway: your career ceiling is not only determined by what you know. It is determined by how clearly you can make others understand what matters.

Most Developers Explain Too Late

One of the biggest mistakes developers make is waiting until the end to explain their thinking.

They work silently. They investigate silently. They make assumptions silently. They change direction silently. Then they open a pull request with a large diff and a two-line description.

Something like:

Fixed billing issue and cleaned up related logic.

That is not a pull request description. That is a crime scene label.

Now reviewers have to reconstruct the story from the diff. They have to figure out what was broken, what changed, why the change is safe, whether the behavior changed intentionally, and what cases were considered.

This wastes review time.

Worse, it creates mistrust.

A reviewer looking at a confusing diff starts wondering: did the developer understand the problem? Did they test the edge cases? Did they change unrelated behavior? Did they notice the migration risk? Did they know this function is used by another workflow?

The work may be good.

But the communication makes it feel risky.

A stronger approach is to communicate the investigation path before the diff becomes huge.

For example:

I found the billing issue. The retry worker can process the same invoice twice when the payment provider times out after capturing payment but before returning a response. I am going to make the refund operation idempotent first, then add a test around duplicate queue delivery. I am not changing the invoice state machine in this PR.

That message does several things.

It explains the cause. It defines the scope. It shows judgment. It prevents surprise. It gives others a chance to correct the direction early.

This is especially important when the work is risky. If you are touching authentication, billing, permissions, database migrations, background jobs, caching, deployment configuration, or shared contracts, do not wait until the pull request to explain what is happening.

The pull request should not be the first time your team understands the problem.

Takeaway: Communicate early enough that your team can help shape the decision, not just review the aftermath.

Writing Better Pull Requests Is a Career Advantage

Pull requests reveal how you think.

Not just how you code.

A weak pull request says:

Update user flow

Then it contains 34 files, a migration, a UI change, a backend change, a refactor, new tests, deleted tests, renamed variables, and one suspicious helper function called formatNewData.

The reviewer now has to do archaeology.

A strong pull request tells a story.

It answers the questions reviewers actually have:

What problem does this solve? What behavior changed? What behavior did not change? What risky areas were touched? How was it tested? What should reviewers focus on? Is there a rollback concern? Are there follow-up tasks?

You do not need a novel. You need enough context to make the review faster and safer.

A useful pull request description might look like this:

## What changed

This adds duplicate-submit protection to the invoice refund flow.

## Why
Users could click the refund button twice before the first request completed. The backend rejected the second request, but the UI showed a generic error, which made support think the refund failed.

## Risk
Low to medium. The backend refund logic is unchanged. This PR only disables the UI action while the first request is pending and improves the error message.

## Testing
- Added a test for double-click submit behavior
- Verified the refund button stays disabled while the request is pending
- Verified the existing refund success path still works

This is not bureaucracy.

This is engineering hygiene.

The best developers I have worked with did not treat pull request descriptions as paperwork. They treated them as part of the change. They knew the diff was not enough. The team needed context.

A good PR description saves reviewer energy. It prevents misunderstandings. It creates a record for future developers. Three months later, when someone asks why a decision was made, the explanation is not buried in Slack or lost in someone’s memory.

The nuance is that not every PR needs a long template. A one-line typo fix does not need a risk analysis. But when the change has behavior, risk, or tradeoff, explain it like you respect the reviewer’s time.

Takeaway: A clear pull request is not decoration. It is how you make your work easier to trust.

The Best Engineers Explain Tradeoffs, Not Preferences

Weak technical arguments sound like preferences.

“This is cleaner.” “This is better.” “This is bad practice.” “This feels wrong.” “We should not do it this way.”

Sometimes these statements are true, but they are not useful enough.

The problem is that preferences do not help teams decide under pressure. Tradeoffs do.

A stronger engineer explains what the team gains, what it loses, and what risk it accepts.

Instead of saying:

This architecture is bad.

Say:

This approach is faster for the first release, but it couples the checkout flow directly to the payment provider. If we need to support another provider later, we will touch the checkout code again. If we expect only one provider for the next year, this is acceptable. If multi-provider support is likely next quarter, we should add a boundary now.

That is a mature engineering statement.

It does not pretend there is only one correct answer. It gives context. It shows judgment. It helps the team choose intentionally.

Senior engineers are often opinionated, but the good ones are not dogmatic. They know most engineering decisions involve tradeoffs: speed versus flexibility, simplicity versus extensibility, consistency versus local optimization, strictness versus delivery pressure, abstraction versus duplication, and control versus operational burden.

The developer who can explain those tradeoffs clearly becomes valuable fast.

Because teams are constantly making imperfect decisions with incomplete information.

That is real software engineering.

You rarely get perfect requirements, unlimited time, clean systems, stable dependencies, and no politics. You get deadline pressure, legacy code, half-known constraints, unclear ownership, and a production system that cannot stop moving.

In that environment, “best practice” is often too vague.

Tradeoff thinking is better.

Here is another example.

Weak version:

We should use a queue here.

Stronger version:

A queue makes the request faster and gives us retry handling, but it also makes the workflow eventually consistent. That means the user may see a pending state instead of immediate completion. If that product experience is acceptable, a queue is safer for this operation because the external API is slow and sometimes times out.

Now the product manager, designer, and backend team can participate in the decision.

That is influence.

Takeaway: preferences create arguments. Tradeoffs create decisions.

Clear Status Updates Prevent Management Theater

Developers often dislike status updates because many status updates are useless.

They become rituals. Standup becomes a list of tasks. Managers ask, “Any blockers?” Everyone says no. Then three days later, someone admits the feature is stuck because an API contract is unclear, the staging environment is broken, and nobody knows who owns the permission model.

The problem is not status updates.

The problem is bad status updates.

A useful developer status update does not recite activity. It communicates progress, risk, and the next decision.

Weak update:

Working on the user settings page.

Better update:

The user settings UI is mostly done. I am blocked on the backend contract for notification preferences because the current API returns preferences as separate booleans, but the design assumes grouped categories. I need a decision on whether the frontend should adapt the current shape or whether backend will update the response.

This is useful.

It tells the team what is done, what is blocked, why it matters, and what decision is needed.

Another weak update:

Still debugging the login issue.

Better update:

I reproduced the login issue in Safari. The session cookie is not being sent after redirect because SameSite is set differently between staging and production. I am comparing the environment configs now. If the config mismatch is confirmed, the fix should be small, but we should also add a deployment check so this does not happen again.

This creates confidence.

Not because the bug is already fixed, but because the thinking is visible.

Managers, leads, and teammates do not need constant noise. They need a signal. They need to know whether the work is healthy, risky, blocked, expanding, or waiting on a decision.

The best updates are short, specific, and decision-oriented.

A simple structure works:

Current state:
What I found:
Risk or blocker:
Next step:
Decision needed:

You do not need to use that format every time. But the thinking behind it is powerful.

It prevents the classic developer trap: silently struggling because you do not want to look weak.

That trap burns days.

Strong developers ask for help with context. Weak communication makes help expensive because nobody knows what was tried, what failed, and what evidence exists.

Takeaway: A good status update is not about proving you are busy. It is about making risk visible early.

Technical Writing Makes You Harder to Ignore

Most developers underestimate writing.

They think writing is for documentation teams, product managers, architects, or people who like Notion too much.

That is a mistake.

Writing is one of the highest-leverage engineering skills because it forces fuzzy thinking to become visible.

If you cannot write the decision clearly, there is a good chance you do not fully understand it yet.

This is not an insult. It is a useful signal.

A developer says:

We need to refactor the notification system.

Okay. Why?

The first written version might be vague:

The current notification system is messy and hard to maintain.

That is a complaint, not a proposal.

A better version becomes clearer:

The current notification system mixes delivery rules, template rendering, user preference checks, and provider-specific API calls in the same service. This makes every new notification type risky because a change to delivery logic can accidentally affect rendering or provider behavior. I propose separating notification eligibility, template rendering, and provider delivery behind explicit interfaces. This would make new notification types easier to test and reduce regression risk.

Now the team has something to discuss.

Writing turns frustration into structure.

It also protects decisions from disappearing.

Slack is where context goes to die. Meetings are where nuance gets misremembered. Code comments help, but they are usually too close to implementation details. A short technical note, design doc, incident summary, or decision record can save future developers from repeating the same argument.

Useful technical writing includes:

Design proposals. Incident writeups. Migration plans. API contract explanations. Architecture decision records. Debugging notes. Onboarding guides. Pull request context. Post-release lessons.

This does not mean every decision needs a document. Over-documentation is real. Some teams write so much that nobody reads anything. The goal is not to document the ceremony. The goal is durable clarity where memory is not enough.

A good rule: write when the decision is expensive to rediscover.

If a future developer asks, “Why did we do it this way?” and the answer matters, write it down.

Takeaway: Technical writing is not separate from engineering. It is how engineering knowledge survives beyond the person who had it.

Communication During Incidents Separates Professionals From Panic

Nothing exposes communication skills like a production incident.

When production breaks, bad communication makes everything worse.

People jump between theories. Someone blames the last deploy. Someone posts random logs without context. Someone says, “It works locally.” Someone restarts a service without saying why. Someone opens five threads. Someone starts fixing symptoms before the team understands the failure. Support asks for an ETA. Leadership asks for impact. Engineering is still debating whether the database is down.

This is how incidents become chaos.

Strong incident communication is calm, factual, and structured.

It separates evidence from guesses.

Bad incident message:

Payments are broken. Maybe the provider is down. Looking into it.

Better message:

Impact: payment confirmation is failing for some checkout sessions since 14:05 UTC. New payments appear to be captured by the provider, but our webhook handler is returning 500 before updating order status. Current action: checking webhook logs and recent deploy changes. Next update in this thread after we confirm whether the failure is in signature validation or order update logic.

This message does not solve the incident by itself.

But it reduces panic.

It tells people what is known, what is not known, what is being checked, and where updates will happen.

During incidents, senior engineers avoid pretending they know more than they do. They say:

Confirmed.

when evidence exists.

They say:

Hypothesis.

When they are making an educated guess.

They say:

Unknown.

When the team does not know yet.

That honesty matters.

A lot of incident damage comes from confident guessing. Someone assumes the cache is stale. Someone assumes the database is fine. Someone assumes the provider is down. Someone assumes the last deployment caused it. Sometimes they are right. Often, they waste precious time.

Good communication creates a shared map.

What is affected? When did it start? What changed recently? What evidence do we have? What is the current hypothesis? What action is being taken? Who owns the next step? What should we not touch yet?

This skill is career-changing because trust is built under pressure.

People remember who created clarity when things were messy.

They also remember who created the noise.

Takeaway: During incidents, your communication should reduce panic, not add more theories to the fire.

The Silent Developer Is Often Misread

There is a common developer fantasy that quiet competence will always be recognized.

Sometimes it is. Often it is not.

A quiet developer may be doing excellent work, but silence creates room for interpretation. The team may not know they are solving a hard problem. Their manager may not see the judgment behind their decisions. Their peers may not understand what risks they removed. The product may think the task was simple because nobody explained the hidden complexity.

This does not mean you need to become loud.

It means you need to become legible.

There is a difference.

Being loud means trying to dominate attention. Being legible means making your work understandable to the people who depend on it.

You can be introverted and still communicate well.

You can write clear updates. You can leave useful PR descriptions. You can document decisions. You can ask precise questions. You can summarize tradeoffs. You can raise risks early. You can explain what changed and why.

None of that requires becoming a meeting performer.

One of the strongest engineers I worked with was quiet in meetings. But when he spoke, everyone listened because he was precise. He did not ramble. He did not posture. He would say something like:

There are two separate problems here. The first is query performance, which we can improve with an index. The second is data correctness, which the index will not fix. If we ship only the index, the page becomes faster but still shows wrong totals for delayed payments.

That is influence.

Not volume. Clarity.

The mistake many quiet developers make is assuming their work will be interpreted correctly without context. It might not be. Especially in larger teams, remote teams, cross-functional projects, or companies where managers cannot inspect every technical detail directly.

Your work needs a trail.

Not a bragging trail. A clarity trail.

Takeaway: You do not need to talk more. You need to make your technical judgment easier to see.

Asking Better Questions Is Part of the Skill

A lot of developers think asking questions makes them look weak.

Bad question asking can do that. Good question, asking does the opposite.

A weak question transfers all thinking to someone else:

This does not work. What should I do?

A stronger question shows investigation:

The profile update request returns 403 only in staging. I confirmed the token is present, the user has profile.write, and the endpoint works locally. The staging logs show ORG_PERMISSION_MISSING. Is staging using a different organization permission seed, or should the frontend be sending an organization ID with this request?

That question is useful.

It gives evidence. It shows what was checked. It narrows the problem. It respects the other person’s time.

Senior engineers ask questions that accelerate the conversation.

They do not hide confusion. They structure it.

This matters because software engineering is full of unknowns. Requirements are incomplete. APIs behave strangely. Legacy code has hidden assumptions. Infrastructure has undocumented quirks. Product decisions change. Nobody knows everything.

The career skill is not pretending you know.

The career skill is reducing unknowns efficiently.

A good technical question often includes:

What you expected. What actually happened? What you already checked. What evidence did you find? What do you think the likely cause is? What decision or help do you need?

For example:

Expected:
The report export should include archived customers when includeArchived=true.

Actual:
Archived customers are missing in staging.
Checked:
- Frontend sends includeArchived=true
- API receives includeArchived=true
- Database query includes status filter
- Local seed data works
Evidence:
Staging query logs show organization_id is applied, but archived status is filtered out later in the repository.
Question:
Is this endpoint supposed to include archived customers, or should the UI label be changed?

This is not just a question.

It is a debugging artifact.

The person answering can help quickly because they are not starting from zero.

Takeaway: Good questions do not make you look weak. They show that you can think clearly through uncertainty.

Communication Is How You Build Technical Trust

Trust is not built by saying, “Trust me.”

Trust is built when people repeatedly see that your judgment is clear, your reasoning is honest, and your work does not create unnecessary surprises.

That happens through communication.

When you explain risks clearly, people trust your warnings. When you write good pull requests, people trust your changes. When you give precise updates, people trust your ownership. When you ask strong questions, people trust your thinking. When you admit uncertainty, people trust your honesty. When you document decisions, people trust your memory less because the system does not need memory.

This is why communication affects promotions.

Not because companies reward people who talk nicely.

Because higher-level engineering work is coordination-heavy.

Senior engineers influence systems beyond their own files. Staff engineers influence teams beyond their own sprint. Tech leads make decisions that affect other developers’ work. Architects need alignment. Engineering managers need visibility. Product teams need tradeoffs. Security teams need risks surfaced. Support teams need explanations. New developers need context.

At some level, your impact depends on whether your understanding can move through the organization.

Code alone cannot do that.

This is uncomfortable for developers who want engineering to be purely technical. But real software is built by groups of people with different information, incentives, pressures, and blind spots.

Communication is not soft.

Miscommunication causes hard failures.

The wrong API contract gets built. The migration runs at the wrong time. The frontend relies on behavior that the backend never guaranteed. The deployment risk is misunderstood. The incident impact is underreported. The security concern sounds optional. The refactor becomes invisible until it breaks something. The decision is made twice because nobody wrote it down.

These are not soft problems.

They are engineering problems with human interfaces.

Takeaway: Technical trust is built when your thinking becomes visible, reliable, and useful to others.

How to Actually Practice This Skill

The frustrating part is that “communicate better” sounds vague.

So make it concrete.

Start with pull requests. Before opening your next meaningful PR, write five things:

What changed? Why did it change? What behavior is different? What risk exists? How did you test it?

Do this even if nobody asks. Especially if nobody asks.

Then improve your status updates. Stop saying only what you are working on. Say what changed, what is blocked, what is risky, and what decision is needed.

Instead of:

Working on checkout bugs.

Write:

I reproduced the checkout bug with expired coupons. The API returns the correct validation error, but the frontend maps it to a generic failure. I am updating the error mapping now. Risk is low because the checkout calculation is unchanged.

Next, practice explaining tradeoffs.

When you disagree with an approach, do not say only that it is wrong. Explain the cost of choosing it and the cost of not choosing it.

Instead of:

This abstraction is overkill.

Say:

This abstraction reduces duplication across three screens, but it also hides simple field behavior behind a configuration layer. Since we only have three screens and the rules are still changing, I would keep the duplication for now and revisit after the fourth use case.

That sounds like engineering judgment.

Then practice writing short decision records. Not long documents. Just enough context.

# Decision: Use cursor pagination for activity logs

## Context
Activity logs can grow quickly, and offset pagination becomes slower as the table grows.

## Decision
Use cursor pagination for the activity log API and UI.

## Tradeoff
Cursor pagination makes jumping to arbitrary pages harder, but improves performance and consistency for append-heavy data.

## Follow-up
Document cursor behavior in the API contract.

This takes ten minutes.

It can save hours later.

Finally, practice incident-style clarity even outside incidents. When debugging, separate facts from guesses.

Facts:

The request fails only in Safari.

Hypothesis:

The cookie policy may be different after redirect.

Next action:

I will compare cookie attributes between Chrome and Safari and check staging config.

This habit makes you calmer under pressure because you are not mixing evidence with panic.

Takeaway: communication improves when you practice it in small engineering moments, not only when the stakes are high.

The Developers Who Ignore This Stay Frustrated

The hard truth is that many developers will ignore this skill forever.

They will keep believing their code should be enough. They will keep complaining that nobody listens. They will keep writing vague pull requests. They will keep raising risks in ways that sound like opinions. They will keep giving status updates that hide the real blocker. They will keep asking unclear questions and getting slow answers. They will keep doing valuable work that nobody fully understands.

Then they will wonder why their career feels stuck.

This does not mean communication replaces technical ability.

A developer who communicates well but cannot reason technically is dangerous in a different way. Smooth talk is not engineering. Confidence without depth creates bad decisions faster.

The point is not to choose communication over code.

The point is that serious developers need both.

Technical ability lets you understand the problem.

Communication lets your understanding help the team.

That is the multiplier.

A developer who can code but cannot communicate is useful in a narrow lane. A developer who can code and communicate clearly becomes someone others trust with ambiguity, risk, ownership, and direction.

That is where career growth happens.

Not in knowing the newest framework before everyone else.

Not in having the loudest opinion.

Not in writing clever code.

In becoming the person who makes complicated things understandable enough to act on.

Conclusion: Clarity Is a Career Skill

Most developers do not need to talk more.

They need to explain better.

They need to turn confusion into structure, risk into tradeoffs, bugs into evidence, decisions into records, and code changes into understandable stories.

That is not corporate nonsense.

That is engineering at scale.

The best developers are not just the ones who can solve hard problems. They are the ones who can make hard problems clear enough for other people to help, trust, review, operate, and build on.

Your code matters.

But your ability to explain the judgment behind your code may decide how far your career goes.

Because eventually, the job is not just writing software.

It is helping a team make better technical decisions under pressure.

That is the skill most developers ignore.

And that is exactly why it compounds.

Follow for more no-BS software engineering insights.


메타데이터
post_id
ed9819a8d8e5
slug
95-of-developers-ignore-this-career-skill-ed9819a8d8e5
url
https://medium.com/skillstuff/95-of-developers-ignore-this-career-skill-ed9819a8d8e5
canonical_url
https://medium.com/skillstuff/95-of-developers-ignore-this-career-skill-ed9819a8d8e5
author_url
https://medium.com/@codebyumar
status
ok
fetched_at
2026-06-11 05:11:55