// HubWorked on 2015–now

Ten years of building: the patterns that keep repeating

SMB commerce, an e-commerce marketplace, a travel platform, an AI startup, cloud infrastructure — different domains, the same lessons. A map of everything I've written, and what I'd tell my 2015 self.

#career#softwareengineering#distributedsystems#architecture

I started my career in 2015 building REST APIs for an SMB commerce platform: orders, inventory, billing, purchase orders. Since then I’ve worked on checkout, wallet and refund services at an e-commerce marketplace, an email platform sending around 20 million personalized emails a day at a travel company, a feature-store platform at an AI startup, and large-scale cloud infrastructure.

Different domains, different stacks. The same lessons kept coming back. This post collects them, and links to everything I’ve written about each.

Change running systems one reversible step at a time

Splitting monoliths, moving data between systems, upgrading platforms underneath live traffic: the approach that works is a series of small, reversible steps. Doing it in one go is where these projects get into trouble.

Assume the network will lie to you

Distributed systems fail partially: a request times out after it succeeded, a message arrives twice, a dependency slows down instead of failing. Designing for that up front is far cheaper than discovering it in production.

The non-code half of senior engineering

The further I’ve gone, the more of my impact has come from things other than code: how incidents are handled, how decisions get made and recorded, which debt gets paid, and whether my team is a queue or a platform.

Built in the open

Most production work lives behind NDAs, so I try ideas out in public projects too:

What I’d tell my 2015 self

  1. Read the old code before you judge it. Most “weird” code encodes a lesson someone learned the hard way. Find out which one before deleting it.
  2. Learn the database properly. Indexes, transactions, isolation levels, locking. A surprising number of scaling problems turn out to be data problems.
  3. Make failure boring. Timeouts, retries, idempotency, rollbacks. The systems that are calm during incidents are the ones designed around failure from the start.
  4. Measure before and after. “It’s faster now” convinces nobody; “p99 went from 1.2 s to 300 ms” convinces everyone.
  5. Automate what you repeat — and then hand the automation to others. The biggest jumps in team capacity I’ve seen came from turning expert-only tasks into safe self-serve tools.
  6. Write it down. Design docs, decision records, runbooks, and now this blog. Writing is how one engineer’s judgment scales to a team.

If you’re working on similar problems — distributed systems, platform engineering, AI infrastructure — I’d like to hear from you: email me or find me on LinkedIn.

// TL;DR, in one picture
0d2d4d6d8d10d0.5d2dfix a typo1d4dadd one field1d6dbump a library0.5d14d ↑"should be quick"Estimate vs actual, daysestimateactualEvery sprint, plotted honestly.ayushwing.com