Your Stakeholders Have Stakeholders (And They All Want Different Things)
So Iâve spent months doing archaeology. Iâve mapped the dependency graphs. Iâve identified why the migration stalled. Iâve proposed a plan.
Now comes the hard part: getting dozens of engineers to actually adopt it.
Oh, and did I mention this is all happening during COVID lockdowns? While food delivery demand is exploding? While product managers are setting aggressive timelines? While engineers are scrambling to hit weekly build cuts?
Yeah. Welcome to the politics of platform engineering.

The Problem With Having a Plan
I presented the architectural plan. Got buy-in from the Senior Director. Engineers agreed it was a good idea. All the checkboxes youâd want to tick, ticked.
And then nothing happened.
Engineers had features to ship, right now, during a pandemic. Feature velocity became the only priority anyone cared about. âWeâll migrate later when we have timeâ became the refrain, and later never came.
The problem wasnât technical. Every engineer I needed to convince had their own stakeholders. Product managers with roadmaps. Tech leads with quarterly goals. Directors measuring feature delivery. Users who needed the app to work. None of those stakeholders cared about Swift.
The Constraint That Changed Everything
The Senior Director gave us one non-negotiable constraint: âYou cannot rewrite the app.â
This sounds obvious, but it shaped everything. We couldnât create a parallel âSwift versionâ of the app, or pause feature development for a big rewrite. We couldnât break active development happening in parallel, and we couldnât force teams to stop what they were doing and migrate.
We had to migrate in place. Incrementally. While dozens of engineers kept shipping features. And hit the weekly build cut. And not break production.
Oh, and do it during a global pandemic while food delivery demand was exploding.
No pressure.

The COVID Context
Lockdowns. Food delivery goes from ânice to haveâ to âessential service.â Usage spikes. Teams are underwater.
Product managers: âWe need these features yesterday.â
Engineers: âWeâre already working weekends to hit the build cut.â
Me: âHey, want to refactor your moduleâs dependency graph?â
You can imagine how well that went.
I wasnât just competing with feature work. I was competing with crisis mode. Every hour an engineer spent on migration was an hour they werenât shipping features that users desperately needed.
The math was brutal. A feature could ship in days and impact millions of users. Migration work might take weeks and benefit⌠future engineers? The mythical âafter we migrate everythingâ state?
Features won every time.
The Memory of Past Pain
But even before COVID, there was resistance. And it had a name: Swift 3.
The Swift 3 migration had happened a few years earlier. It broke everything. Thousands of compiler errors. Weeks of work to fix. Code that worked perfectly fine suddenly needed rewrites because the language changed.
Engineers remembered the pain. The lost weekends. The features that slipped. The incidents from rushed fixes.
So when I showed up saying âwe should migrate to Swift,â the reaction was⌠skepticism.
âDidnât we already try this?â âIs this going to be another Swift 3 situation?â âWhat happens when Swift 6 comes out and breaks everything again?â
And honestly? Valid questions. I couldnât promise Swift wouldnât change again. I couldnât promise the migration would be painless. All I could promise was that not migrating meant staying stuck forever.
Thatâs a hard sell when people are busy.
The Incident Tax
Incidents were expensive, and that made everything harder.
We had aggressive feature flagging for new features. But legacy Objective-C code? Much of it couldnât be easily feature flagged. Patterns from 2014 didnât have clean on/off switches.
Which meant: if you broke something during migration, it could ship to production. And production incidents were costly. Eng hours to fix. User impact. Postmortems. The scrutiny.
So engineers were risk-averse. Understandably.
Every engineer ran the same calculation. They could write a new feature in Swift using existing interop layers: safe, familiar, ships fast. Or they could migrate core Objective-C code: risky, time-consuming, might cause incidents. The safe path won every time.
The interop layers the mobile platform team had created solved the immediate problem (write new code in Swift) but prevented the actual migration (convert old code to Swift).
Weâd created a comfortable middle ground that let everyone avoid the hard problem.

The Multi-Level Buy-In Game
I had buy-in from the Senior Director. That didnât mean I had buy-in from anyone else.
Engineers saw extra work. Tech leads supported it in principle, as long as their teams didnât take on more than they already had. Product managers wanted to know if it would delay their roadmap. Directors needed to see how it impacted quarterly metrics.
Each level had different concerns, different incentives, different definitions of success. The Senior Director cared about technical debt and long-term maintainability. Directors cared about quarterly delivery and team velocity. Product managers cared about shipping features. Tech leads cared about not burning out their teams. Engineers cared about not working weekends.
All valid concerns. All in tension with each other.
I needed to convince all of them simultaneously, with different arguments for each level. Having a plan isnât enough. You need a strategy for adoption.
The Objective-C Loyalists
And then there were the Objective-C loyalists.
Yes, they existed. Engineers who genuinely preferred Objective-C over Swift. Who saw the dynamic runtime features as advantages, not liabilities. Who found Swiftâs strictness annoying rather than helpful.
They werenât wrong, exactly. Objective-C has real strengths. The runtime is powerful. Interop with C and C++ is seamless. The language is stable (because itâs finished evolving).
Swift? Still changing. Stricter. Breaking changes between versions. Less mature tooling in some areas.
So when I pitched âmigrate to Swift,â these engineers heard âthrow away a perfectly good tool for a newer, buggier one.â
I couldnât change their minds by arguing Swift was objectively better. I had to show that the migration was inevitable and help them see the path forward.
Thatâs a very different conversation than âSwift is better, letâs migrate.â

The Weekly Build Cut
Every week, there was a build cut. A deadline. Code needed to be merged, tested, and ready to ship.
This weekly rhythm created constant pressure. Engineers were always working toward the next cut. Always trying to land features. Always fixing last-minute issues.
In that environment, migration work was a luxury. Something youâd do âafter the build cutâ or âwhen things calm down.â
Things never calmed down.
The weekly cycle reinforced feature work over migration work. Features had deadlines. Migration didnât. And in a world of competing priorities, deadlines win.
The Strategy That Actually Worked
So how do you get adoption in this environment?
You donât mandate it. You donât create a top-down edict. You donât say âeveryone must migrate by Q3.â
You lead by example. You make migration the path of least resistance.
The mobile platform team took ownership of the Core modules. We didnât ask feature teams to do the hard work. We did it ourselves. We migrated the Core modules that everything depended on, built the bridging layers, and created the patterns. Feature teams could keep shipping. Weâd handle the foundation.
Every migration we did, we documented. Tips, tricks, patterns that worked, pitfalls to avoid, examples of successful migrations. We didnât hoard knowledge. We showed our work, made it visible, made it easy for others to copy.
When teams had questions, we helped. When they hit blockers, we unblocked them. When they wanted to migrate, we enabled them. But we never said âyou must migrate now.â We said âwhen youâre ready, hereâs how.â
We improved tooling too. Built linters that caught common issues. Created automated migration scripts. Reduced friction. Eventually, migrating became easier than fighting with the old architecture. When that happened, teams started choosing to migrate on their own. Not because we told them to. Because it made their lives easier.
And when teams did migrate, we highlighted them. Shared their success. Made them heroes. This created social proof. Momentum built slowly. But it built.

The Turning Point
The turning point came months later. A feature team hit a nasty bug in legacy Objective-C code. They spent days debugging it. Finally realized: the bug was in a pattern that the migrated Swift version had already fixed.
The tech lead said: âScrew it, weâre migrating to the new architecture.â
They did. It took a week. But after that week, their velocity actually improved. Fewer bugs. Cleaner code. Better tooling support.
Other teams noticed. âWait, migration makes things faster?â Word spread. More teams started migrating. Not because we mandated it. Because they saw the value.
You canât force adoption in platform engineering. You can only create the conditions where adoption becomes inevitable.
What I Learned
Executive buy-in is necessary but not sufficient. You need buy-in at every level, and each level responds to different arguments.
Crisis mode kills long-term work. When everything is urgent, nothing thatâs âjust importantâ gets done. You have to find ways to make long-term work relevant to short-term goals.
Past pain creates present resistance. The Swift 3 migration left scars. You canât ignore that history. You have to acknowledge it and show how this time is different.
Risk aversion is rational. When incidents are costly and migration is risky, people will avoid migration. Reducing the risk matters more than telling people to be brave.
Competing incentives are the real blocker. Engineers want one thing. Product managers want another. Tech leads want a third. Your job is to align incentives, not override them.
And above all: do the hard work yourself. Show itâs possible. Make it visible. Make the new way easier than the old way. Donât appeal to principles. Appeal to pragmatism. When migration is easier than staying put, people migrate.
Whatâs Next
So here I am, months into convincing dozens of engineers across many teams that migration is worth doing.
Weâve migrated some of the Core modules. Weâve created patterns. Weâve shared examples. Early adopters are starting to migrate.
But weâre still in that uncomfortable middle state. Half the app is Swift. Half is Objective-C. And every change we make has to work in both worlds.
Now comes the fun part: actually doing the migration at scale. While keeping the app stable. While teams keep shipping features. While not breaking production.1
Footnotes
-
Narrator: Something was definitely going to break. Stay tuned for Part 3. âŠ
No comments yet. Share on Mastodon and see your comment or write a post on your blog if you support Webmentions
No reposts yet. Share on Mastodon and see your repost or write a post on your blog if you support Webmentions
No likes yet. Share on Mastodon and see your like or write a post on your blog if you support Webmentions
No bookmarks yet. Share on Mastodon and see your bookmark or write a post on your blog if you support Webmentions
Powered by Webmentions