Skip to content
Published on

Deliberate Practice — Experience Alone Will Not Make You Better

Authors

Introduction: Twelve Years In, Still Not Better

A senior I once worked with had twelve years of backend experience. On paper, anyone would have hired him as a senior engineer. Yet working alongside him, I felt a strange dissonance. He wrote code exactly the way he had five years earlier, and faced with new problems he always reached for the same tools. His career spanned twelve years, but his skill was closer to "three years repeated four times."

In contrast, a junior with only three years would put his finger precisely on the heart of a discussion. Every week he revisited the code he had written and asked, "Why did I do it this way?" He jotted down what he did not understand and chased it to the end. They spent the same hours, yet the gap between them widened steadily.

This article is about the nature of that gap. To state the conclusion up front: the length of your career does not guarantee skill. What you did, and how you did it, is what guarantees it. And that "how" has a name. It is called deliberate practice.

This is not an abstract sermon. The goal is concrete methods you can apply at your desk starting tomorrow morning. We will go warm but firm, without exaggeration.

1. The Uncomfortable Truth: Experience Is Not Skill

The Trap of Ten Years

You have probably heard of the "10,000-hour rule" — the popular notion that investing 10,000 hours in anything makes you an expert. Yet the original research behind that notion, by Anders Ericsson, actually tells nearly the opposite story.

What Ericsson emphasized was not the quantity of time but its quality. In his studies, what separated the top-level violinists was not the sheer total of practice hours but the hours of focused practice that pushed against their limits. Simply playing for a long time and consciously fixing the parts you cannot do are completely different activities.

In his book "Peak," Ericsson makes one uncomfortable observation: in many fields, people stop improving once they reach a certain level. Driving for twenty years does not make you a race-car driver, and there is research suggesting that a doctor who has practiced for thirty years is not guaranteed to diagnose better than one with five. At some point, once we become "good enough," we slip into autopilot.

The Nature of Autopilot

Autopilot is efficient. It lets you handle familiar work quickly without thinking. The problem is that skill does not grow in the autopilot state. The brain does not bother to change for work it does not find difficult.

A developer's autopilot mode looks like this.

- Builds with the usual framework, the usual patterns
- On an error, copies the message, searches, pastes the first answer
- Passes code review quickly with "LGTM"
- Looks at new tech "later, when there is time" (that time never comes)
- Treats retrospectives as a formality, repeating the same lines

Inside this mode, whether you work one year or ten, you exercise the same muscles. That is why a career stacks up while skill stays flat.

The Core Distinction: Experience vs. Practice

AspectExperience (mere repetition)Deliberate practice
GoalFinishing the workImproving a specific weakness
DifficultyComfortable levelSlightly beyond reach
FocusDiffuse is fineFull immersion required
FeedbackOccasional, vagueImmediate and specific
ResultWork done, but stagnantWork done and skill grows

The point of this table is that experience and practice can overlap but are not the same. We accumulate countless experiences every working day, yet the share that converts into deliberate practice is surprisingly low.

2. The Four Elements of Deliberate Practice

Translating Ericsson's research into a developer's language, deliberate practice stands on four pillars. Let us take them one at a time.

Element 1: A Clear and Specific Goal

"I want to get good at React" is not a goal. It is too big and vague to know what to do. The goal of deliberate practice must be measurable and narrow.

Bad goal:  "I want to handle async well"
Good goal: "I can reproduce, through my own experiments,
            the behavioral difference between Promise.all
            and for-await-of, and explain in one paragraph,
            in my own words, when to use which"

A good goal lets you judge for yourself whether it is done. A vague goal is perpetually in progress. A narrow goal targets only one weakness at a time, so the brain can focus.

Element 2: Full Focus

Deliberate practice is the enemy of multitasking. "Practice" done with Slack notifications on and YouTube playing is not practice but time-passing with background music.

The realistic devices for focus are these.

- Set a timer in 25-50 minute blocks (Pomodoro)
- Turn off all notifications for that time (Do Not Disturb)
- One session equals one goal
- When done, a 5-minute note: what you learned, what blocked you

The quality of focus determines the quality of practice. An immersed 30 minutes beats a scattered two hours.

Element 3: Immediate and Specific Feedback

Practice without feedback is like practicing a golf swing in the dark. If you cannot see where the ball went, no number of swings will improve you. Deliberate practice needs a mechanism that quickly tells you whether what you just did was right.

For developers, the sources of feedback are surprisingly many.

- Tests: tell you instantly with red/green
- Type checkers and linters: catch mistakes while you code
- Benchmarks: say in numbers whether it got faster or slower
- Code review: structural feedback through human eyes
- Production metrics: the most honest feedback, from real users

The key is to make the feedback loop short. Feedback that arrives in 30 seconds is far more powerful for learning than feedback that arrives in a month. Section 4 covers feedback-loop design separately.

Element 4: Challenge Beyond Your Limits (Outside the Comfort Zone)

The last pillar is the hardest and most important. Deliberate practice is, by definition, uncomfortable. If it feels comfortable, it is review, not practice.

Learning science speaks of three zones.

Comfort zone  - What you can already do. No growth.
Learning zone - Slightly beyond reach. Growth happens.
Panic zone    - Far too hard. Only frustration remains.

Deliberate practice is the art of staying in the learning zone. Too easy and it bores you; too hard and you collapse. Exactly one step harder, the spot where you understand 90 percent but the last 10 percent blocks you — that is the golden zone.

3. Concrete Methods for Developers

Now we leave the abstract and head for the desk. The following four are methods I have personally found effective, and ones that many senior engineers commonly recommend.

Method 1: Reading Code (Consciously Reading Well-Written Code)

We know that to write well we must read good writing, yet we often forget that to write good code we must read good code. Most developers only see their own code and their colleagues' code. They rarely look at world-class code.

Open source is that treasure trove. But mere scrolling is not practice.

A procedure for reading-code practice

1. Set a goal
   e.g. "How does this library solve concurrency problems?"
2. Find the entry point (README, tests, public API)
3. Follow a single flow to the end (do not read everything)
4. Write down questions at the points that block you
   "Why use CAS here instead of a lock?"
5. Find the answer, or form a hypothesis and experiment
6. Write the pattern you learned in one sentence

The heart of this practice is being active — never stopping the question "why?" Good code is the result of countless decisions, and the very process of tracing the reasons for those decisions is the practice.

Method 2: Reimplementation (Not Copying, but Understanding and Rebuilding)

One step beyond reading is reimplementation. After understanding how something working behaves, you build it yourself without looking at the original.

Reimplementation practice examples

- Implement debounce/throttle functions yourself
- Build a tiny state-management library (store plus subscribe)
- Implement a Promise from the spec alone
- Write a simple router, a simple virtual-DOM diff
- Write an LRU cache from scratch, with tests

The power of reimplementation is that it separates "what you think you know" from "what you truly know." You may have used debounce a hundred times, but try to write it and you stumble on timer cleanup, this-binding, and handling the trailing call. That stumbling point is exactly the part you did not know.

Method 3: Code Katas (Repeating Small Problems to Sharpen Fundamentals)

A kata, in martial arts, is the repeated rehearsal of a fixed set of movements. A code kata is the practice of solving the same small problem in several ways, several times. The purpose is not to solve the problem but to refine the process of solving it.

How to run a code kata

- Pick one small problem (e.g. Roman numeral conversion)
- Mon: solve it your usual way
- Tue: solve it with TDD, tests first
- Wed: solve it in a purely functional style
- Thu: solve it in the fewest lines (an experiment in sacrificing readability)
- Fri: solve it again in the most readable code (finding balance)

Solving the same problem under different constraints surfaces the decisions you usually make on autopilot. You can find problems at sites like codewars.com or codekata.com, but honestly, a small function from your daily work is enough to use as a kata.

Method 4: Postmortems (Consciously Learning from Failures and Incidents)

The most expensive textbook is the outage. The alarm at dawn, the broken deploy, the lost data. These experiences are so intense it feels they should teach you automatically, but unless you process them consciously, they remain only trauma.

A postmortem is the conscious procedure that turns an incident into a learning asset. The key is a blameless attitude. You ask not "who was at fault" but "what system made this mistake possible."

A simple personal postmortem template

1. What happened (facts only, in chronological order)
2. Why it happened (5 Whys, down to the root cause)
3. How you noticed (time to detection)
4. How you recovered
5. What change prevents recurrence (a concrete action)
6. One thing you newly learned this time

The postmortem-culture chapter in Google's SRE book is a good starting point. Even without a team-level postmortem, simply filling in the template above on your own lets you learn twice as much from the same incident.

4. How to Build Feedback Loops

Of the four elements, feedback is the one developers most often skip, especially when studying alone. So let us cover how to design feedback loops deliberately.

The Structure of a Feedback Loop

   ┌──────────────┐
   │  1. Attempt   │   (write code, form a hypothesis)
   └──────┬───────┘
          v
   ┌──────────────┐
   │  2. Get signal│   (tests, review, metrics, people)
   └──────┬───────┘
          v
   ┌──────────────┐
   │  3. See gap   │   (expected vs actual, what diverged)
   └──────┬───────┘
          v
   ┌──────────────┐
   │  4. Adjust    │   (revise hypothesis, next attempt)
   └──────┬───────┘
          └──────────> back to step 1 (shorter loop, more powerful)

The faster this loop turns, the faster you learn. A good development environment is, in the end, a collection of tools that shorten this loop. Hot reload, fast tests, and good error messages are all loop-shortening devices.

Making Feedback for Yourself

You can manufacture feedback even without a colleague's review.

- Review from your future self:
  rereading code a day later makes it objective
- Tests as feedback machines:
  prove "this is right" with a test, not with the code
- Write in public:
  organizing what you learned into a post exposes the gaps
- Explain it (rubber duck):
  explaining to someone (or a toy) reveals what you do not know
- Build it two ways:
  building the same thing differently makes each version feedback for the other

A Conversation for Asking a Colleague for Feedback

To receive feedback well, you must ask well. "Take a look at my code" is not a good question. It is too broad for the other person to know what to look at.

Bad request:
  "Please review this PR."

Good request:
  "I am not confident about the error handling in this PR.
   In particular, I would appreciate it if you could check
   whether the retry logic is reasonable when the external API
   times out. The rest you can look at lightly."

A narrow, specific request saves the other person's time and concentrates feedback on the part where you are genuinely weak.

5. Stepping Outside the Comfort Zone

We know in our heads that "you grow by doing hard things," yet the body drifts toward the easy. Leaving the comfort zone is less a matter of willpower than of design.

Diagnosing Your Comfort Zone

First you must know where you are stuck. Answer the following honestly.

Comfort-zone checklist

[ ] In the last month, were you stuck for over an hour on something?
[ ] In recent code, was there anything where you thought "will this work?"
[ ] Have you honestly said "I do not know" recently?
[ ] Have you tried a new tool / language / paradigm?
[ ] Has anyone challenged one of your decisions?

The fewer the checks, the deeper you likely sit in the comfort zone.

No friction at all means comfort, and comfort can be a sign that growth has stopped.

Pushing Out One Step at a Time

The safe way to leave the comfort zone is not to jump into the panic zone but to move one step into the learning zone.

- Deliberately use one unused feature of a familiar language
- Touch an area you usually avoid (backend if frontend, frontend if DB)
- When opinions split in review, do not stay silent — give your reasons
- Volunteer to present or share on a topic you are unsure of
- Verify with measurement what you used to only guess

Frequent small discomforts beat occasional large ones. The person who does something 5 percent beyond reach every day travels farthest a year later.

6. Breaking Through the Plateau

You work hard, and then at some point you no longer feel any improvement. That is the plateau. A plateau is not a failure but a natural part of the learning curve. It appears in almost every path to mastery.

The Nature of the Plateau

Ericsson notes that a plateau is often a limit of method, not a limit of ability. You have reached a point where your current practice method no longer stimulates you. You have adapted to the same stimulus.

Common signs of a plateau
- It feels like there is nothing new at all
- Familiar work has become far too easy
- Interest fades and it is boring
- No change is visible for the effort

Strategies to Break a Plateau

1. Take precise aim at a weakness
   Do not vaguely try to be good at everything; find your single
   weakest point and attack only that (this cuts off autopilot)

2. Add constraints
   Artificial constraints like "no libraries," "one file,"
   "twice the performance" force you to use new muscles

3. Raise the difficulty one level
   Move to a larger codebase, more demanding requirements

4. Teach it
   Teaching others lays your understanding's gaps bare

5. Change your environment
   A new team, a new domain, new colleagues force autopilot off

The most dangerous reaction at a plateau is "more, and longer." Increasing only the volume in the same way does not work. You must change the method.

7. Measuring Progress

"What gets measured gets improved" applies to skill too. But skill is not a clean number like revenue, so measuring it takes a little creativity.

What to Measure

- Learning log: record three "things I newly learned" each week
- Stuck time: is the time you stay stuck on similar problems shrinking?
- Reimplementation speed: what once took two hours, how long now?
- Code-review comments: are the critiques you get shifting to advanced ones?
- Explaining ability: can you explain a concept without stumbling?

Keeping a Learning Journal

The simplest and most powerful measurement tool is a learning journal. It need not be grand.

Weekly learning journal format (5 minutes)

Date:
Deliberate practice this week:
Three things I newly learned:
  1.
  2.
  3.
The point where I was most stuck:
One thing to try next week:

Gather a few weeks and reread them, and you see a growth curve invisible day to day. The journal measures progress and, at the same time, strengthens memory by retrieving what you learned once more.

8. Designing a Weekly Routine

Good intentions evaporate without a routine. The "when I have time" time never comes. Deliberate practice survives only when it claims a place on your calendar.

Below is an example that allots roughly five hours a week to deliberate practice. Adjust the amount to your circumstances. The key is a little every day, and variety.

DayActivityTimeDeliberate-practice element
MonOne code kata30 minClear goal, immediate feedback
TueReading open-source code45 minChallenge beyond limits, focus
WedReimplement yesterday's reading45 minFeedback, outside comfort zone
ThuCode kata (different constraint)30 minBreak plateau with constraints
FriWeekly learning journal20 minMeasure progress, strengthen retrieval
OngoingSmall challenges during work-Daily learning zone
When incident occursPersonal postmortem30 minLearning from failure

You do not need to follow this table verbatim. Two things matter. First, that practice is pinned to your calendar as concrete time. Second, that at least once a week there is an activity that takes you outside the comfort zone.

I want to stress challenges during work. Practice is not only the separate five hours. Asking, once more, "is there a slightly better way?" inside your daily work, and trying a solution one step harder instead of the familiar one, is the most efficient practice of all. Do not separate work and practice; plant practice inside the work.

9. Common Pitfalls

Finally, let me point out the pitfalls that well-intentioned people often fall into. Avoiding these alone gets you halfway there.

Pitfall 1: Mistaking Busyness for Practice

The most common and most subtle pitfall. When we are busy, we feel we are growing. The day fills up clearing tickets, attending meetings, answering Slack. But most of that is the busyness of autopilot, not deliberate practice.

Telling busyness from practice
- Did you learn something new when it was over? If not, it was busyness.
- Was it even slightly beyond reach? If it was comfortable, busyness.
- Did it target a weakness? If you used only strengths, busyness.

Being busy and growing are different. A day of much work and a day of grown skill are not necessarily the same.

Pitfall 2: Mistaking Passive Consumption for Learning

Bingeing lecture videos at double speed, hoarding bookmarks of tech articles. Input is only the start of learning, not learning itself. Unless you move your hands and produce output, most of it evaporates. A healthy ratio is two hours of writing code for every hour of lecture watched.

Pitfall 3: Paralysis from Goals Too Large

A goal like "master machine learning" is so big it makes even the first step hard to take. The bigger the goal, the smaller you must slice it. A great mountain can only be climbed one step at a time.

Pitfall 4: Avoiding Feedback

Showing your code to others is always scary. So the people who most need feedback are the ones who avoid it most. Yet feedback received despite the embarrassment is the fastest shortcut to growth. Feedback is a gift, not an attack.

Pitfall 5: A Fixed Mindset

Carol Dweck's research shows the growth gap between people who see ability as fixed and those who see it as something to be grown. "I was just never good at algorithms" becomes a self-fulfilling prophecy. A weakness is merely an area you have not yet practiced. It begins with attaching one word, "yet." Not "I cannot do this," but "I cannot do this yet."

Closing: One Step Today

Back to the two engineers from the beginning. The difference between the twelve-year senior and the three-year junior was neither talent nor time. It was the result of small conscious efforts compounding daily.

Deliberate practice is not a grand resolution. It is looking once more at the code you wrote today, noting what you do not know as not-known, trying a solution one step harder — the accumulation of those small actions.

And to be honest, this is not always enjoyable. Deliberate practice is, by definition, uncomfortable. Turning off comfortable autopilot and placing yourself in the learning zone every time takes energy. So do not be too harsh on yourself. You do not have to be perfect every day. You only have to not stop.

Not the length of your career, but what you did and how you did it in that time, is what makes you. Tomorrow's you is the sum of the practice today's you chooses. Do not start grandly; start small. One step today is enough.

References