I wrote a post on avoiding switching costs a few years ago. The notion was simple. If a company knows that you're forced to use them, they can raise prices on you drastically and you will have to pay it. This is the standard danger of a monopoly, which companies can attempt to become by setting prices so low that all competitors go out of business. The interesting thing about software vendors is that they can get you into this state without being a monopoly.
If you're using a software vendor, odds are that what you need is pretty complex and beyond what you want to build yourself. It makes sense to have a vendor deal with that complexity while your team focuses on the core competancies of your own software.
Odds are also good that there are no standards for the system you are purchasing. That means every vendor can have their own custom implementation of the solution. That requires you tailoring your integration of the needed functionality to that vendor. A simple interface/class may not cut it. Core assumptions of what data is available and how it is delivered is built into that integration. Switching vendors means rewriting huge swathes of code or recreating a bunch of processes.
This happened to me in my original post on switching costs. We had built all of our infrastructure management scripts around a third party. All of our processes such as code deploys revolved around that third party. Our vendors new pricing may have increased 10x, but the burden of rebuilding everything we had meant we were forced to pay it. That vendor likely knew that about most of their customers.
You may think you're good at picking vendors and this won't happen to you. The problem with that thought is you only know the *current* state of that vendor, who runs it, how they operate, and their culture. All that can change with a new CEO, a new board, new investors, or an acquisition. Customers of VMWare are experiencing what I experienced, though at a larger scale than where I was.
I've argued in the past for completely avoiding vendor lock-in. Sure I use AWS, but I limit myself to stuff like EC2, S3, RDS, SQS, etc. Those are services that have an exact equivalent in other clouds. In fact, I switched from Google Cloud to AWS in 2019 and it was relatively painless. A web server is a web server and a relational database is a relational database, regardless of the cloud provider. Things like Lambda and App Engine are a lot more difficult to migrate to a different cloud provider so I avoided them.
The problem with the idea of avoiding vendor lock-in is that sometimes you have no choice but to accept it. Maybe your CEO signed a deal that requires using a particular vendor. Maybe building something yourself would take weeks or months and you want to get a product out sooner. Maybe a single vendor is how everyone in your industry communicates/integrates and is basically required to even have a business. There are a ton more potentially good reasons.
What can be done if we're stuck with a vendor that will have leverage over us? The answer really depends on the technology involved, the industry involved, etc. There are some core steps to contingency planning though. What would happen if you needed to switch vendors? How hard would it be? You don't need to spend hours or days coming up with specs for that scenario. Simply asking the question alone and a 15-30 minute discussion about it is usually enough to help prepare. As you build out the system, having asked that question makes you think about it with every decision made. The preparation will be built into the system design no matter how complex the integration.
One tactic I use quite often is creating my own spec for any data that comes from a vendor. No matter what fields the vendor returns and in whatever format, I write an ETL into the schema that I have defined. The rest of my codebase then interacts only with my schema. This way it doesn't matter that Vendor A calls something one thing while Vendor B calls it something else. It also doesn't matter if Vendor A returns all the data you need in an API call while Vendor B requires several lookups. It's all abstracted into the ETL. This doesn't work with every vendor, but it works with enough of them to keep my risks manageable.
It sounds simple enough, but that's why it is worth asking the question "How hard would replacing a vendor be?" You may be able to come up with a simple solution that wasn't obvious at first. I've certainly seen a lot of systems suffer because we needed to replace 1000+ calls to a function that was tailored to the data a vendor returned.
I'm curious though, what issues have you had to deal with regarding vendors? What have you found effective in mitigating lock-in?