Since I started my self-hosted homelab, I’ve been thinking of ways to back up all my data. The first thing I chose to back up automatically is this blog using a script I wrote. The script creates a weekly backup of the WordPress database and the media files into compressed archives and uploads them to AWS S3. At the time of this post, the backup files are approximately 1GB each, and S3 charges $0.02/GB, which is a good deal to me.
To keep S3 costs low, I set up the bucket to automatically delete backup files more than 90 days old using AWS S3’s Lifecycle Management Rules. This way, even if the size of my backup files increases, I won’t have multiple old backups wasting space and raising storage costs in S3. I’ll show you how I set this all up in this post.
Enable Lifecycle Management
In the AWS console, navigate to your S3 bucket and click on the Management Tab.

Under Lifecycle configuration, click “Create lifecycle rule” to create a new lifecycle rule. Lifecycle rules are actions you want AWS S3 to take on your files during their lifetime, such as moving them between storage classes or deleting them after a while.

Next, give the lifecycle rule a descriptive name, and specify whether you want the rule to apply to the entire bucket or specific objects. If you choose to apply the rule to all bucket objects, click the check box that is presented and move on to the Lifecycle rule actions.

Check the “Expire current versions of objects” box to make AWS delete or expire the files after some time. In versioned buckets, expiring an object adds a delete marker to the object, similar to a soft delete. In buckets without versioning enabled, expiring an object deletes it from the bucket. In my case, the bucket isn’t versioned, so this option is good for me. In the next section, set the days to wait before expiring objects. In the image below, I chose 90, this means that files older than 90 days will be automatically deleted.

Conclusion
Deleting old backups using lifecycle management in S3 is cost-effective and simple to set up. I’ll probably use some version of this approach for future backups. For example, I could use lifecycle rules to automatically transition older backups to cheaper storage classes before expiring them. How do you rotate backups? Let me know in the comments.