How to minimize IoT vendor and technology lock-in
Going from connected product number 0-1, 1-2, or 2-n without sufficient reflection and realignment has been the root cause of every bad decision we’ve seen in building IoT offerings. Shortsighted technical architecture, expedient implementation choices, and premature investment in scale routinely lead to detrimental vendor lock-in that prohibits the change required to bolster a product’s success.
Businesses making a long-term commitment to creating connected products travel through three specific phases:
- 0-1: getting the first connected product on the market (not prototype)
- 1-2: connecting the second product (not line extensions)
- 2-n: connecting subsequent products and/or line extensions
Longitudinal experience and observation of those companies who’ve made the complete journey has taught us where and how sloppiness during 0-1 creates a punitive and avoidable cost burden when going from 2-n. The most dangerous problems begin with lock-in.
Shackling your new connected product’s operations to a specific vendor is a decision that’s made casually during a product’s intimidating build phase with minimal regard to its post-build operational life. Product owners are motivated to get things done, and so make choices that propel them to the finish line.
Similarly, service providers aim to integrate as quickly and tightly as they can to get you to and across that finish line. Professional services vendors earn their margin from your action (go, develop, build!), and their presence in your program helps drive action over (non-billable) consideration. Your “doneness” harms their bottom line. Software product and SaaS companies dig in to help drive you to an operational state—their margin comes from operating their invested capital, not from customer setup, service, or acquisition.
The ideal customer for both IoT product and services vendors is an operating connected product program under continuous development. Sound familiar?
The answer isn’t to see your vendors as predators or necessary evils, they’re just businesses like yours with deeply-specific skills and offerings. Like all relationships, boundaries make vendor relationships healthy. Long-term mastery of your fate begins with a deliberate ownership matrix of each facet of your connected product program:
- Who owns what?
- What stays in?
- What goes out?
- Why?
Name names and cover all the abbreviations (EE, ME, FW, BA, UX, FE, BE, QA, etc.) and all the services (cellular, platform, frameworks, etc.) As a bonus, with this defined, your vendors will understand what you want and who you need them to be with far greater clarity.
Modern software is rarely one whole thing, built from scratch and completely custom. Applications today use libraries and services created to solve specific problems. In IoT this means any seemingly singular service you’re buying also includes services from third-party cloud providers, platforms, communication services, and other integrations. That’s how a Twilio outage can take out your IoT platform and leave both you and your platform provider completely powerless.
Leveraging this is an excellent way to get from 0-1 quicker, but binds your IoT offering to your vendor, who’s in turn bound to their vendors. If you’re imagining an interconnected web of fragile relationships, breathe deeply, the answer is plan, don’t panic. Like all disaster response, you need insight and a mitigation plan for each core scenario:
Insight collection:
- Understand how your vendor’s application is architected
- Monitor its health and status as your normally would
- Monitor the health of its dependencies
- Monitor performance (in addition to health) where possible
Mitigation planning for each vendor-provided service:
- What’s your substitute?
- What’s your customer service plan?
- What’s your implementation path?
The anxiety of vendor lock-in drops considerably if you’re not relying on black boxes.
If you cast your connected product program’s vision forward, the whats underpinning your product infrastructure matter far less than its hows. How your choices were made and integrations were done will impact your cost to operate or change services during the 1-2 or 2-n phases. Those hows occur in several areas of your system, creating traps along the way:
- Hard-coded services
- App and firmware SDK implementation
- App and firmware SDK and framework aversion
- Programming language selection
Each brings specific perils that you can avoid.
Take the example of routing your connected product traffic through a service at example.com. As more code is written, and more customers are connected, your reliance on example.com grows. Now assume you want to change to a new service at new-example.com. That means:
- Changing your code. (You can deploy an update, but it means rewrite and retesting everything.)
- Making sure everyone gets the update. (Less easy, but still possible. Don’t forget shelf-stock!).
- Knowing when everyone is changed over so you can cancel example.com. (Harder. You have to plan for this.)
Ultimately, you’ll be paying for example.com and new-example.com until you’re comfortable stopping one service, and possibly creating a terrible experience for customers who have yet to transition.
The answer lies in creating traffic proxies. In an oversimplified example:
- Your application connects to example.yourdomain.com which you control
- example.yourdomain.com redirects to example.com
- You control if/when you want to redirect example.yourdomain.com to new-example.com
Broadly, owning where your application traffic gets routed in this manner will save re-coding, vendor-lock in, service duplication, and above all, a possible horrible customer experience.
SDKs (software development kits) are a code shortcut used by engineers to connect your application to an existing service like a cloud platform, telecom service, etc. In our example from above, example.com has a convenient tool that makes integrating their service functions directly into your code easy for your developers. It’s tempting, especially early when speed-to-done feels important.
SDKs are tools provided by product and SaaS vendors to expedite development and lock you in.
Using your vendor’s SDK means you probably can’t protect your future with a simple redirect. They’re designed to be tightly integrated to the service they support and your application’s functions.
The answer will require three things:
- Concise understanding of the SDK functions so you can properly abstract them.
- Code that sits between your application and the SDK making replacement less complex.
- Solid documentation of how the SDK should be handled to avoid accidental integration.
Bonus caution! Any of the following sentences from an external development or service vendors are indicators of future lock-in and should be thoroughly interrogated:
- We use ____ to speed development. Ask “what do I save, and what am I committing to?”
- We always recommend ____ to solve this problem. “Always? When would you not recommend this?”
- We have a relationship with ____ service. “What is the nature of this relationship?”
Again, lock-in doesn’t happen at the operational level out of malice or pure greed (hey, the greed’s strategic), your implementers push for it for speed and familiarity.
If you took “avoid SDKs” as the point of the previous section, here’s the seemingly contradictory counterpoint.
Engineering teams skillfully talk themselves into building custom integrations in lieu of an SDK. In this particular echo chamber, your fight will be against the confirmation bias inherent in the question of “what do we NOT get with _____ SDK?”
Avoiding an SDK is more problematic than integrating one without abstraction for a few reasons:
- You’ll be rebuilding something that already exists and is likely fine. Most differences between an SDK and your roadmap can be ironed out with some straightforward compromises.
- Your version won’t be as well documented. SDKs are designed to be used and so are well documented.
- You’re chaining your application code to a service provider’s feature changes and schedule. Vendor changes are often preceded by SDK changes, you won’t have that notice or that stability.
- Service switches will require a deeper examination of your code to look for hidden integrations and undocumented dependencies.
The answer to the SDK/not-SDK decision will rest on two precepts:
- Can you adequately isolate an SDK (as outlined above)?
- Do you understand the development, operational, and financial ramifications of saying no to the SDK?
The answer to 1 is usually “yes”. The answer to 2 is, inevitably, “no.”
Language selection is probably the most emotional topic in software engineering. Yet application language selection also tends to be one of the most off-handed but impactful decisions made in a product’s lifecycle. Too often we’ve seen an application built in ______ because it’s what the team knows, it’s what people are talking about, etc. only to have avoidable, crippling limitations emerge later.
If you’re at this phase, these discussions should raise your eyebrows:
- Full stack Javascript (or any language) evangelists. There are viable arguments for having all aspects of your application coded in the same language. For simpler things this makes sense. More often, backend and frontend layer requirements necessitate different language choices. Remember: coding competency does not equal layer expertise.
- Native vs non-native app zealots. This one is usually irrelevant and often exhausting. Purveyors of each camp can make compelling cases for their position. Use your judgment here—there’s usually no wrong answer, but remember that native apps mean two codebases whereas non-native apps usually mean three!
- Emerging language trendsetters. We watched a successful and promising SaaS product slowly buckle under the weight of code written in Elixir/Erlang. Haven’t heard of those? That’s not surprising. Try staffing for them. Don’t get fancy with code languages unless your market demands it or your industry requires it. Any other reason is headache fuel.
- Framework fanatics. These conversations should be minimized at all costs-mostly because they’re only relevant to the people coding that layer, and only until the next-better framework comes along. Lock everyone with an opinion in a room and don’t let them out until they achieve unanimity.
Getting past the hype and/or the emotion of this choice is much harder than it should be. The answer: language selection requires a matrix of questions that can only be answered by multidisciplinary engineers or seasoned architects who are trained to make informed decisions.
Start with a simple table that outlines service > language > reason for this choice. For each, you should be able to test your answers against service > alternative language > reason not to make this choice. Your decisions could include available skills, existing libraries or adjacent services, etc. If your team can’t provide viable alternatives, they aren’t experienced enough.
Additionally, for every choice, ask the following.
- “How will the selection of _____ impact our compute resource needs and costs as we scale?” Some languages require significant resources when traffic spikes. Engineers will know this, “devs” may not.
- “Are we able to apply some rigor around _____ to ensure our application is maintainable?” In many languages, there are many paths to the same solution making coding faster and supporting harder. Don’t be lulled by over-flexibility. It costs more.
- “By choosing _____ are we limiting or cutting off future integrations, alterations, or enhancements?” Under-extensibility is almost worse than over-flexibility. Your code should solve current and future problems. If you can’t promise that, you're choosing the wrong language.
- “What is the staffing landscape for _____ and how is it projected to change?” Is there an Erlang expert on this plane!?
Take the time to get this one right. Your team can guide you to options but they likely have strong opinions based on familiarity and competence (and therefore self-worth). Expertise and diligence will get you to the best possible answer.
Next Mile possesses an abundance of experience mitigating operational issues caused by build-phase lock-in. If you’re stuck, contact us, we’ll help you chart a path and march forward against your headwinds.