Your team wraps every provider call behind an in-house abstraction so services could move - what does owning it cost?
answer
- you swapped one dependency for another
- a wrapper is a product, not a layer
- owners, releases, deprecations, support rota
- platform features arrive twice
- one backend means it is unproven
basics
~20 sAn in-house abstraction becomes a product with its own maintainers, release process, bug queue and upgrade debt. Every platform capability and every consumer request now arrives twice: once in the platform, once in the wrapper that hides it.
solid answer
~40 sThe third seam is one **you** design: internal interfaces for storage, queueing, secrets and identity that services call instead of calling the platform. It does make a dozen services uniform, and it is the only seam that can hide differences the other two cannot. The cost is that the wrapper is now a dependency exactly as the platform is - it needs owners, versioning and releases, documentation, a deprecation path for its own interfaces and somebody to answer for it during an incident. Every new platform capability is unavailable until someone extends it, so the wrapper's backlog becomes the platform's roadmap, and a team blocked on that backlog will reach around it. You did not remove a dependency; you swapped a vendor's for one you now staff.
go deeper
Recall that an in-house abstraction is ordinary software your organisation owns. It needs maintainers, releases and documentation just like anything else you would have bought instead.
Explain the mechanics of the lag: a capability the platform ships cannot be used until the wrapper exposes it, it is reviewed and released, and consumers upgrade. That queue is the wrapper's real cost.
Demonstrate the judgment that a wrapper with one backend is unproven, and that blocked teams bypass it. Argue for narrow interfaces, a legal escape hatch, and evidence from a second implementation.
Treat the wrapper as a product decision with a standing budget. Fund two or three seams where fan-out and proprietary weight justify them, and be willing to retire the layer when its consumers go away.
## The third seam When no open interface exists and self-running the component is too expensive, the remaining option is an abstraction of your own: internal interfaces - an object-storage interface, a queue interface, a secrets interface, a workload-identity interface - that the services call instead of the platform. The platform's client sits behind that boundary, and in principle a second implementation could be dropped in later. This is the most powerful seam, because it is the only one that can hide differences nobody else standardised. It is also the only seam whose entire cost lands on your own team, forever. ## The wrapper is a product, not a layer Once a dozen services depend on it, the abstraction has every property of a product you buy: 1. **Owners.** Someone must be named, and must still be named after they change teams. 2. **Releases and versions.** Consumers upgrade at different times, so you need versioning, a compatibility policy and a way to ship a fix without a coordinated push across a dozen repositories. 3. **Documentation.** An interface nobody can read is re-implemented badly by each consumer. 4. **A support path.** During an incident, somebody has to answer whether the fault is in the wrapper or beneath it - and that question now exists, where before it did not. 5. **Deprecation.** Your own interfaces age. Removing one is the same migration problem in miniature, with you as the vendor. 6. **Testing.** The wrapper must be tested in its own right, including against the failure behaviour of what it wraps. ## The two structural costs Beyond staffing, two costs are structural and show up on every wrapper that survives a year. **Feature lag.** A capability shipped by the platform is unusable by consumers until someone extends the wrapper, reviews it, releases it and the consumers upgrade. The wrapper's backlog has quietly become the roadmap for everything behind it, and the team that owns it becomes a scheduling dependency for teams it does not report to. **The bypass problem.** A team blocked by that lag and under its own deadline will call the platform directly. That is not misbehaviour; it is the rational response. What matters is whether the bypass is sanctioned and recorded or unsanctioned and invisible. An abstraction that forbids bypass without being able to keep up produces a codebase where nobody knows which services are actually portable. | | Thin wrapper (two or three narrow interfaces) | Thick wrapper (a facade over the platform) | |---|---|---| | What it protects | the few dependencies that would dominate a move | everything, in principle | | Feature lag | limited to the wrapped surfaces | every capability, every time | | Maintenance | affordable for a small team | a standing team of its own | | Bypass pressure | low, and easy to allow explicitly | constant, and usually denied | | Evidence it works | one interface can be given a second backend | almost never tested end to end | ## The proof problem The uncomfortable part is that a wrapper with exactly one implementation behind it is **unproven**. It was written against one platform, so it inherits that platform's assumptions about latency, error taxonomy, consistency and limits without anyone deciding to encode them. The interface may look neutral and still be unusable against anything else. The only strong evidence is a second implementation carrying real traffic for at least one interface. A second backend exercised only in tests is weaker evidence, but far better than an argument about naming. What is not evidence at all: a design document asserting neutrality, an absence of provider names in the type signatures, or a high count of services that adopted it. ## When the wrapper is worth it It pays where the wrapped interface is genuinely proprietary, where the interface is narrow enough to specify in a page, and where many services use it - because the fixed running cost is then spread across all of them and the rewrite it avoids multiplies by the same factor. One storage or secrets interface used by a dozen services can justify a maintainer. It does not pay where the platform already implements an open interface (you would be wrapping a seam you already have), where only one or two services touch the dependency (rewriting them later is cheaper than maintaining a layer for years), or where the proprietary capability *is* the reason you chose the platform - an abstraction over it either hides the value you are paying for or reproduces it badly.
- How would you know whether the wrapper is actually portable?Only by running a second implementation behind it. Until at least one interface has two backends carrying real traffic, the wrapper encodes the assumptions of the single platform it was written against and its leaks are undiscovered. A second backend exercised in tests is weaker evidence, but still far stronger than an argument about naming.
- What keeps a wrapper from becoming the bottleneck on every other team's roadmap?Keep it narrow and make bypass legal. Wrap only the two or three dependencies where a move would genuinely be expensive, publish an escape hatch that exposes the underlying client for everything else, and record where that hatch is used. A wrapper nobody is allowed to go around becomes a queue everybody waits in.
- Is a wrapper ever cheaper to own than the lock-in it prevents?Yes, where it is thin, where the interface it hides is genuinely proprietary, and where many services use it. One narrow storage or secrets interface across a dozen services can pay for its maintainer. A facade over an entire platform almost never does, because the lag and the staffing scale with the surface.
Building your own universal adapter so any plug fits does not get you out of the adapter business - it puts you in it. You now own a catalogue that has to be updated every time a new socket appears, and everyone waits for your next release.
saying these in an interview costs you the question
- Claims a wrapper removes the provider dependency rather than adding one you staff
- Assumes a wrapper with only one implementation behind it is proven portable
- Ignores that each new platform capability must be re-exposed before teams can use it
- Thinks blocked teams will wait for the wrapper rather than call the platform directly
- Treats wrapper maintenance as a one-off build cost instead of a permanent commitment
- Wraps the whole platform when only two or three interfaces ever justified it