The problem nobody warns you about Last quarter I migrated a side project from AWS S3 to Cloudflare R2. Should've been a two-hour job. It took an entire Saturday. The migration itself wasn't the issue. R2 is S3-compatible, so the protocol mostly worked. The pain came from everywhere else in my codebase — the helper that uploaded user avatars to S3, the worker that streamed CSV exports, the cron job that backed up Postgres dumps. Each one had been written against a slightly different abstraction. Some used the AWS SDK v3 directly. Some used a wrapper I'd built in 2022 and forgotten about. One particularly cursed module used presigned URLs through a fetch call I'd copy-pasted from Stack Overflow. If you've ever tried to swap object storage providers in a real codebase, you know this feeling. The provider is rarely the problem. Your own coupling is. Why this keeps happening The root cause is that every storage provider ships an SDK that reflects its own internal model rather than a shared standard.…