Production Technology Risks: Planning for When Dependencies Fail
A few months ago I was building a data versioning system for EMM (Expert Memory Machine) - a platform where AI agents automatically classify files. I chose lakeFS as Git for S3, MinIO as local object storage, PostgreSQL for metadata.
Everything worked beautifully. Tests green. Deployment ready. Then a colleague asked: "What if lakeFS becomes obsolete in 5 years?"
That question made me stop. Not to think about features or performance, but about what actually matters: what happens when technology becomes obsolete?
Why this question matters¶
Code lives longer than we think when we write it.
That Python 2.7 script I wrote in 2015 and forgot about? Still running in production. Python 2.7 EOL was 2020. But the script works. Now we need to migrate because security patches ended.
That MongoDB 2.4 instance nobody touched? Also running somewhere. MongoDB 2.4 released in 2013. Support ended in 2016. But someone forgot to upgrade it, and it quietly runs until someone tries connecting with a new driver.
Dependencies become obsolete. Projects close. Companies change licenses. Startups go bankrupt.
When choosing technology, you need to think not "does this work now" but "what happens in 5 years".
Three components, three risk levels¶
My system has three key dependencies: PostgreSQL, MinIO, lakeFS. They look similar (databases, storage, versioning), but their risks are completely different.
PostgreSQL - when risk is practically zero¶
PostgreSQL exists since 1986. It's older than most people using it.
Age: 35+ years.
Backing: PostgreSQL Global Development Group + dozens of enterprise sponsors.
Adoption: Apple, Instagram, Spotify, Reddit, Netflix, thousands more.
Release cycle: major version annually, 5+ year support.
Community: 1000+ active contributors.
If PostgreSQL disappears tomorrow, we all have much bigger problems than EMM database. The entire internet falls.
Risk: 🟢 practically zero.
Alternatives: MySQL, MariaDB - also mature, similar API, easy migration through SQL standard.
For PostgreSQL, asking "what if it becomes obsolete" seems absurd. It won't. It is the standard.
MinIO - when risk exists but is controlled¶
MinIO appeared in 2014. 10 years is decent. GitHub shows 47k stars, active development, stable releases every 2-3 weeks.
But there's a catch. In May 2021 MinIO changed license from Apache 2.0 to AGPLv3.
AGPLv3 means: if you deploy MinIO and provide network access - you must open-source all your code. The entire system. Including proprietary business logic.
For enterprise this is a red flag. For open-source projects it's fine. For production deployment, commercial license costs money.
But here's what matters: MinIO is S3-compatible storage. Keyword: S3-compatible.
S3 isn't just an AWS service. It's an industry standard. S3 API is what everyone understands. Boto3, AWS CLI, s3cmd - all work with any S3-compatible storage.
This means: if MinIO AGPLv3 becomes a problem, I can replace it with:
AWS S3 - managed service, 99.999999999% durability, expensive egress but zero ops.
Cloudflare R2 - S3-compatible, zero egress fees, 50% cheaper than AWS S3, managed service.
Wasabi - S3-compatible storage, cheaper than Amazon, predictable pricing.
Ceph - self-hosted S3-compatible, complex but powerful.
Migration looks like this:
# Old config
S3_ENDPOINT=http://minio:9000
S3_ACCESS_KEY_ID=minioadmin
S3_SECRET_ACCESS_KEY=minioadmin123
# New config (Cloudflare R2)
S3_ENDPOINT=https://[account].r2.cloudflarestorage.com
S3_ACCESS_KEY_ID=your_r2_key
S3_SECRET_ACCESS_KEY=your_r2_secret
Code doesn't change. Boto3 doesn't know the difference. Same S3 API.
Risk: 🟡 medium (license change, single vendor), but easily mitigated through S3 standard.
My solution: MinIO for local development (Docker Compose), Cloudflare R2 for production. Zero AGPLv3 complications.
lakeFS - when risk is higher but manageable¶
lakeFS is a young project. Founded 2020. Age: 5 years.
GitHub: 4.4k stars. Funding: $31M Series B from VCs. Company: Treeverse (Israeli startup, ~50 people).
Production adoption: Lockheed Martin, NASA, Microsoft, Adobe. Good sign. Enterprise companies don't take unstable tools.
But the fact remains: it's a startup. Startups can close. VCs can stop funding. Project can become unmaintained.
What then?
Here I did two things.
First: abstraction layer¶
I didn't write import lakefs everywhere in agent code. I created abstraction:
# storage_backend.py
class StorageBackend(ABC):
@abstractmethod
def write_file(self, path: str, content: bytes): pass
@abstractmethod
def read_file(self, path: str) -> bytes: pass
class LocalStorageBackend(StorageBackend): ...
class LakeFSStorageBackend(StorageBackend): ...
class S3StorageBackend(StorageBackend): ...
Agent code uses StorageBackend, not LakeFSBackend. The difference is critical.
If lakeFS becomes obsolete, I don't rewrite agents. I create DVCStorageBackend or DeltaLakeStorageBackend, and change config:
# Was
OUTPUT_BACKEND=lakefs
LAKEFS_REPO=emm-vault
# Became
OUTPUT_BACKEND=dvc
DVC_REPO=emm-vault
Agent code stays unchanged. This is the power of abstractions.
Second: data ownership¶
lakeFS doesn't store my data. It stores it in S3.
lakeFS architecture looks like:
lakeFS API → S3 (data) + PostgreSQL (metadata)
DATA lives in S3 bucket as content-addressed objects. METADATA (branches, commits, refs) lives in PostgreSQL.
This means: if lakeFS disappears tomorrow, my data doesn't. It's in S3. I can read it directly. Can write migration script. Can switch to another versioning tool.
I'm not locked into lakeFS proprietary format. Data in S3 is regular files. PostgreSQL is regular tables.
Data ownership is insurance against vendor lock-in.
Principles for production dependencies¶
From this experience I formed several rules for choosing production dependencies:
1. Older technology = lower risk¶
PostgreSQL (35 years) > MinIO (10 years) > lakeFS (5 years).
This doesn't mean "never use new technologies". It means "know the risk and mitigate it".
If technology is young (<5 years) - need abstraction layer. If middle-aged (5-15 years) - need to monitor project health. If older (15+ years) - can rely on stability.
2. Open source gives options¶
All three components are open source. PostgreSQL (PostgreSQL License), MinIO (AGPLv3), lakeFS (Apache 2.0).
Open source means: if maintainers disappear, I can fork the project. Or someone else forks. Community maintains it.
Proprietary software doesn't give this. When vendor closes, software is dead. No source code = no options.
3. Standards beat features¶
MinIO isn't the fastest object storage. But it's S3-compatible. That matters more than performance.
S3 API is a standard. Boto3, AWS SDK, s3cmd - ecosystem is huge. If I use S3 API, I can switch backends without code changes.
Features come and go. Standards remain.
4. Abstraction layers are investment, not overhead¶
storage_backend.py takes 400 lines. Seems like overhead. "Why abstract if I know I'm using lakeFS?"
Because in 3 years you DON'T know what you'll be using. lakeFS might become obsolete. Better tool might appear. Requirements might change.
Abstraction layer is insurance. You pay 400 lines now to avoid paying 10,000 lines rewrite later.
5. Data ownership > convenience¶
There are tools that "simplify life" through proprietary formats. "Just use our platform, we handle everything!"
This is convenient short-term. Disaster long-term.
If your data is in proprietary format, you're locked in. When vendor raises prices, you pay. When vendor closes, you're screwed.
lakeFS stores data in S3 (standard) + metadata in PostgreSQL (standard). I can export anytime.
Data ownership means: I control my data, not the vendor.
Monitoring strategy - early warning system¶
Choosing right technologies isn't enough. Need to monitor their health.
I created monitor_tech_health.py - script that checks every 6 months:
def check_project_health(repo: str) -> dict:
# GitHub API calls
stats = {
"stars": get_star_count(repo),
"commits_last_year": get_commit_count(repo, since="1y"),
"releases_last_year": get_release_count(repo, since="1y"),
"open_issues": get_issue_count(repo, state="open"),
"contributors": get_contributor_count(repo)
}
return stats
Metrics for lakeFS: - Stars: 4,400+ (growing) - Commits/year: 500+ (active) - Releases/year: 50+ (2-week cycle) - Open issues: ~150 (manageable) - Contributors: 50+ (good diversity)
Red flags (when to sound alarm): - Stars falling or stagnant - Commits < 50/year (project dying) - No releases 6+ months (abandoned) - Open issues > 500 (overwhelmed maintainers) - Contributors < 10 (bus factor risk)
If red flags appear - time to prepare migration.
Fallback plans - what to do when things go bad¶
Even with right technologies and monitoring, need fallback plan. What to do if project closes?
Scenario 1: lakeFS becomes unmaintained¶
Plan A: Freeze on last stable version. Self-host indefinitely. lakeFS is stateless, easy to deploy.
Plan B: Fork repository (Apache 2.0 license allows). Maintain internally or find community fork.
Plan C: Migrate to alternative: - DVC (Data Version Control) - 13k GitHub stars, mature - Delta Lake - Databricks backing, enterprise-grade - Apache Iceberg - Netflix, Apple, Adobe backing - AWS S3 Versioning - native feature, limited capabilities
Plan D: Fallback to direct S3 without versioning. Functionality lost, but system works.
Migration script (sketch):
def migrate_from_lakefs_to_s3():
# Export latest commit from lakeFS
files = lakefs.list_files(repo="emm-vault", branch="main")
for file in files:
content = lakefs.read_file(file.path)
s3.write_file(bucket="emm-vault", key=file.path, data=content)
# Switch backend
os.environ["OUTPUT_BACKEND"] = "s3"
os.environ["S3_BUCKET"] = "emm-vault"
Migration time: few hours for 10GB vault. Acceptable.
Scenario 2: MinIO AGPLv3 becomes problem¶
Just change endpoint config:
# docker-compose.yml - development
services:
minio:
image: minio/minio
# production - Kubernetes ConfigMap
data:
s3-endpoint: "https://[account].r2.cloudflarestorage.com"
Code doesn't change. Boto3 works. Migration = config change.
Scenario 3: PostgreSQL... well PostgreSQL won't fail¶
But if migration were needed:
# Export
pg_dump lakefs_db > lakefs_backup.sql
# Import to MySQL (if needed)
# Or to any other SQL DB
SQL standard means portability.
Real-world examples - what happened to other projects¶
This isn't a theoretical exercise. Technology obsolescence happens regularly.
CentOS - when reliable OS disappears¶
CentOS existed 17 years (2004-2021). Industry standard for enterprise Linux. Thousands of production servers.
In 2020 Red Hat announced: CentOS 8 EOL in 2021 (instead of 2029). Migration to CentOS Stream (rolling release) or RHEL.
Hundreds of thousands of servers needed migration. Decommission dates, emergency planning, testing.
Companies relying on CentOS stability got 1 year for migration. Those with abstraction (containerized workloads) migrated quickly. Those with hardcoded CentOS assumptions suffered.
Docker Hub rate limits¶
2020: Docker Hub announces rate limits for anonymous pulls. 100 pulls / 6 hours for anonymous, 200 for authenticated free users.
CI/CD pipelines globally started failing. "Error: toomanyrequests: too many failed login attempts for username or IP address".
Companies using Docker Hub directly in production pipelines - broken builds. Those with registry mirror or private registry - unaffected.
Dependency on free service became bottleneck overnight.
MongoDB license change¶
2018: MongoDB changed license from AGPLv3 to SSPL (Server Side Public License). More restrictive than AGPL - cloud providers can't offer MongoDB as-a-service without contribution.
AWS response: created DocumentDB (MongoDB-compatible) but without MongoDB source code.
MongoDB compatibility became fragmented. Some features work on MongoDB, don't work on DocumentDB.
Companies locked into MongoDB API forced to pick platform or pay MongoDB Atlas fees.
Conclusions from production experience¶
Technology risks aren't "what if" questions. They're "when" questions.
Dependencies become obsolete. Startups close. Companies change licenses. Free services introduce rate limits.
The right approach:
Choose mature technologies where possible. PostgreSQL exists 35 years for a reason.
For new technologies - add abstraction layer. storage_backend.py protects from lakeFS obsolescence.
Use standards, not proprietary APIs. S3 API gives flexibility, MinIO-specific API gives lock-in.
Data ownership is critical. If vendor controls data format, you're locked in.
Monitor project health. Red flags give early warning for migration.
Have fallback plan ready. When lakeFS fails, I know what to do.
For EMM I have: - PostgreSQL (zero risk) - MinIO → Cloudflare R2 migration ready (config change) - lakeFS → S3/DVC migration documented (abstraction layer works)
If all three dependencies disappear tomorrow, I can restore system in 1 day.
That's the goal of proper architecture: minimize blast radius when dependencies fail.
Technology choices today determine operational burden in 5 years. Choose wisely.
Related: Data versioning with lakeFS, Kubernetes deployment
Author: Igor Gorovyy
Role: DevOps Engineer Lead & Senior Solutions Architect
LinkedIn: linkedin.com/in/gorovyyigor
Risk analysis summary¶
| Component | Age | Risk Level | Mitigation Strategy |
|---|---|---|---|
| PostgreSQL | 35 years | 🟢 Very Low | Standard SQL, easy migration |
| MinIO | 10 years | 🟡 Medium | S3 API, Cloudflare R2 ready |
| lakeFS | 5 years | 🟡 Medium-High | Abstraction layer, fallbacks |
Worst-case recovery time: 1 day to restore full functionality with alternative backends.