Moving off AWS S3 without rewriting your app
The storage line is cheap. The transfer line is the one that grows.

Open your AWS bill and the storage line looks reasonable. Scroll down to data transfer. That number climbs every month, and it has little to do with how much you keep. It tracks how often people read your files.
S3 bills you twice. Once to hold the bytes, and again every time someone downloads them. Teams budget for the first charge and get surprised by the second.
Say you host user uploads, product images, or backups on S3. Storage might run you twenty dollars a month. Then a launch goes well, traffic triples, and your transfer-out line jumps to three hundred. You stored nothing new. People read what was already there.
What "S3-compatible" gives you
The S3 API became the way software talks to object storage. Your SDK, CLI, backup tool, and CI pipeline all speak it. A provider that implements the same API lets those tools point somewhere else without a rewrite.
For most apps, the code change looks like this:
# before
s3 = boto3.client("s3", region_name="us-east-1")
# after
s3 = boto3.client(
"s3",
endpoint_url="https://s3.neviri.com",
aws_access_key_id=KEY,
aws_secret_access_key=SECRET,
)That is the change: a new endpoint and your keys. get_object, put_object, list_objects_v2, presigned URLs, and multipart uploads all keep working, because they hit the same API. The aws CLI works the same way with --endpoint-url. So does rclone, s3cmd, and most backup software that already targets S3.
Where the cost drops
AWS charges around nine cents per gigabyte to move data out to the internet, and the price holds near there until you pass terabytes. Neviri charges $0.072 per GB and includes 100 GB free per account before metering starts.
Run the math on a busy month. A site serving two terabytes of images out of S3 pays about $180 in egress. The same traffic on Neviri costs $144. Storage costs about the same either way. The difference shows up in transfer.
If your workload reads far more than it writes, and most public-facing apps do, egress is the line worth attacking first.
What to check before you switch
Object storage has three details that trip up a move. Sort them out before you migrate.
Path style versus virtual host. AWS defaults to bucket.s3.amazonaws.com. Neviri serves path style: s3.neviri.com/bucket/key. Most SDKs handle this with one config flag. Set addressing_style to path in boto3, or --s3-force-path-style in the CLI, and links resolve.
CORS on the bucket. If a browser reads your objects with fetch or an image tag from a different origin, the bucket needs a CORS rule. Copy the same origins you allow on S3.
Public read. A bucket is private until you say otherwise. If you serve public images, set the read policy on the new bucket to match. Test one file in an incognito window before you flip DNS.
A migration you can run this afternoon
rclone copies between any two S3-compatible stores and verifies checksums as it goes. Set up two remotes, one for AWS and one for Neviri, then sync:
rclone sync aws:my-bucket neviri:my-bucket --progress --checksumFor a first pass, run it while your app still points at S3. The copy only reads from S3, so your live app keeps serving. Copying that data out of AWS counts as egress, so budget for the transfer. When the copy finishes, point your app at the new endpoint, run the sync once more to catch anything written in between, and watch your logs. Roll back by changing the endpoint string if something looks wrong. You kept the source intact.
Large datasets take longer. Run the bulk copy over a weekend, do a final delta sync at cutover, and the only pause your readers see is the moment you switch endpoints.
Where this fits
Object storage suits files your app hands out but does not query: uploads, exports, static assets, database dumps, build artifacts. Anything you would have put in an S3 bucket has a home here, read by the same code.
Cheaper storage is a nice line item, but predictable egress is the one your finance team notices. Because the egress rate is lower and you know it up front, you can predict the bill even as traffic grows.
Point one bucket at Neviri this week. Copy a real workload, watch the transfer line for a billing cycle, and compare. Your code keeps speaking the same S3 API. The only thing that changes is what you pay to move the bytes out.