How to use DigitalOcean Spaces for server backups
DigitalOcean Spaces is S3-compatible object storage sold as a subscription: as of October 2026, $5.00 a month covers 250 GiB of storage and 1,024 GiB of outbound transfer across all your buckets. For backups, create a Standard Storage bucket with the CDN off, give the server a Limited access key for that one bucket, and upload to https://<region>.digitaloceanspaces.com with the AWS CLI or s3cmd. Spaces has no Object Lock, and a Droplet's backups in Spaces stay in the same DigitalOcean account as the Droplet.
Spaces needs a DigitalOcean account. If you don't have one yet, create it before the first step.
Create a DigitalOcean accountAffiliate link — we earn a commission if you sign up.
Create a bucket for backups
- In the control panel, click Spaces Object Storage in the left menu, then Create Bucket.
- Under Choose a datacenter region, pick the region. It becomes part of the bucket's endpoint and can't be changed later. As of October 2026, Standard Storage is offered in NYC3, AMS3, SFO2, SFO3, SGP1, LON1, FRA1, TOR1, BLR1, SYD1, ATL1, RIC1 and MKC1.
- Under Choose a Storage type, pick Standard Storage. Cold Storage is covered below. The type can't be changed after creation.
- Leave the Content Delivery Network (CDN) off. The CDN caches files on edge servers for fast public downloads, and nobody but you should download your backups.
- Name the bucket: 3 to 63 lowercase letters, numbers and dashes, starting with a letter or number, and unique among all DigitalOcean users. The name is part of the URL, so keep private details out of it.
- Select a project and click Create a Spaces Bucket.
A new bucket is private. File listing defaults to restricted, so only requests signed with an access key can list it, and files are readable only with credentials unless they are uploaded with a public ACL. Never add --acl-public (s3cmd) or --acl public-read (AWS CLI) to a backup upload.
Create a limited access key
- Click Spaces Object Storage, open the Access Keys tab and click Create Access Key.
- Under Select access scope, choose Limited access.
- Tick the backup bucket and set its Permissions to Read/Write/Delete.
- Name the key after the server, such as
web-01-backups, and click Create Access Key. - Copy the secret key now. DigitalOcean shows it only once.
Access keys can be created only in the control panel, not with the API or doctl. Know their rules:
- There is no write-only level. Uploading needs Read/Write/Delete, so a server that can upload backups can also delete them. Keep a copy elsewhere too.
- Name the bucket in every command. Listing all buckets needs a full access key, so
aws s3 lswith no bucket fails with a limited key. - Limited keys and bucket policies don't mix. A bucket with a
PutBucketPolicypolicy can't get a limited key, and the reverse. - Full and limited keys can't be converted into each other.
The endpoint
S3 tools talk to the regional endpoint, https://<region>.digitaloceanspaces.com, for example https://fra1.digitaloceanspaces.com. The bucket's page also shows an Origin endpoint, https://<bucket>.<region>.digitaloceanspaces.com, which is the bucket's own URL. Give tools the regional one; DigitalOcean's versioning guide warns that versioning requests sent to the origin endpoint fail.
When a tool asks for a region, DigitalOcean's SDK guide says to use us-east-1. The region is only used to validate the request; the endpoint decides the datacenter.
Upload with the AWS CLI
aws configure --profile spacesEnter the Spaces access key and secret key, us-east-1 as the region, and leave the output format blank.
aws s3 cp /var/backups/web-01-2026-10-03.tar.gz s3://web-01-backups/web-01/ --endpoint-url https://fra1.digitaloceanspaces.com --profile spacess3://web-01-backups/web-01/is the bucket and a key prefix. The trailing slash keeps the file's name.--endpoint-urlsends the request to Spaces in FRA1 instead of AWS.--profile spacesuses the keys you just saved.
To skip --endpoint-url, add endpoint_url = https://fra1.digitaloceanspaces.com under [profile spaces] in ~/.aws/config.
Upload with s3cmd
DigitalOcean documents s3cmd 2.0.0 or later. Write a separate config file for Spaces, and pass the bucket so the setup test checks that bucket instead of listing all of them, which a limited key can't do:
s3cmd --configure -c ~/.s3cfg-spaces s3://web-01-backups- Access Key and Secret Key: the Spaces key.
- Default Region: accept
US. Spaces takes the region from the endpoint. - S3 Endpoint:
fra1.digitaloceanspaces.com. - DNS-style bucket+hostname:port template:
%(bucket)s.fra1.digitaloceanspaces.com. - Encryption password: optional. It is only used by uploads with
-e, which encrypt the file with GPG first. - Use HTTPS protocol:
Yes. Spaces requires HTTPS.
s3cmd -c ~/.s3cfg-spaces put /var/backups/web-01-2026-10-03.tar.gz s3://web-01-backups/web-01/-c picks the Spaces config file, put uploads, and the trailing slash keeps the file's name.
Expire old backups with a lifecycle rule
Spaces supports lifecycle rules for time-based expiration and for removing incomplete multipart uploads. Tag-based rules aren't supported, and the control panel has no lifecycle setting. Changing lifecycle rules needs a full access key, so run this from a workstation, not the server:
{
"Rules": [
{
"ID": "expire-backups-after-30-days",
"Filter": { "Prefix": "web-01/" },
"Status": "Enabled",
"Expiration": { "Days": 30 },
"AbortIncompleteMultipartUpload": { "DaysAfterInitiation": 1 }
}
]
}aws s3api put-bucket-lifecycle-configuration --bucket web-01-backups --lifecycle-configuration file://lifecycle.json --endpoint-url https://fra1.digitaloceanspaces.com --profile spaces-adminFilterwithPrefixlimits the rule to keys underweb-01/.ExpirationwithDays: 30deletes each object 30 days after it was created.AbortIncompleteMultipartUploadclears parts left by a failed upload after a day. Spaces also removes incomplete multipart uploads older than 30 days on its own.
The same expiration with s3cmd, using a config file that holds a full access key:
s3cmd -c ~/.s3cfg-spaces-admin expire s3://web-01-backups --expiry-days=30 --expiry-prefix=web-01/Read the rule back with aws s3api get-bucket-lifecycle-configuration or s3cmd getlifecycle.
Leave versioning off on a bucket managed this way. With versioning on, a deleted object stays behind as a previous version that still uses storage, and DigitalOcean documents no lifecycle action for removing previous versions.
Cold Storage for long-term archives
Cold Storage is a cheaper bucket type for data you rarely read, and DigitalOcean suggests it for archived backups. As of October 2026:
- Storage is $0.007 per GiB per month. Retrieval is $0.01 per GiB, waived up to your average daily Cold Storage usage for the month.
- Each object has a 30-day minimum. Early deletes and overwrites are billed at the storage rate for the remaining days, after the first 250 GiB each month.
- Objects under 128 KiB are billed as 128 KiB.
- Cold Storage buckets are created only in the control panel, aren't offered in BLR1, and support no CDN or bucket policies.
It suits monthly archives kept for months. Nightly backups rotated within 30 days belong in Standard Storage.
What it costs
As of October 2026, DigitalOcean's pricing docs list, for Standard Storage:
- $5.00 a month for the subscription, for any number of buckets.
- 250 GiB of storage included across all buckets, then $0.02 per GiB per month.
- 1,024 GiB of outbound transfer included, shared by all buckets, then $0.01 per GiB.
- Inbound transfer is free, but uploads from a Droplet count against the Droplet's own outbound allowance.
- Transfer from Spaces to Droplets in the same region, such as FRA1 to FRA1, is free.
- Billing starts with the first bucket and ends when you destroy the last one, prorated hourly. The minimum billable object size is 4 KiB.
Example: 150 GiB of backups fits in the base $5. At 400 GiB you pay $5 plus 150 GiB × $0.02, so $8 a month.
Limits
- 100 buckets and 200 access keys per account by default.
- 800 operations per second per bucket. Some older buckets have lower limits.
- A single PUT can be up to 5 GB. Bigger files go up in multipart uploads, which the AWS CLI and s3cmd handle: up to 10,000 parts and 5 TB per object.
- A bucket can't move to another region or team; copy into a new bucket instead.
- No Object Lock. It isn't among the S3 features Spaces supports, so nothing in Spaces makes a backup immutable.
- Versioning and bucket policies are set through the S3 API only, and doctl can't create buckets.
A Spaces copy stays inside DigitalOcean
If your servers are Droplets, backups in Spaces cover the common failures: a destroyed Droplet, a broken upgrade, deleted files. A bucket in another region also covers trouble in one region.
They don't cover losing the account. The Droplet and the bucket share one login and one billing relationship. DigitalOcean's pricing page says it may remove access to Spaces for accounts with unresolved billing issues, and anyone who takes over the account can delete both.
Keep one more copy with a different provider, as the 3-2-1 backup rule describes. It works the other way too: Spaces is a sound off-site target for servers that run on another cloud.
Verify a backup
aws s3 ls s3://web-01-backups/web-01/ --recursive --human-readable --summarize --endpoint-url https://fra1.digitaloceanspaces.com --profile spaces--recursive lists every object under the prefix, --human-readable prints sizes in MiB and GiB, and --summarize adds the object count and total size. Then stream an archive back and hash it:
aws s3 cp s3://web-01-backups/web-01/web-01-2026-10-03.tar.gz - --endpoint-url https://fra1.digitaloceanspaces.com --profile spaces | sha256sumThe - destination writes the download to standard output. Compare the hash with sha256sum of the archive before upload. A match shows the file is intact; a restore shows it is complete, as in how to test a backup restore.
A key that can upload can usually delete too. For backups an attacker cannot remove, see protecting backups from ransomware; to keep what is stored readable only by you, encrypt it before upload.
Frequently asked questions
- How much does DigitalOcean Spaces cost?
- As of October 2026, $5.00 a month for Standard Storage, including 250 GiB of storage and 1,024 GiB of outbound transfer across all buckets. Extra storage is $0.02 per GiB per month and extra transfer $0.01 per GiB.
- Can I limit a Spaces access key to one bucket?
- Yes. Create a Limited access key and give it Read or Read/Write/Delete on specific buckets. Keys can be created only in the control panel.
- Does DigitalOcean Spaces support Object Lock?
- No. Object Lock isn't among the S3 features Spaces supports, and a key that can upload to a bucket can also delete from it.
- Does DigitalOcean back up Spaces buckets?
- No. Spaces has no built-in backups. Copy anything important to another bucket, another provider or a machine you control.
- What is the Spaces endpoint URL?
https://<region>.digitaloceanspaces.comfor the bucket's region, for examplehttps://nyc3.digitaloceanspaces.com. If a client asks for a region, useus-east-1.
How this was checked
Commands, limits and prices were checked against these official pages, on October 3, 2026:
- DigitalOcean Docs: How to Create a Spaces Bucket
- DigitalOcean Docs: How to Manage Access to Spaces (access keys)
- DigitalOcean Docs: Spaces Pricing
- DigitalOcean Docs: Spaces Limits
- DigitalOcean Docs: Spaces Availability
- DigitalOcean Docs: Spaces S3 Compatibility
- DigitalOcean Docs: Spaces API reference (supported operations, key permission levels)
- DigitalOcean Docs: How to Configure Lifecycle Rules
- DigitalOcean Docs: How to Configure Spaces Versioning
- DigitalOcean Docs: How to Set File Listing Permissions
- DigitalOcean Docs: How to Enable the Spaces CDN
- DigitalOcean Docs: Set Up s3cmd 2.x with Spaces
- DigitalOcean Docs: Examples of s3cmd 2.x usage with Spaces
- DigitalOcean Docs: Use Spaces with AWS S3 SDKs (endpoint and region)
- s3cmd usage reference (s3tools.org)
- AWS CLI reference: s3api put-bucket-lifecycle-configuration
- AWS CLI reference: s3 cp, s3 ls