My First Experience as a Tech Lead: What Led Me There, What I Would Do Differently, and Lessons Learned
From Senior Dev to Crisis Tech Lead: How a High-Stakes Data Migration Redefined My Career
toString() is hands-on AI + architecture for busy engineers. If you want runnable blueprints subscribe—it helps me keep shipping these.
It was January 2017. Four months earlier, in September, I relocated to London from Milan to join a consulting company focused on e-commerce. As a senior developer, I quickly became part of a project for one of the world’s largest e-commerce retailers.
From September to January, our team composed of one tech lead, two senior developers (myself included), and two juniors was responsible for implementing new features on the UK website. Everything went smoothly. I already knew the commerce engine platform (SAP Commerce), having used it for the previous three and a half years. The team was supportive, and despite the move, I adapted effortlessly, thanks to my ability to quickly demonstrate value to both my peers and management and the great team that I was part of.
One of the tasks that left a strong impression was supporting the design of the Google Tag Manager (GTM) Data Layer.
What Is the Data Layer?
The dataLayer is a JavaScript object that acts as a structured bridge between your front-end and GTM. Instead of relying on brittle DOM scraping, the front-end pushes structured event and variable data into the dataLayer upon user interactions.
Business Implication:
This establishes a standardized, reliable source of truth for tracking events, ensuring consistency across marketing and analytics platforms.
Technical Example:
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'addToCart',
ecommerce: {
currencyCode: 'GBP',
add: {
products: [{
name: 'Organic Cotton T-Shirt',
id: 'SKU-12345',
price: '25.00',
brand: 'EcoWear',
category: 'Apparel/T-Shirts',
variant: 'Blue',
quantity: 1
}]
}
}
});
This foundation enables scalable, secure, and high-performance data collection, empowering business teams to decide what user behaviour to track.
Although the design was nearly complete when I joined, I proactively reviewed it. Having extensive experience with this platform and with the integration of this 3rd party, I knew where issues had historically surfaced especially mismatches between what the business wanted to track and what was the data actually available at page level.
Often, requirements included data not directly tied to page interactions but vital for final reporting dashboards. SAP Commerce is a sophisticated, monolithic platform that covers modules such as:
Product Catalogue & Content Management
Price & Tax Engine
Personalization & Search
Promotions & AI-powered Merchandising
Order Management & Fulfilment
Because of its complexity, even minor changes—like moving data from back-end layers to the front end—could have wide-reaching implications across modules, increasing dev and testing efforts.
Indeed, a common challenge when designing and estimating this type of work is verifying whether the data that needs to be pushed to the dataLayer is already available on the page or can be provided easily. If not, we can face scenarios where existing implementations must be modified just to fetch and expose the data, sometimes solely for Data Layer purposes.
This was exactly the situation I encountered. What I needed was a quick verification: mapping the required data against the data already available. This simple step allowed me to confirm whether the original estimation accounted for the extra work required to make missing data accessible.
It turned out to be a valuable intervention as it found few missing and allowed to present a more accurate review and timeline to the client. It demonstrated both proactivity and technical skill to the wider project team—an impression that became particularly important soon after, when a new phase of the project entered a critical stage.
That reputation for spotting risks early and finding practical solutions didn’t go unnoticed. When the client’s largest and most complex initiative Operation Unity needed additional technical leadership, I was asked to join the team.
At the time, each country ran its own separate codebase, which was costly to maintain. The goal of Operation Unity was to consolidate everything into a single codebase, still using the same underlying commerce platform, but enhanced with multi-country and multi-catalogue capabilities. This meant every feature could be enabled or disabled at the country level. It was a major undertaking, and my team was responsible for all the integration points and the data migration.
When I joined, the project was already in motion. Back then, I had limited experience with planning initiatives of that scale—things like estimation, dependency mapping, and progress tracking. I didn’t take the time to read the contract or understand exactly what had been committed to. As a senior developer, my focus was on delivering my part: completing tasks, making integrations work, writing tests, running demos, and supporting teammates when needed.
After about two months, the integration work was nearly complete—but the toughest phase was about to begin: Data Migration. The plan stated we had one month to complete it, but that was essentially all the plan said—there were no assumptions documented about how it would be done. The project’s architect at the time told me the approach was to use Impex with Groovy scripts to export the data, and then another set of Impex and Groovy scripts to import it.
The architect’s proposed approach relied heavily on SAP Commerce’s ImpEx framework, so understanding its capabilities and limitations was critical. For context, ImpEx (Import/Export) in SAP Commerce is a specialized data exchange format and tool for importing or exporting data to and from the platform’s database. It uses a declarative syntax to perform CRUD operations on type system objects.
INSERT_UPDATE Product;code[unique=true];name;catalogVersion(catalog(id),version)
;product1;Sample Product;Default:Staged
;product2;Another Product;Default:Staged
How It Works:
Header line: Defines the type and attributes to process.
Modifier syntax: e.g., [unique=true] or (catalog(id),version) for complex mappings.
Data lines: Semicolon-separated values corresponding to header columns.
Data Model Transformation Examples
1. Attribute Mapping Transformation
Source system has productTitle
→ Target SAP Commerce needs name
:
INSERT_UPDATE Product;code[unique=true];name[translator=de.mycompany.ProductTitleTranslator]
;SKU001;${productTitle}
2. Reference Resolution
Source provides category names → Target needs CategoryPK references:
INSERT_UPDATE Product;code[unique=true];supercategories(code,catalogVersion(catalog(id),version))
;product1;electronics:Default:Staged,accessories:Default:Staged
3. Value Transformation with Custom Translators
Source has boolean strings → Target needs Boolean objects:
INSERT_UPDATE PriceRow;product(code)[unique=true];currency(isocode)[unique=true];price;unit(code)
;product1;USD;99.99;pieces
;product1;EUR;89.99;pieces
5. Multi-Value Attribute Handling
Source has comma-separated keywords → Target needs collection:
INSERT_UPDATE Product;code[unique=true];keywords[collection-delimiter=,]
;product1;"electronics,mobile,smartphone"
Key transformation capabilities:
Cell decorators:
[translator=...], [default=...], [unique=true]
Collection handling:
[collection-delimiter=,]
Reference resolution:
(attribute1,attribute2)
Custom processors: Java classes implementing
ImportProcessor
Conditional logic:
[if-empty=...]
,[ignore-null=true]
In short, ImpEx gives you a powerful way to map between heterogeneous data models while preserving referential integrity—something essential when migrating data between environments or consolidating multiple systems into one..
As you can imagine, for a company of this scale, migrating the data of three countries—UK, Korea, and Taiwan—was no small feat. The datasets included PII, order history, transaction records, etc., making it both technically complex and highly sensitive. Building not only the scripts but also a testing framework robust enough to give the right level of confidence was no easy task. And, at least from what I could see at the time, there was no clear plan in place.
Being a direct and straightforward person, after just a few days on the task, I began voicing my concerns to the team—highlighting that we were not equipped to meet the deadline. Despite this, the project’s architect kept reassuring me that he would soon step in to help and that we’d still deliver on time.
Weeks went by. Problems started surfacing—data inconsistencies, unclear mapping approaches, and mismatches between source and target systems. Just as I was about to escalate the issue beyond the architect, I learned that he had left the company… and was now unreachable.
Shit! - This was my reaction
What I did next was go straight to the project’s Delivery Manager and share my concerns. He freaked out. His first question was, “How long do you think it will take?” I asked him to give me one day, and I’d come back with an answer.
That day, I reviewed everything I possibly could—starting with the commercial aspects of the project, then looking at the time already spent on migration. From there, I tried to build a model to forecast how long the full migration might take. It was my first time doing this kind of activity, and the stakes were high: big responsibilities, big money, and the project’s reputation on the line.
Surprisingly, I didn’t feel pressure in a bad way—I felt electrified. I knew I was in a pivotal position and nothing to loose, at the end it wasn’t my fault, and I wanted to make it count. So I laid out my plan.
The next day, I returned to the Delivery Manager. Keep in mind, this was just seven months after moving to London, so I was still learning the culture and figuring out how to navigate situations like this. But one thing I’ve always trusted is my empathy—the ability to read the emotional state of the person in front of me. He was clearly worried, maybe even terrified. That’s when my communication shifted from a warning… to an offer.
“We need two additional months, two more people—people I choose—so three of us in total including me. And I can step into the architect/tech-lead role to complete the project.”
It was a bold ask, but it came with a plan. I explained how we would re-prioritize the work, break it into achievable milestones, and run daily validations so we’d spot issues early. I would take ownership of the migration strategy, keep him informed with daily updates, and cut through bottlenecks by making quick technical decisions when needed.
It wasn’t about blaming how we got here—it was about charting a path to get us out.
He agreed almost instantly. The relief on his face was clear. In that moment, I went from being “the senior dev raising alarms” to “the person trusted to lead the solution.” And that shift changed everything—not just for the project, but for how I started to see my own career path.
But before we could put my plan into motion, there was one more hurdle: getting the client and SAP, the other system integrator, on board. That meant presenting the reality of the situation, owning where we had gone wrong, and showing them exactly how we’d turn it around.
From that day forward, I wasn’t just coding or testing. I was leading the migration: mapping every data set, documenting each transformation, creating validation checkpoints, and designing rollback strategies for every stage. The work was intense, but now we had clarity, accountability, and momentum.
The PM came back to me and said, “Marco, we need to speak with the client and communicate your plan. You’ll need to convince them—and SAP, the other system integrator helping with the migration.”
I knew that earning their trust was critical. In a moment like this, the only approach that could work was complete honesty. I acknowledged that, as a company, we had messed up. But I also made it clear that I had a plan—one that made sense, that I could explain in detail, and that they could get behind. And that’s exactly what happened.
Once we had the green light, I chose my two team members—both people I’d worked with before, trusted 100%, and knew were not only incredibly hard-working but also a lot of fun to work with. We reviewed the plan together, agreed on the approach, and got to work.
Part of the plan involved more than just code and scripts—it required alignment with the local teams in each country. So I flew to Korea and Taiwan to explain, face-to-face, how the migration was going to work, what the expectations were, and how we would collaborate. I also worked with them to assess and manage their bandwidth, making sure they could support the process effectively without being overwhelmed.


Those visits turned out to be a game-changer. Meeting in person allowed us to create real bonds, build mutual trust, and clear up misunderstandings instantly instead of letting them drag on over email. That trust became invaluable later—especially during the intense testing phase—because when issues came up, we already had the rapport and the confidence in each other to solve them quickly.
With the team assembled, the plan approved, and the local teams aligned, we went full speed ahead. Every day had a clear set of priorities, and we stuck to them relentlessly.
We broke the migration into smaller, verifiable chunks—each one passing through our validation framework before moving to the next. This approach saved us from the nightmare scenario of doing one massive migration and only discovering critical issues at the very end.
The local teams in Korea and Taiwan were instrumental here, running the test cases we’d designed together and giving us rapid feedback on any anomalies. Because we’d already built trust in person, there was zero hesitation when changes were needed. If something didn’t work, we discussed it openly, fixed it fast, and moved forward without blame.
The work was intense—long days, late nights. With our UK base, the client’s management team in the US, and local teams spread across Korea and Asia, we were essentially covering all time zones. I remember days that felt endless—just as I thought I could wrap up, someone on the other side of the world would be starting their day with new questions. It was chaos at times; even the few hours of sleep I managed were often followed by waking up to an inbox overflowing with urgent emails.
And yet, despite the exhaustion, there was a sense of purpose and alignment I’d rarely felt before.
After weeks of disciplined execution, we hit our revised timeline. The migration went live with minimal issues, and the post-launch stability confirmed that the extra effort, planning, and collaboration had paid off. It wasn’t flawless—there were a few minor defects, as there always are—but we had delivered one of the most complex data migrations I had ever been part of, and we had done it under immense pressure.
For me, it was more than just a technical win—it was a turning point in my career. I had stepped into an architect-level role under pressure, navigated high-stakes client conversations, and led a distributed team through a critical delivery.
Lesson Learned
Looking back, this experience taught me far more than just the technicalities of data migration. It shaped how I approach high-pressure situations and leadership challenges. Here are the key takeaways I wish I’d known earlier:
Don’t Wait to Raise Concerns
If you see a risk, speak up early—especially in large, complex projects. Delaying bad news never makes it better. When I realised the migration plan was unclear and unrealistic, voicing it quickly gave us a fighting chance to change course.
Turn Warnings Into Offers
Simply saying, “We have a problem” is not enough. Come with a solution, resources you need, and a clear path forward. This transforms you from a messenger of bad news into a problem-solver people can trust.
Face-to-Face Matters—Especially in Distributed Teams
My trips to Korea and Taiwan weren’t just about process alignment—they built trust. That trust paid off later when testing got tough and we needed immediate, honest collaboration.
Break Big Problems Into Small, Verifiable Wins
Large migrations fail when everything is left to the end. Chunking the work, validating each step, and having rollback strategies saved us from costly surprises.
Empathy Is a Leadership Skill
Reading the emotional state of the people you’re working with—whether it’s a panicked delivery manager or a client under pressure—helps you adapt your message so it’s heard, not just said.
Every career has those defining moments where you either step back or step up.
This was mine—and it shaped the way I lead to this day.
If you enjoyed this story and found the lessons useful, consider subscribing so you don’t miss future posts. I’d also love to hear your thoughts—have you ever been thrown into a high-stakes project like this? Drop a comment, subscribe and share your experience.