For a long time I measured my progress by what I could build. A new framework learned, a new kind of app shipped, one more line on the stack section of my CV. It felt like the right scoreboard, because early on it mostly was.
What I didn't notice was the moment the scoreboard stopped matching the game. The code didn't get easier, exactly. It just stopped being the part that kept me up at night. The hard part had moved somewhere else: deciding what to build, deciding what not to build, and living with the consequences of both.
This post is my attempt to describe that shift as I lived it. It's not a framework for deciding who is senior. Titles mean different things in different companies and different markets. In 2025 I was a Software Engineer at one company and a Senior Software Engineer at another, at the same time, and a few months later a Full Stack Developer at a third. The work behind those titles wasn't nearly as different as the words. So read this as one engineer's view of how the problems changed, not as a ladder anyone has to climb.
Junior: learning to execute
I started in 2022, prototyping a delivery app, web and mobile, while I was still in college. I was alone on it, which meant I made every decision: the architecture, the data model, how the pieces talked to each other. For a while I took that as a sign I was further along than I was.
It took me years to understand the difference. Making decisions nobody reviews is not the same as making good decisions. Nobody told me a choice was wrong, so I assumed it wasn't. I was making architecture decisions without knowing what the alternatives were, what they cost, or what would break six months later. I didn't know what I didn't know.
When I joined a team in 2024, working on web and mobile apps with React, Next.js, React Native and Flutter, the shape of my work became clearer, and honestly more comfortable. Tasks came well defined. Someone had already decided what the screen should do; my job was to make it do that. The question I asked all day was:
"How do I implement this?"
That question is not a small one. At that stage it's the right question. You're learning the stack, the codebase, the conventions nobody wrote down, and the difference between code that works on your machine and code that survives review. I needed guidance often, and I needed it to be specific.
Looking back, the main thing I was building wasn't features. It was execution: the ability to take something defined and turn it into working software without drama. Everything that came later depends on that. You can't reason about trade-offs in code you still struggle to write.
Mid-level: learning to own
The change to mid-level didn't come with a new kind of task. It came with less instruction attached to the same kind of task.
Instead of "build this screen," it became "we need this integration." I worked on integrations with Mercado Livre, Shopee and Meta, and I owned publishing and maintaining iOS apps through Apple Developer: the release cycle, the App Store review guidelines, the part of the work that starts after the pull request is merged. That last part taught me something the code never did. A feature isn't done when it works. It's done when it's in users' hands and still working.
External systems force this lesson on you. Their APIs time out, change without notice, send the same event twice, or answer successfully with half the data missing. So the questions I asked started to change. What happens when this call fails? What if this webhook arrives twice? How do I test this without charging a real card? How will I know it broke in production before a customer tells me?
The question underneath all of them was:
"What's the best way to solve this?"
That question assumes the problem is already correct. Someone else decided what we're solving; I decide how. I became responsible for edge cases, tests, performance and deploys, and I needed less and less detail in the ticket to get it done.
It's a real step, and for a while it feels like the whole job. You're trusted. You ship. People stop checking every line. It's easy to believe that the next step is just more of the same: bigger features, more complex systems, more technologies.
For me it wasn't.
Senior: learning to decide
The clearest sign that my work had changed was that I started getting problems instead of tasks.
Not "build X," but "this screen is slow," "this system needs to move off Firestore," "customers can't pay and we don't know why." No spec, sometimes no clear owner, and often incomplete information about what was actually happening.
New problems
The problems themselves took a different shape. They were less often about a feature and more often about a system that was already running, with people depending on it.
An ERP focused on fleet management that I worked on had to move its core from Firestore to PostgreSQL, and six separate products had to be consolidated into one multi-tenant deployment. The constraint that shaped everything was that the operation couldn't stop. Writing the new schema was not the hard part. The hard part was deciding how to migrate module by module, what could coexist and for how long, and what risk we were willing to accept at each step. None of that fits in a ticket.
New responsibilities
The responsibilities changed too, and they were harder to notice, because nobody hands them to you in a ticket.
- What happens after deploy. On a web and mobile product used by thousands of people, being responsible meant crash reporting, logs and metrics: knowing something broke before a customer tells you.
- Other people's money and data. Payments and webhooks, where the same event can arrive twice and a careless retry charges someone again. And deciding what not to collect: in a payment flow, what we left out of the instrumentation mattered as much as what we captured.
- Translating trade-offs. Explaining to people who don't read code what we're giving up, why, and what it will cost later.
- Building less. Questioning whether the requested feature solves the problem, and sometimes arguing against building it.
- Owning the call. Deciding without someone validating each step, and owning it when it turns out wrong.
Building a product from scratch again is what made the difference obvious to me. In 2022, alone on the delivery app, I made every decision and nobody paid for any of them. Building a multi-tenant marketplace automation platform from zero, with integrations, payments and order flows, I was again making most of the decisions. The autonomy was the same. The weight was completely different: there were paying customers on the other side of each one.
So the question moved again:
"What problem are we actually trying to solve?"
That question is uncomfortable. Sometimes the answer is that the feature someone asked for doesn't solve the problem they have. Sometimes it's "I don't know yet, and here's how we find out." Either way, the answer is now mine to give.
Confident, and stuck
There's a part of this stretch I didn't expect. The more I grew, the more confident I felt. And, at the same time, the more stuck I felt. I could deliver. I knew my way around the stack, the systems, production. That confidence was useful for making decisions, but it was bad at showing me where I had stopped growing.
What got me moving again wasn't a new technology. It was people. I started getting more help from more experienced engineers: staff engineers, managers, seniors, people with as many years of experience as I have years of age. That taught me a lot, and very little of it was about syntax. A good part of what I described above, the questions I ask before writing anything, I learned by watching how they worked.
The other direction surprised me more. Helping people at the very start of their careers helped me too. Explaining something is the fastest way to find out whether you really understand it, and answering someone else's questions forces you to organize what you know. It shaped how I study, how I apply what I learn, and how I pass it on.
I think that's the part of seniority that doesn't fit on a CV: learning from the people ahead of you while helping the people who are just starting, at the same time.
The problem changes
If I had to put the whole shift in one sentence, it would be this: the code stays hard, but it stops being the bottleneck.
What becomes hard instead:
- Figuring out what actually needs to be built. Requirements arrive incomplete, and the missing part is usually the important part.
- Choosing trade-offs. Every option costs something. The job is to know what, and to say it out loud.
- Working inside existing systems. Most real work isn't greenfield. It's changing something people depend on while they're using it.
- Predicting consequences. The schema you pick today decides what's cheap and what's painful for the next two years.
- Working with uncertainty. Deciding with 60% of the information because waiting for 100% costs more.
- Balancing speed and quality. Not as a slogan. As a concrete choice, on a specific feature, this week.
- Understanding impact. A frontend error in checkout isn't a UI bug. It's lost revenue that no technical dashboard shows.
None of these replace code. They sit on top of it. You still need to write the query, the component, the migration. But the hardest hour of the week is rarely spent in the editor anymore.
The market notices
It took me a while to see that the market was tracking the same shift, just with a delay.
Early on, the way you get evaluated is mostly legible from a CV: which technologies you know, which frameworks, which projects you built, how many years you have, whether you can implement a feature. That makes sense. At that stage, those really are the best signals of whether you can execute.
As the scope grows, those signals stop being enough. The things that start to matter are harder to list:
- ownership: whether things you touch get finished, including the parts after deploy
- autonomy: how much direction you need to move a problem forward
- decision-making, and whether you can explain the decisions you made
- architecture, not as diagrams but as consequences
- impact on the product, not just output
- communication, especially about trade-offs and risk
- comfort with ambiguity
- the ability to connect a technical choice to what the business is trying to do
What changes isn't only how you're evaluated. It's the kind of opportunity that shows up. Scoped tasks turn into open problems. "Can you build this?" turns into "can you figure out what we should do here?" The trust is different, and so is the responsibility that comes with it.
I want to be careful here. This isn't a promise about salary or a guaranteed career path. Markets differ, companies differ, and plenty of people are underrated or overrated for reasons that have nothing to do with any of this. It's just what I've noticed: perceived value tends to follow the size of the problems you're trusted with, more than the length of your stack list.
What changed for me
If you compare my stack from 2022 with my stack today, it grew. But that's not what changed. I could list every technology I've used and it wouldn't explain the difference between how I worked then and how I work now.
What changed is where I start. I used to start with the implementation. Now I start with the problem, and I try to be suspicious of it before I trust it. I ask what happens after deploy, who notices when it breaks, and what we're giving up. I've stopped treating "nobody objected" as "it was right."
I also changed what I consider done. Done used to mean merged. Then it meant deployed. Now it means the problem is actually solved, and I can explain why this solution and not another.
And most of that I didn't figure out alone. It came from people who had been there before me, and from having to explain it to people who hadn't yet.
I'm still learning
I don't think I've arrived anywhere. There are things I'm still working on: knowing when good enough really is enough, telling the difference between a trade-off and a shortcut, and saying "I was wrong" faster than I used to. I still learn most of it the same way: from the people further ahead, and by explaining it to the people just starting.
And I'm pretty sure some of what I believe today will look naive to me in a few years, the same way my first architecture decisions look now. That's fine. I think it's the whole point.
Code will keep being part of the job. I still enjoy it, and I don't trust engineers who stop caring about it. But at some point, writing code stops being the hard part. The hard part is everything around it: understanding the problem, choosing what to give up, and owning the result.
That's the part I'm still learning.
