Skip to content
Back to Architecture Decisions

Vendor Lock-in

Assess and minimize the cost of leaving a vendor, without refusing to use vendors at all.

Why

Vendor lock-in is the cost of switching to a different provider — measured in engineer-months. Some lock-in is fine (S3 API is a de-facto standard, leaving is cheap); some is severe (DynamoDB proprietary API, leaving is a rewrite). Refusing all lock-in means building everything yourself (expensive, slow); embracing all lock-in means one vendor price hike doubles your bill. The discipline is to assess lock-in per component, accept cheap lock-in freely, and add portability layers (thin abstractions, standard formats) only where lock-in is severe and switching is plausible. Blind 'no lock-in' is as expensive as blind 'all-in on one vendor'.

When

When selecting any vendor-managed component. Takes 1 hour to assess. Revisit if the vendor's pricing or roadmap changes.

How

1. For the vendor component, identify the proprietary surface:
   - API (standard like S3, or proprietary like DynamoDB?)
   - Data format (standard like SQL/JSON, or proprietary?)
   - Integrations (does it tie into other vendor services?)
2. Estimate switching cost: engineer-months to move to the alternative
   - < 1 eng-month → low lock-in, accept freely
   - 1-6 eng-months → moderate, add a thin abstraction if switching is plausible
   - > 6 eng-months → high, either avoid or consciously accept + document
3. For high lock-in, negotiate: multi-year price lock, data export guarantees
4. Keep data in standard formats (SQL, JSON, Parquet) even in proprietary stores
5. Avoid vendor-specific orchestration (Lambda functions tied to Kinesis) where a standard (containers + queue) works
6. Document the lock-in assessment per component in the architecture doc

Example

Components and lock-in:
  S3 (storage): standard API (MinIO compatible), switching cost < 1 eng-week → LOW
  DynamoDB (KV): proprietary API, switching to Postgres = 3 eng-months → MODERATE
  Lambda (compute): proprietary event bindings, switching to Fargate = 2 eng-months → MODERATE
  Bedrock (LLM): proprietary model API, switching = 1 eng-week (prompt portability) → LOW

Actions:
  - S3, Bedrock: accept freely (low lock-in)
  - DynamoDB: add a thin DAO layer so queries could swap to Postgres
  - Lambda: keep functions small + container-based for portability
  - Data: all in JSON/Parquet, never vendor-specific formats

Common Problems

  • ⚠Treating all lock-in as equal — S3 lock-in is negligible (standard API), DynamoDB lock-in is real (proprietary); assess per component, not globally.

Best Practices

  • ✓Accept lock-in for commodity services (storage, queue) where the API is standardized; fight it for services that embed your business logic (workflow engines).
  • ✓Keep a 'vendor exit runbook' for any high-lock-in component — even if you never use it, writing it reveals the true switching cost.

Related Resources