tolgacelik.net
All posts
·3 min read

Your Code Works Locally. Now What?

"Works on my machine" isn't a meme — it's a culture problem. What's the distance between when you think a feature is done and when it's actually done? A senior's end-to-end shipping checklist.

deploymentdevopsci-cdobservabilityjunior-senior

For a newer developer, when a feature is "done" is clear: it runs locally, the screen shows what you wanted, you've simulated a user flow or two and everything looks fine. "Great, let's merge, I'm done here."

As the years go on you discover that moment is actually less than halfway there. Done done is a different list entirely. This post is that list.

The "works on my machine" pattern

Something that runs locally can still fail in production. Why:

  • Data difference — 10 rows locally, 10 million in prod. An N+1 that's 2ms locally is 12 seconds in production.
  • Traffic difference — one user vs 10,000 concurrent. Race conditions, locks, queue backpressure appear.
  • Environment difference — Node 20 locally, Alpine-based 18 in the container. Tiny diff, big break.
  • Dependency difference — Redis 6 locally, Redis 7 cluster mode in prod. Commands aren't identical.
  • Network difference — localhost vs Istio mesh. Timeout behavior shifts.

At least one of those five will surprise you — almost every time. A disciplined dev expects it and plans for it.

What "actually done" looks like — my version

A feature earns the "done" label only once it clears these gates:

1. Tests

  • Unit tests — for the core logic
  • Integration tests — real DB, real HTTP, real timing
  • Occasional e2e — the happy path should work in a real browser at least once

An untested feature is not shipped, regardless of how well it ran locally. End of story.

2. Observability

When this breaks, plan in advance where you'll look:

  • Enough logs? Specifically at inputs, failure branches, and meaningful state transitions?
  • Metrics? (request count, latency, error rate — at minimum)
  • Tracing? (at least on the critical paths in production)

"We shipped, it broke, we can't tell what broke" is the most common incident pattern I see. The fix isn't more logging — it's logging in the right places before you need them.

3. Alarm

If the feature breaks, somebody needs to know. A Sentry error that'll trigger, a Grafana threshold alarm — have a concrete answer to "how will we find out this failed?"

Manually testing isn't an alarm. A customer emailing you isn't an alarm.

4. Rollback plan

If something goes wrong after shipping, can you undo in under 5 minutes? Is there a feature flag? Is reverting to the prior version one command? Can the DB migration roll back?

"I don't know" shouldn't be the answer here. Know the answer before you ship.

5. Documentation (bare minimum)

Nobody enjoys writing docs, but at least write for your future self. One README line: "This feature solves X in context Y, talks to Z endpoint." Three months later, you'll thank yourself.

6. Security sweep

  • User input validated?
  • Authorization checks in place (not just authentication — authorization)?
  • Sensitive data accidentally logged or exposed?
  • Rate limit / abuse protection considered?

Senior-level habit: ask these four questions no matter how small the feature seems.

7. Performance sanity

What happens at scale? Fine at 1,000 users — what about 100,000? N+1 queries? Missing indexes? How many downstream API calls?

Even at big companies, plenty of devs just "wait for the surprise." Don't be that dev.

The senior's "done" test

My internal test is:

If I shipped this and went on a two-week vacation, would the rest of the team know what to do if it broke?

If yes, it's done. If no, it's not — it was just merged.

Takeaway

"Works locally" is the starting line, not the finish line. The real work happens after the code is written: tests, observability, alarms, rollback, security, performance, docs. What makes senior engineers senior is largely this layer.

Five more minutes on this list prevents five hours of incident response. The math is simple.

ShareLinkedInX
Get the next one in your inbox

Long-form notes on distributed systems, production stability, AI-assisted shipping. No spam, easy to unsubscribe.

Email only. Stored on this server. Never sold or shared.

Comments

No comments yet. Be the first.

Leave a comment

Never shown publicly. Only used if I need to reply.