Skip to content
ExponaBLOG
ENGINEERING CRAFT · DAY 057 / 100

What 'senior' actually means: what developers should know

It was never about years of experience.

Expona Admin7 min read

I've been writing code for over a decade, and I've worked with developers who reached "senior" status in four years and others who never got there in fifteen. What 'senior' actually means has nothing to do with how long you've been around. It's about the choices you make when the path forward isn't clear, how you multiply the capability of everyone around you, and whether your teammates trust you to think, not just type.

At day 57, you're far enough in to know that seniority isn't a title or a salary bracket. It's a set of behaviors that separate people who move the needle from people who just move tickets.

Judgment: knowing what not to build

The first senior thing I learned wasn't how to architect a system. It was how to say no to it.

Early in my career, every problem felt like a nail and every framework was a hammer. We'd pitch building a custom notification service when a queue plus a cron job would work. We'd refactor shared utilities into a monorepo because we could, not because we needed to. The worst part: nobody stopped us, because we were competent enough to finish what we started.

Judgment is knowing the difference between a real problem and a version of a problem you haven't solved yet. It's walking into a design meeting and asking "what do we lose if we don't do this?" instead of "can we do this?"

I was working on a trading platform where we wanted to stream live price updates to thousands of connected clients. The engineering team jumped to WebSockets with custom buffering logic. Before coding, I asked: How many users actually need sub-100ms updates? The answer: about 2% during market hours. We built WebSockets for that 2%, and the rest got polling. The system was simpler, cheaper to scale, and we shipped three weeks earlier.

That's judgment. It's the ability to hold multiple solutions in your head and pick the one that costs the least and buys the most optionality.

Good questions that show judgment:

  • What problem are we solving, and for how many users?
  • What's the simplest thing that could work?
  • What breaks if we're wrong, and how bad is that?
  • Are we solving a problem or are we avoiding boredom?
  • What do we defer without losing our shot at this?

Ownership: running toward ambiguity

Ambiguity breaks junior developers. It breaks some mid-level ones too. Senior people run toward it.

When requirements are vague, when the stakeholders haven't agreed, when nobody's really sure what the next quarter looks like, that's when ownership shows up. It's not about being fearless. It's about being the person who doesn't wait for permission to clarify.

I joined a CRM rebuild where the product spec said "faster search." That's it. No performance targets, no scale numbers, no user feedback. A junior dev would have started coding. A mid-level dev would have asked their manager what to do. I sat with product, data, and customer success for a day and came back with a spec: P95 latency under 300ms for accounts with up to 50,000 contacts, with a full-text index strategy and a three-month runway.

That ownership moved us from "someday we'll be faster" to "we will ship this, measurably, by this date."

Ownership also means staying with a problem after you ship it. It means owning the errors, the scale limits, the tech debt. It means being on call for your own code, not as punishment, but as part of understanding what you actually built.

When you own something, you think about rollback strategies before you deploy. You think about what data you need to see if it breaks. You think about the person who'll be paged at 3 AM if this goes sideways.

Multiplication: the team improves because you're there

This is the hardest one to explain, but it's the most important. A senior person makes their team better not just by being good, but by making other people good.

I had a developer, Priya, who was solid but hadn't shipped a service by herself. Instead of just reviewing her code, I sat with her through the design phase. Not to tell her the answer, but to ask questions: How will this fail? What metrics do we watch? How do we know it's working? She designed something conservative and solid. When it went wrong (it always does), she was ready for it because she'd thought about what could break.

A year later, she was unblocking three other engineers because she actually understood the system. That multiplication happened because I spent time teaching her how to think, not just what to think.

Multiplication shows up in different ways:

  • In code reviews: You explain why something matters, not just that it's wrong.
  • In pairing: You narrate your thinking so people learn your process.
  • In architecture: You design systems that other people can extend, not just systems that you alone understand.
  • In hiring: You bring people up to your level instead of surrounding yourself with people you're comfortable next to.
  • In retrospectives: You name what worked and why, so the team can repeat it.

The test is simple: if you left tomorrow, would your team be stronger or weaker? Not just because you're gone, but because of what you left behind. Good teams get better after their senior people leave, because those people built the capability into the team itself.

Communication: explaining complex systems simply

Senior developers can explain systems that shouldn't be explainable. That's not because they're smarter. It's because they've held the full picture long enough to know which parts matter.

I once had to explain why our order processing pipeline was slow. The system was complex: Kafka topics, SQS queues, a distributed saga pattern, eventual consistency trade-offs, retry logic. A junior engineer wrote a document that listed all those things. Smart document, impossible to understand.

I wrote it this way:

Orders move through three stages. Stage one: capture and validate (under 100ms, synchronous). Stage two: inventory and payment (up to 10 seconds, we can retry). Stage three: fulfillment (can take hours, but the customer sees confirmation right away). We're slow because we're doing stage two synchronously when we could do it async. The trade-off: the customer waits a bit longer, but we can handle 10x more orders.

That's communication. It's knowing what detail matters and what detail distracts.

For technical communication, I do this:

  1. State the problem in one sentence.
  2. Say what we're doing about it in one sentence.
  3. Explain why we can't just do the obvious thing.
  4. Walk through one concrete example, step by step.
  5. Name the trade-offs we're making.

Here's an example documenting a retry strategy:

typescript

// Payment processing retry strategy
// Problem: External payment APIs fail (network, rate limits, temporary outages)
// Solution: Exponential backoff with jitter, max 5 retries over 24 hours
// Trade-off: Customer might not know status for minutes, but we won't lose orders

interface RetryPolicy {
  maxAttempts: number;           // 5
  baseDelayMs: number;           // 1000 (1 second)
  maxDelayMs: number;            // 300000 (5 minutes)
  backoffMultiplier: number;     // 2
}

// Attempt 1: immediate
// Attempt 2: 1s + jitter
// Attempt 3: 2s + jitter
// Attempt 4: 4s + jitter
// Attempt 5: 8s + jitter (capped at 5m)
// If all fail, create a support ticket and notify customer

function calculateDelay(attempt: number, policy: RetryPolicy): number {
  const exponentialDelay = policy.baseDelayMs * Math.pow(policy.backoffMultiplier, attempt - 1);
  const cappedDelay = Math.min(exponentialDelay, policy.maxDelayMs);
  const jitter = Math.random() * cappedDelay * 0.1; // 10% jitter
  return cappedDelay + jitter;
}

The code is one part. The why is the senior part. You explain why we retry (external systems fail), why exponential backoff (give the system time to recover), why jitter (prevent thundering herd), why a cap (we can't wait forever).

Common mistakes

Mistaking speed for seniority. "I built this in two days" isn't evidence of seniority. "I built this in two days and it scales to 100k requests/second and the team can extend it" is closer.

Confusing knowledge with leadership. Knowing more frameworks than everyone else doesn't make you senior. Teaching people how to learn new frameworks does.

Owning the problem, not the outcome. Some people claim ownership but then blame external factors when things go wrong. Senior people own the outcome, which sometimes means working around broken dependencies, unclear requirements, or limited budgets.

Explaining from the top of the mountain. "This is obviously the right architecture" shuts down thinking. "Here's why I chose this over X, Y, and Z" opens it up.

Treating ambiguity as someone else's job. The question "shouldn't product clarify this?" is a junior move. The senior move is to clarify it yourself, and then loop in product to confirm.

Key takeaways

  • Seniority is about judgment: knowing what not to build, not what to build faster.
  • It's about ownership: running toward ambiguity instead of waiting for permission.
  • It's about multiplication: your team is better because you're there, not despite your presence.
  • It's about communication: explaining complex systems so other people can understand and extend them.
  • It's not about years. It's about decisions. You can demonstrate it in two years or miss it in ten.
  • The real test: if you left, would the team be stronger or weaker? Would they have better judgment, more ownership, clearer thinking?
ShareXLinkedInReddit

Found this useful? Support the writing.

Buy me a coffee
Written by
Expona Admin
Site administrator

Comments

Loading comments…

Leave a comment

Comments are reviewed before they appear. Be kind and stay on topic.

Related articles