Search code examples
amazon-web-servicesamazon-rds

How to know RDS free storage


I've created a RDS postgres instance with size of 65GB initially. Is it possible to get free space available using any postgres query.

If not, how can I achieve the same?

Thank you in advance.


Solution

  • A couple ways to do it

    Using the AWS Console

    Go to the RDS console and select the region your database is in. Click on the Show Monitoring button and pick your database instance. There will be a graph (like below image) that shows Free Storage Space. It may be on the second or third page of graphs.

    This is documented over at AWS RDS documentation.

    Example AWS RDS console

    Using the API via AWS CLI

    Alternatively, you can use the AWS API to get the information from cloudwatch.

    I will show how to do this with the AWS CLI.

    This assumes you have set up the AWS CLI credentials. I export AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY in my environment variables, but there are multiple ways to configure the CLI (or SDKS).

    REGION="eu-west-1"
    START="$(date -u -d '5 minutes ago' '+%Y-%m-%dT%T')"
    END="$(date -u '+%Y-%m-%dT%T')"
    INSTANCE_NAME="tstirldbopgs001"
    
    AWS_DEFAULT_REGION="$REGION" aws cloudwatch get-metric-statistics \
      --namespace AWS/RDS --metric-name FreeStorageSpace \
      --start-time $START --end-time $END --period 300 \
      --statistics Average \
      --dimensions "Name=DBInstanceIdentifier, Value=${INSTANCE_NAME}"
    
    {
        "Label": "FreeStorageSpace",
        "Datapoints": [
            {
                "Timestamp": "2017-11-16T14:01:00Z",
                "Average": 95406264320.0,
                "Unit": "Bytes"
            }
        ]
    }
    

    Using the API via Java SDK

    Here's a rudimentary example of how to get the same data via the Java AWS SDK, using the Cloudwatch API.

    build.gradle contents

    apply plugin: 'java'
    apply plugin: 'application'
    
    sourceCompatibility = 1.8
    
    repositories {
        jcenter()
    }
    
    dependencies {
        compile 'com.amazonaws:aws-java-sdk-cloudwatch:1.11.232'
    }
    
    mainClassName = 'GetRDSInfo'
    

    Java class

    Again, I rely on the credential chain to get AWS API credentials (I set them in my environment). You can change the call to the builder to change this behavior (see Working with AWS Credentials documentation).

    import java.util.Calendar;
    import java.util.Date;
    
    import com.amazonaws.regions.Regions;
    import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
    import com.amazonaws.services.cloudwatch.AmazonCloudWatchClientBuilder;
    import com.amazonaws.services.cloudwatch.model.GetMetricStatisticsRequest;
    import com.amazonaws.services.cloudwatch.model.GetMetricStatisticsResult;
    import com.amazonaws.services.cloudwatch.model.StandardUnit;
    import com.amazonaws.services.cloudwatch.model.Dimension;
    import com.amazonaws.services.cloudwatch.model.Datapoint;
    
    public class GetRDSInfo {
        public static void main(String[] args) {
            final long GIGABYTE = 1024L * 1024L * 1024L;
    
            // calculate our endTime as now and startTime as 5 minutes ago.
            Calendar cal = Calendar.getInstance();
            Date endTime = cal.getTime();
            cal.add(Calendar.MINUTE, -5);
            Date startTime = cal.getTime();
    
            String dbIdentifier = "tstirldbopgs001";
            Regions region = Regions.EU_WEST_1;
    
            Dimension dim = new Dimension()
                .withName("DBInstanceIdentifier")
                .withValue(dbIdentifier);
    
            final AmazonCloudWatch cw = AmazonCloudWatchClientBuilder.standard()
                                            .withRegion(region)
                                            .build();
    
            GetMetricStatisticsRequest req = new GetMetricStatisticsRequest()
                .withNamespace("AWS/RDS")
                .withMetricName("FreeStorageSpace")
                .withStatistics("Average")
                .withStartTime(startTime)
                .withEndTime(endTime)
                .withDimensions(dim)
                .withPeriod(300);
    
            GetMetricStatisticsResult res = cw.getMetricStatistics(req);
    
            for (Datapoint dp : res.getDatapoints()) {
                // We requested only the average free space over the last 5 minutes
                // so we only have one datapoint
                double freespaceGigs = dp.getAverage() / GIGABYTE;
                System.out.println(String.format("Free Space: %.2f GB", freespaceGigs));
            }
        }
    }
    

    Example Java Code Execution

    > gradle run
    
    > Task :run
    Free Space: 88.85 GB
    
    
    BUILD SUCCESSFUL in 7s