

# Managing throughput capacity automatically with DynamoDB auto scaling
<a name="AutoScaling"></a>

Many database workloads are cyclical in nature, while others are difficult to predict in advance. For one example, consider a social networking app where most of the users are active during daytime hours. The database must be able to handle the daytime activity, but there's no need for the same levels of throughput at night. For another example, consider a new mobile gaming app that is experiencing unexpectedly rapid adoption. If the game becomes too popular it could exceed the available database resources, resulting in slow performance and unhappy customers. These kinds of workloads often require manual intervention to scale database resources up or down in response to varying usage levels.

Amazon DynamoDB auto scaling uses the AWS Application Auto Scaling service to dynamically adjust provisioned throughput capacity on your behalf, in response to actual traffic patterns. This enables a table or a global secondary index (GSI) to increase its provisioned read and write capacity to handle sudden increases in traffic, without throttling. When the workload decreases, Application Auto Scaling decreases the throughput so that you don't pay for unused provisioned capacity.

**Note**  
If you use the AWS Management Console to create a table or a global secondary index, DynamoDB auto scaling is enabled by default. You can modify your auto scaling settings at any time. For more information, see [Using the AWS Management Console with DynamoDB auto scaling](AutoScaling.Console.md).  
When you delete a table or global table replica then any associated scalable targets, scaling polices, or CloudWatch alarms are not automatically deleted with it.

With Application Auto Scaling, you create a *scaling policy* for a table or a global secondary index. The scaling policy specifies whether you want to scale read capacity or write capacity (or both), and the minimum and maximum provisioned capacity unit settings for the table or index.

The scaling policy also contains a *target utilization*—the percentage of consumed provisioned throughput at a point in time. Application Auto Scaling uses a *target tracking* algorithm to adjust the provisioned throughput of the table (or index) upward or downward in response to actual workloads, so that the actual capacity utilization remains at or near your target utilization.

DynamoDB outputs consumed provisioned throughput for one-minute periods. Auto scaling triggers when your consumed capacity breaches the configured target utilization for two consecutive minutes. CloudWatch alarms might have a short delay of up to a few minutes before triggering auto scaling. This delay ensures accurate CloudWatch metric evaluation. If the consumed throughput spikes are more than a minute apart, auto scaling might not trigger. Similarly, a scale down event can occur when 15 consecutive data points are lower than the target utilization. In either case, after auto scaling triggers, the [UpdateTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateTable.html) API is invoked. It then takes several minutes to update the provisioned capacity for the table or index. During this period, any requests that exceed the previous provisioned capacity of the tables are throttled.

**Important**  
You can't adjust the number of data points to breach to trigger the underlying alarm (though the current number could change in the future).

 You can set the auto scaling target utilization values between 20 and 90 percent for your read and write capacity. 

**Note**  
In addition to tables, DynamoDB auto scaling also supports global secondary indexes. Every global secondary index has its own provisioned throughput capacity, separate from that of its base table. When you create a scaling policy for a global secondary index, Application Auto Scaling adjusts the provisioned throughput settings for the index to ensure that its actual utilization stays at or near your desired utilization ratio.

## How DynamoDB auto scaling works
<a name="AutoScaling.HowItWorks"></a>

**Note**  
To get started quickly with DynamoDB auto scaling, see [Using the AWS Management Console with DynamoDB auto scaling](AutoScaling.Console.md).

The following diagram provides a high-level overview of how DynamoDB auto scaling manages throughput capacity for a table.

![\[DynamoDB auto scaling adjusts a table’s throughput capacity to meet demand.\]](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/images/auto-scaling.png)


The following steps summarize the auto scaling process as shown in the previous diagram:

1. You create an Application Auto Scaling policy for your DynamoDB table.

1. DynamoDB publishes consumed capacity metrics to Amazon CloudWatch. 

1. If the table's consumed capacity exceeds your target utilization (or falls below the target) for a specific length of time, Amazon CloudWatch triggers an alarm. You can view the alarm on the console and receive notifications using Amazon Simple Notification Service (Amazon SNS).

1. The CloudWatch alarm invokes Application Auto Scaling to evaluate your scaling policy.

1. Application Auto Scaling issues an `UpdateTable` request to adjust your table's provisioned throughput.

1. DynamoDB processes the `UpdateTable` request, dynamically increasing (or decreasing) the table's provisioned throughput capacity so that it approaches your target utilization.

To understand how DynamoDB auto scaling works, suppose that you have a table named `ProductCatalog`. The table is bulk-loaded with data infrequently, so it doesn't incur very much write activity. However, it does experience a high degree of read activity, which varies over time. By monitoring the Amazon CloudWatch metrics for `ProductCatalog`, you determine that the table requires 1,200 read capacity units (to avoid DynamoDB throttling read requests when activity is at its peak). You also determine that `ProductCatalog` requires 150 read capacity units at a minimum, when read traffic is at its lowest point. For more information about preventing throttling, see [Troubleshooting throttling in Amazon DynamoDB](TroubleshootingThrottling.md).

Within the range of 150 to 1,200 read capacity units, you decide that a target utilization of 70 percent would be appropriate for the `ProductCatalog` table. *Target utilization* is the ratio of consumed capacity units to provisioned capacity units, expressed as a percentage. Application Auto Scaling uses its target tracking algorithm to ensure that the provisioned read capacity of `ProductCatalog` is adjusted as required so that utilization remains at or near 70 percent.

**Note**  
DynamoDB auto scaling modifies provisioned throughput settings only when the actual workload stays elevated or depressed for a sustained period of several minutes. The Application Auto Scaling target tracking algorithm seeks to keep the target utilization at or near your chosen value over the long term.  
Sudden, short-duration spikes of activity are accommodated by the table's built-in burst capacity. For more information, see [Burst capacity](burst-adaptive-capacity.md#burst-capacity).

To enable DynamoDB auto scaling for the `ProductCatalog` table, you create a scaling policy. This policy specifies the following:
+ The table or global secondary index that you want to manage
+ Which capacity type to manage (read capacity or write capacity)
+ The upper and lower boundaries for the provisioned throughput settings
+ Your target utilization

When you create a scaling policy, Application Auto Scaling creates a pair of Amazon CloudWatch alarms on your behalf. Each pair represents the upper and lower boundaries for your provisioned throughput settings. These CloudWatch alarms are triggered when the table's actual utilization deviates from your target utilization for a sustained period of time.

When one of the CloudWatch alarms is triggered, Amazon SNS sends you a notification (if you have enabled it). The CloudWatch alarm then invokes Application Auto Scaling, which in turn notifies DynamoDB to adjust the `ProductCatalog` table's provisioned capacity upward or downward as appropriate.

During a scaling event, AWS Config is charged per configuration item recorded. When a scaling event occurs, four CloudWatch alarms are created for each read and write auto-scaling event: ProvisionedCapacity alarms: ProvisionedCapacityLow, ProvisionedCapacityHigh and ConsumedCapacity alarms: AlarmHigh, AlarmLow. This results in a total of eight alarms. Therefore, AWS Config records eight configuration items for every scaling event.

**Note**  
You can also schedule your DynamoDB scaling so it happens at certain times. Learn the basic steps [here](https://docs.aws.amazon.com/autoscaling/application/userguide/get-started-exercise.html).

## Usage notes
<a name="AutoScaling.UsageNotes"></a>

Before you begin using DynamoDB auto scaling, you should be aware of the following:
+ DynamoDB auto scaling can increase read capacity or write capacity as often as necessary, in accordance with your auto scaling policy. All DynamoDB quotas remain in effect, as described in [Quotas in Amazon DynamoDB](ServiceQuotas.md).
+ DynamoDB auto scaling doesn't prevent you from manually modifying provisioned throughput settings. These manual adjustments don't affect any existing CloudWatch alarms that are related to DynamoDB auto scaling.
+ If you enable DynamoDB auto scaling for a table that has one or more global secondary indexes, we highly recommend that you also apply auto scaling uniformly to those indexes. This will help ensure better performance for table writes and reads, and help avoid throttling. You can enable auto scaling by selecting **Apply same settings to global secondary indexes** in the AWS Management Console. For more information, see [Enabling DynamoDB auto scaling on existing tables](AutoScaling.Console.md#AutoScaling.Console.ExistingTable).
+ When you delete a table or global table replica, any associated scalable targets, scaling polices or CloudWatch alarms are not automatically deleted with it.
+ When creating a GSI for an existing table, auto scaling is not enabled for the GSI. You will have to manually manage the capacity while the GSI is being built. Once the backfill on the GSI completes and it reaches active status, auto scaling will operate as normal.

# Using the AWS Management Console with DynamoDB auto scaling
<a name="AutoScaling.Console"></a>

When you use the AWS Management Console to create a new table, Amazon DynamoDB auto scaling is enabled for that table by default. You can also use the console to enable auto scaling for existing tables, modify auto scaling settings, or disable auto scaling.

**Note**  
 For more advanced features like setting scale-in and scale-out cooldown times, use the AWS Command Line Interface (AWS CLI) to manage DynamoDB auto scaling. For more information, see [Using the AWS CLI to manage DynamoDB auto scaling](AutoScaling.CLI.md).

**Topics**
+ [

## Before you begin: Granting user permissions for DynamoDB auto scaling
](#AutoScaling.Permissions)
+ [

## Creating a new table with auto scaling enabled
](#AutoScaling.Console.NewTable)
+ [

## Enabling DynamoDB auto scaling on existing tables
](#AutoScaling.Console.ExistingTable)
+ [

## Viewing auto scaling activities on the console
](#AutoScaling.Console.ViewingActivities)
+ [

## Modifying or disabling DynamoDB auto scaling settings
](#AutoScaling.Console.Modifying)

## Before you begin: Granting user permissions for DynamoDB auto scaling
<a name="AutoScaling.Permissions"></a>

In AWS Identity and Access Management (IAM), the AWS managed policy `DynamoDBFullAccess` provides the required permissions for using the DynamoDB console. However, for DynamoDB auto scaling, users require additional permissions. 

**Important**  
 To delete an auto scaling-enabled table, `application-autoscaling:*` permissions are required. The AWS managed policy `DynamoDBFullAccess` includes such permissions.

To set up a user for DynamoDB console access and DynamoDB auto scaling, create a role and add the **AmazonDynamoDBFullAccess** policy to that role. Then assign the role to a user.

## Creating a new table with auto scaling enabled
<a name="AutoScaling.Console.NewTable"></a>

**Note**  
DynamoDB auto scaling requires the presence of a service-linked role (`AWSServiceRoleForApplicationAutoScaling_DynamoDBTable`) that performs auto scaling actions on your behalf. This role is created automatically for you. For more information, see [Service-linked roles for Application Auto Scaling](https://docs.aws.amazon.com/autoscaling/application/userguide/application-auto-scaling-service-linked-roles.html) in the*Application Auto Scaling User Guide*.

**To create a new table with auto scaling enabled**

1. Open the DynamoDB console at [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/).

1. Choose **Create table**.

1. On the **Create table** page, enter the **Table name** and primary key details.

1. If you choose **Default settings**, auto scaling is enabled in the new table.

   Otherwise, choose **Customize settings** and do the following to specify custom settings for the table: 

   1. For **Table class**, keep the default selection of **DynamoDB Standard**.

   1. For **Read/write capacity settings**, keep the default selection of **Provisioned**, then do the following:

      1. For **Read capacity**, make sure **Auto scaling** is set to **On**.

      1. For **Write capacity**, make sure **Auto scaling** is set to **On**.

      1. For **Read capacity** and **Write capacity**, set your desired scaling policy for the table and, optionally, all global secondary indexes of the table.
         + **Minimum capacity units** – Enter your lower boundary for the auto scaling range.
         + **Maximum capacity units** – Enter your upper boundary for the auto scaling range.
         + **Target utilization** – Enter your target utilization percentage for the table.
**Note**  
If you create a global secondary index for the new table, the index's capacity at time of creation will be the same as your base table's capacity. You can change the index's capacity in the table's settings after you create the table.

1. Choose **Create table**. This creates your table with the auto scaling parameters you specified.

## Enabling DynamoDB auto scaling on existing tables
<a name="AutoScaling.Console.ExistingTable"></a>

**Note**  
DynamoDB auto scaling requires the presence of a service-linked role (`AWSServiceRoleForApplicationAutoScaling_DynamoDBTable`) that performs auto scaling actions on your behalf. This role is created automatically for you. For more information, see [Service-linked roles for Application Auto Scaling](https://docs.aws.amazon.com/autoscaling/application/userguide/application-auto-scaling-service-linked-roles.html).

**To enable DynamoDB auto scaling for an existing table**

1. Open the DynamoDB console at [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/).

1. In the navigation pane on the left side of the console, choose **Tables**.

1. Choose the table on which you want to enable auto scaling, and then do the following:

   1. Choose the **Additional settings** tab.

   1. In the **Read/write capacity** section, choose **Edit**.

   1. In the **Capacity mode** section, choose **Provisioned**.

   1. In the **Table capacity** section, set **Auto scaling** to **On** for **Read capacity**, **Write capacity**, or both. For each of these, set your desired scaling policy for the table and, optionally, all global secondary indexes of the table.
      + **Minimum capacity units** – Enter your lower boundary for the auto scaling range.
      + **Maximum capacity units** – Enter your upper boundary for the auto scaling range.
      + **Target utilization** – Enter your target utilization percentage for the table.
      + **Use the same capacity read/write capacity settings for all global secondary indexes** – Choose whether global secondary indexes should use the same auto scaling policy as the base table.
**Note**  
For best performance, we recommend that you enable **Use the same read/write capacity settings for all global secondary indexes**. This option allows DynamoDB auto scaling to uniformly scale all the global secondary indexes on the base table. This includes existing global secondary indexes, and any others that you create for this table in the future.  
With this option enabled, you can't set a scaling policy on an individual global secondary index.

1. When the settings are as you want them, choose **Save**.

## Viewing auto scaling activities on the console
<a name="AutoScaling.Console.ViewingActivities"></a>

As your application drives read and write traffic to your table, DynamoDB auto scaling dynamically modifies the table's throughput settings. Amazon CloudWatch keeps track of provisioned and consumed capacity, throttled events, latency, and other metrics for all of your DynamoDB tables and secondary indexes.

To view these metrics in the DynamoDB console, choose the table that you want to work with and choose the **Monitor** tab. To create a customizable view of table metrics, select **View all in CloudWatch**.

## Modifying or disabling DynamoDB auto scaling settings
<a name="AutoScaling.Console.Modifying"></a>

You can use the AWS Management Console to modify your DynamoDB auto scaling settings. To do this, go to the **Additional settings** tab for your table, and choose **Edit** in the **Read/write capacity** section. For more information about these settings, see [Enabling DynamoDB auto scaling on existing tables](#AutoScaling.Console.ExistingTable).

# Using the AWS CLI to manage DynamoDB auto scaling
<a name="AutoScaling.CLI"></a>

Instead of using the AWS Management Console, you can use the AWS Command Line Interface (AWS CLI) to manage Amazon DynamoDB auto scaling. The tutorial in this section demonstrates how to install and configure the AWS CLI for managing DynamoDB auto scaling. In this tutorial, you do the following:
+ Create a DynamoDB table named `TestTable`. The initial throughput settings are 5 read capacity units and 5 write capacity units.
+ Create an Application Auto Scaling policy for `TestTable`. The policy seeks to maintain a 50 percent target ratio between consumed write capacity and provisioned write capacity. The range for this metric is between 5 and 10 write capacity units. (Application Auto Scaling is not allowed to adjust the throughput beyond this range.)
+ Run a Python program to drive write traffic to `TestTable`. When the target ratio exceeds 50 percent for a sustained period of time, Application Auto Scaling notifies DynamoDB to adjust the throughput of `TestTable` upward to maintain the 50 percent target utilization.
+ Verify that DynamoDB has successfully adjusted the provisioned write capacity for `TestTable`.

**Note**  
You can also schedule your DynamoDB scaling so it happens at certain times. Learn the basic steps [here](https://docs.aws.amazon.com/autoscaling/application/userguide/get-started-exercise.html).

**Topics**
+ [

## Before you begin
](#AutoScaling.CLI.BeforeYouBegin)
+ [

## Step 1: Create a DynamoDB table
](#AutoScaling.CLI.CreateTable)
+ [

## Step 2: Register a scalable target
](#AutoScaling.CLI.RegisterScalableTarget)
+ [

## Step 3: Create a scaling policy
](#AutoScaling.CLI.CreateScalingPolicy)
+ [

## Step 4: Drive write traffic to TestTable
](#AutoScaling.CLI.DriveTraffic)
+ [

## Step 5: View Application Auto Scaling actions
](#AutoScaling.CLI.ViewCWAlarms)
+ [

## (Optional) Step 6: Clean up
](#AutoScaling.CLI.CleanUp)

## Before you begin
<a name="AutoScaling.CLI.BeforeYouBegin"></a>

Complete the following tasks before starting the tutorial.

### Install the AWS CLI
<a name="AutoScaling.CLI.BeforeYouBegin.InstallCLI"></a>

If you haven't already done so, you must install and configure the AWS CLI. To do this, follow these instructions in the *AWS Command Line Interface User Guide*:
+ [Installing the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/installing.html)
+ [Configuring the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html)

### Install Python
<a name="AutoScaling.CLI.BeforeYouBegin.InstallPython"></a>

Part of this tutorial requires you to run a Python program (see [Step 4: Drive write traffic to TestTable](#AutoScaling.CLI.DriveTraffic)). If you don't already have it installed, you can [download Python](https://www.python.org/downloads). 

## Step 1: Create a DynamoDB table
<a name="AutoScaling.CLI.CreateTable"></a>

In this step, you use the AWS CLI to create `TestTable`. The primary key consists of `pk` (partition key) and `sk` (sort key). Both of these attributes are of type `Number`. The initial throughput settings are 5 read capacity units and 5 write capacity units.

1. Use the following AWS CLI command to create the table.

   ```
   aws dynamodb create-table \
       --table-name TestTable \
       --attribute-definitions \
           AttributeName=pk,AttributeType=N \
           AttributeName=sk,AttributeType=N \
       --key-schema \
           AttributeName=pk,KeyType=HASH \
           AttributeName=sk,KeyType=RANGE \
       --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5
   ```

1. To check the status of the table, use the following command.

   ```
   aws dynamodb describe-table \
       --table-name TestTable \
       --query "Table.[TableName,TableStatus,ProvisionedThroughput]"
   ```

   The table is ready for use when its status is `ACTIVE`.

## Step 2: Register a scalable target
<a name="AutoScaling.CLI.RegisterScalableTarget"></a>

Next you register the table's write capacity as a scalable target with Application Auto Scaling. This allows Application Auto Scaling to adjust the provisioned write capacity for *TestTable*, but only within the range of 5–10 capacity units.

**Note**  
DynamoDB auto scaling requires the presence of a service linked role (`AWSServiceRoleForApplicationAutoScaling_DynamoDBTable`) that performs auto scaling actions on your behalf. This role is created automatically for you. For more information, see [Service-linked roles for Application Auto Scaling](https://docs.aws.amazon.com/autoscaling/application/userguide/application-auto-scaling-service-linked-roles.html) in the *Application Auto Scaling User Guide*. 

1. Enter the following command to register the scalable target. 

   ```
   aws application-autoscaling register-scalable-target \
       --service-namespace dynamodb \
       --resource-id "table/TestTable" \
       --scalable-dimension "dynamodb:table:WriteCapacityUnits" \
       --min-capacity 5 \
       --max-capacity 10
   ```

1. To verify the registration, use the following command.

   ```
   aws application-autoscaling describe-scalable-targets \
       --service-namespace dynamodb \
       --resource-id "table/TestTable"
   ```
**Note**  
 You can also register a scalable target against a global secondary index. For example, for a global secondary index ("test-index"), the resource ID and scalable dimension arguments are updated appropriately.   

   ```
   aws application-autoscaling register-scalable-target \
       --service-namespace dynamodb \
       --resource-id "table/TestTable/index/test-index" \
       --scalable-dimension "dynamodb:index:WriteCapacityUnits" \
       --min-capacity 5 \
       --max-capacity 10
   ```

## Step 3: Create a scaling policy
<a name="AutoScaling.CLI.CreateScalingPolicy"></a>

In this step, you create a scaling policy for `TestTable`. The policy defines the details under which Application Auto Scaling can adjust your table's provisioned throughput, and what actions to take when it does so. You associate this policy with the scalable target that you defined in the previous step (write capacity units for the `TestTable` table).

The policy contains the following elements:
+ `PredefinedMetricSpecification`—The metric that Application Auto Scaling is allowed to adjust. For DynamoDB, the following values are valid values for `PredefinedMetricType`:
  + `DynamoDBReadCapacityUtilization`
  + `DynamoDBWriteCapacityUtilization`
+ `ScaleOutCooldown`—The minimum amount of time (in seconds) between each Application Auto Scaling event that increases provisioned throughput. This parameter allows Application Auto Scaling to continuously, but not aggressively, increase the throughput in response to real-world workloads. The default setting for `ScaleOutCooldown` is 0.
+ `ScaleInCooldown`—The minimum amount of time (in seconds) between each Application Auto Scaling event that decreases provisioned throughput. This parameter allows Application Auto Scaling to decrease the throughput gradually and predictably. The default setting for `ScaleInCooldown` is 0.
+ `TargetValue`—Application Auto Scaling ensures that the ratio of consumed capacity to provisioned capacity stays at or near this value. You define `TargetValue` as a percentage.

**Note**  
To further understand how `TargetValue` works, suppose that you have a table with a provisioned throughput setting of 200 write capacity units. You decide to create a scaling policy for this table, with a `TargetValue` of 70 percent.  
Now suppose that you begin driving write traffic to the table so that the actual write throughput is 150 capacity units. The consumed-to-provisioned ratio is now (150 / 200), or 75 percent. This ratio exceeds your target, so Application Auto Scaling increases the provisioned write capacity to 215 so that the ratio is (150 / 215), or 69.77 percent—as close to your `TargetValue` as possible, but not exceeding it.

For `TestTable`, you set `TargetValue` to 50 percent. Application Auto Scaling adjusts the table's provisioned throughput within the range of 5–10 capacity units (see [Step 2: Register a scalable target](#AutoScaling.CLI.RegisterScalableTarget)) so that the consumed-to-provisioned ratio remains at or near 50 percent. You set the values for `ScaleOutCooldown` and `ScaleInCooldown` to 60 seconds.

1. Create a file named `scaling-policy.json` with the following contents.

   ```
   {
       "PredefinedMetricSpecification": {
           "PredefinedMetricType": "DynamoDBWriteCapacityUtilization"
       },
       "ScaleOutCooldown": 60,
       "ScaleInCooldown": 60,
       "TargetValue": 50.0
   }
   ```

1. Use the following AWS CLI command to create the policy.

   ```
   aws application-autoscaling put-scaling-policy \
       --service-namespace dynamodb \
       --resource-id "table/TestTable" \
       --scalable-dimension "dynamodb:table:WriteCapacityUnits" \
       --policy-name "MyScalingPolicy" \
       --policy-type "TargetTrackingScaling" \
       --target-tracking-scaling-policy-configuration file://scaling-policy.json
   ```

1. In the output, note that Application Auto Scaling has created two Amazon CloudWatch alarms—one each for the upper and lower boundary of the scaling target range.

1. Use the following AWS CLI command to view more details about the scaling policy.

   ```
   aws application-autoscaling describe-scaling-policies \
       --service-namespace dynamodb \
       --resource-id "table/TestTable" \
       --policy-name "MyScalingPolicy"
   ```

1. In the output, verify that the policy settings match your specifications from [Step 2: Register a scalable target](#AutoScaling.CLI.RegisterScalableTarget) and [Step 3: Create a scaling policy](#AutoScaling.CLI.CreateScalingPolicy).

## Step 4: Drive write traffic to TestTable
<a name="AutoScaling.CLI.DriveTraffic"></a>

Now you can test your scaling policy by writing data to `TestTable`. To do this, you run a Python program.

1. Create a file named `bulk-load-test-table.py` with the following contents.

   ```
   import boto3
   dynamodb = boto3.resource('dynamodb')
   
   table = dynamodb.Table("TestTable")
   
   filler = "x" * 100000
   
   i = 0
   while (i < 10):
       j = 0
       while (j < 10):
           print (i, j)
           
           table.put_item(
               Item={
                   'pk':i,
                   'sk':j,
                   'filler':{"S":filler}
               }
           )
           j += 1
       i += 1
   ```

1. Enter the following command to run the program.

   `python bulk-load-test-table.py`

   The provisioned write capacity for `TestTable` is very low (5 write capacity units), so the program stalls occasionally due to write throttling. This is expected behavior.

   Let the program continue running while you move on to the next step.

## Step 5: View Application Auto Scaling actions
<a name="AutoScaling.CLI.ViewCWAlarms"></a>

 In this step, you view the Application Auto Scaling actions that are initiated on your behalf. You also verify that Application Auto Scaling has updated the provisioned write capacity for `TestTable`.

1. Enter the following command to view the Application Auto Scaling actions.

   ```
   aws application-autoscaling describe-scaling-activities \
       --service-namespace dynamodb
   ```

   Rerun this command occasionally, while the Python program is running. (It takes several minutes before your scaling policy is invoked.) You should eventually see the following output.

   ```
   ...
   {
       "ScalableDimension": "dynamodb:table:WriteCapacityUnits", 
       "Description": "Setting write capacity units to 10.", 
       "ResourceId": "table/TestTable", 
       "ActivityId": "0cc6fb03-2a7c-4b51-b67f-217224c6b656", 
       "StartTime": 1489088210.175, 
       "ServiceNamespace": "dynamodb", 
       "EndTime": 1489088246.85, 
       "Cause": "monitor alarm AutoScaling-table/TestTable-AlarmHigh-1bb3c8db-1b97-4353-baf1-4def76f4e1b9 in state ALARM triggered policy MyScalingPolicy", 
       "StatusMessage": "Successfully set write capacity units to 10. Change successfully fulfilled by dynamodb.", 
       "StatusCode": "Successful"
   }, 
   ...
   ```

   This indicates that Application Auto Scaling has issued an `UpdateTable` request to DynamoDB.

1. Enter the following command to verify that DynamoDB increased the table's write capacity.

   ```
   aws dynamodb describe-table \
       --table-name TestTable \
       --query "Table.[TableName,TableStatus,ProvisionedThroughput]"
   ```

   The `WriteCapacityUnits` should have been scaled from `5` to `10`.

## (Optional) Step 6: Clean up
<a name="AutoScaling.CLI.CleanUp"></a>

In this tutorial, you created several resources. You can delete these resources if you no longer need them.

1. Delete the scaling policy for `TestTable`.

   ```
   aws application-autoscaling delete-scaling-policy \
       --service-namespace dynamodb \
       --resource-id "table/TestTable" \
       --scalable-dimension "dynamodb:table:WriteCapacityUnits" \
       --policy-name "MyScalingPolicy"
   ```

1. Deregister the scalable target.

   ```
   aws application-autoscaling deregister-scalable-target \
       --service-namespace dynamodb \
       --resource-id "table/TestTable" \
       --scalable-dimension "dynamodb:table:WriteCapacityUnits"
   ```

1. Delete the `TestTable` table.

   ```
   aws dynamodb delete-table --table-name TestTable
   ```

# Using the AWS SDK to configure auto scaling on Amazon DynamoDB tables
<a name="AutoScaling.HowTo.SDK"></a>

In addition to using the AWS Management Console and the AWS Command Line Interface (AWS CLI), you can write applications that interact with Amazon DynamoDB auto scaling. This section contains two Java programs that you can use to test this functionality:
+ `EnableDynamoDBAutoscaling.java`
+ `DisableDynamoDBAutoscaling.java`

## Enabling Application Auto Scaling for a table
<a name="AutoScaling.HowTo.SDK-enable"></a>

The following program shows an example of setting up an auto scaling policy for a DynamoDB table (`TestTable`). It proceeds as follows:
+ The program registers write capacity units as a scalable target for `TestTable`. The range for this metric is between 5 and 10 write capacity units.
+ After the scalable target is created, the program builds a target tracking configuration. The policy seeks to maintain a 50 percent target ratio between consumed write capacity and provisioned write capacity.
+ The program then creates the scaling policy, based on the target tracking configuration.

**Note**  
When you manually remove a table or global table replica, you do not automatically remove any associated scalable targets, scaling policies, or CloudWatch alarms.

------
#### [ Java v2 ]

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.applicationautoscaling.ApplicationAutoScalingClient;
import software.amazon.awssdk.services.applicationautoscaling.model.ApplicationAutoScalingException;
import software.amazon.awssdk.services.applicationautoscaling.model.DescribeScalableTargetsRequest;
import software.amazon.awssdk.services.applicationautoscaling.model.DescribeScalableTargetsResponse;
import software.amazon.awssdk.services.applicationautoscaling.model.DescribeScalingPoliciesRequest;
import software.amazon.awssdk.services.applicationautoscaling.model.DescribeScalingPoliciesResponse;
import software.amazon.awssdk.services.applicationautoscaling.model.PolicyType;
import software.amazon.awssdk.services.applicationautoscaling.model.PredefinedMetricSpecification;
import software.amazon.awssdk.services.applicationautoscaling.model.PutScalingPolicyRequest;
import software.amazon.awssdk.services.applicationautoscaling.model.RegisterScalableTargetRequest;
import software.amazon.awssdk.services.applicationautoscaling.model.ScalingPolicy;
import software.amazon.awssdk.services.applicationautoscaling.model.ServiceNamespace;
import software.amazon.awssdk.services.applicationautoscaling.model.ScalableDimension;
import software.amazon.awssdk.services.applicationautoscaling.model.MetricType;
import software.amazon.awssdk.services.applicationautoscaling.model.TargetTrackingScalingPolicyConfiguration;
import java.util.List;

/**
 * Before running this Java V2 code example, set up your development environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class EnableDynamoDBAutoscaling {
    public static void main(String[] args) {
        final String usage = """

            Usage:
               <tableId> <roleARN> <policyName>\s

            Where:
               tableId - The table Id value (for example, table/Music).
               roleARN - The ARN of the role that has ApplicationAutoScaling permissions.
               policyName - The name of the policy to create.
               
            """;

        if (args.length != 3) {
            System.out.println(usage);
            System.exit(1);
        }

        System.out.println("This example registers an Amazon DynamoDB table, which is the resource to scale.");
        String tableId = args[0];
        String roleARN = args[1];
        String policyName = args[2];
        ServiceNamespace ns = ServiceNamespace.DYNAMODB;
        ScalableDimension tableWCUs = ScalableDimension.DYNAMODB_TABLE_WRITE_CAPACITY_UNITS;
        ApplicationAutoScalingClient appAutoScalingClient = ApplicationAutoScalingClient.builder()
            .region(Region.US_EAST_1)
            .build();

        registerScalableTarget(appAutoScalingClient, tableId, roleARN, ns, tableWCUs);
        verifyTarget(appAutoScalingClient, tableId, ns, tableWCUs);
        configureScalingPolicy(appAutoScalingClient, tableId, ns, tableWCUs, policyName);
    }

    public static void registerScalableTarget(ApplicationAutoScalingClient appAutoScalingClient, String tableId, String roleARN, ServiceNamespace ns, ScalableDimension tableWCUs) {
        try {
            RegisterScalableTargetRequest targetRequest = RegisterScalableTargetRequest.builder()
                .serviceNamespace(ns)
                .scalableDimension(tableWCUs)
                .resourceId(tableId)
                .roleARN(roleARN)
                .minCapacity(5)
                .maxCapacity(10)
                .build();

            appAutoScalingClient.registerScalableTarget(targetRequest);
            System.out.println("You have registered " + tableId);

        } catch (ApplicationAutoScalingException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
        }
    }

    // Verify that the target was created.
    public static void verifyTarget(ApplicationAutoScalingClient appAutoScalingClient, String tableId, ServiceNamespace ns, ScalableDimension tableWCUs) {
        DescribeScalableTargetsRequest dscRequest = DescribeScalableTargetsRequest.builder()
            .scalableDimension(tableWCUs)
            .serviceNamespace(ns)
            .resourceIds(tableId)
            .build();

        DescribeScalableTargetsResponse response = appAutoScalingClient.describeScalableTargets(dscRequest);
        System.out.println("DescribeScalableTargets result: ");
        System.out.println(response);
    }

    // Configure a scaling policy.
    public static void configureScalingPolicy(ApplicationAutoScalingClient appAutoScalingClient, String tableId, ServiceNamespace ns, ScalableDimension tableWCUs, String policyName) {
        // Check if the policy exists before creating a new one.
        DescribeScalingPoliciesResponse describeScalingPoliciesResponse = appAutoScalingClient.describeScalingPolicies(DescribeScalingPoliciesRequest.builder()
            .serviceNamespace(ns)
            .resourceId(tableId)
            .scalableDimension(tableWCUs)
            .build());

        if (!describeScalingPoliciesResponse.scalingPolicies().isEmpty()) {
            // If policies exist, consider updating an existing policy instead of creating a new one.
            System.out.println("Policy already exists. Consider updating it instead.");
            List<ScalingPolicy> polList = describeScalingPoliciesResponse.scalingPolicies();
            for (ScalingPolicy pol : polList) {
                System.out.println("Policy name:" +pol.policyName());
            }
        } else {
            // If no policies exist, proceed with creating a new policy.
            PredefinedMetricSpecification specification = PredefinedMetricSpecification.builder()
                .predefinedMetricType(MetricType.DYNAMO_DB_WRITE_CAPACITY_UTILIZATION)
                .build();

            TargetTrackingScalingPolicyConfiguration policyConfiguration = TargetTrackingScalingPolicyConfiguration.builder()
                .predefinedMetricSpecification(specification)
                .targetValue(50.0)
                .scaleInCooldown(60)
                .scaleOutCooldown(60)
                .build();

            PutScalingPolicyRequest putScalingPolicyRequest = PutScalingPolicyRequest.builder()
                .targetTrackingScalingPolicyConfiguration(policyConfiguration)
                .serviceNamespace(ns)
                .scalableDimension(tableWCUs)
                .resourceId(tableId)
                .policyName(policyName)
                .policyType(PolicyType.TARGET_TRACKING_SCALING)
                .build();

            try {
                appAutoScalingClient.putScalingPolicy(putScalingPolicyRequest);
                System.out.println("You have successfully created a scaling policy for an Application Auto Scaling scalable target");
            } catch (ApplicationAutoScalingException e) {
                System.err.println("Error: " + e.awsErrorDetails().errorMessage());
            }
        }
    }
}
```

------
#### [ Java v1 ]

The program requires that you provide an Amazon Resource Name (ARN) for a valid Application Auto Scaling service linked role. (For example: `arn:aws:iam::122517410325:role/AWSServiceRoleForApplicationAutoScaling_DynamoDBTable`.) In the following program, replace `SERVICE_ROLE_ARN_GOES_HERE` with the actual ARN. 

```
package com.amazonaws.codesamples.autoscaling;

import com.amazonaws.services.applicationautoscaling.AWSApplicationAutoScalingClient;
import com.amazonaws.services.applicationautoscaling.AWSApplicationAutoScalingClientBuilder;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalableTargetsRequest;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalableTargetsResult;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalingPoliciesRequest;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalingPoliciesResult;
import com.amazonaws.services.applicationautoscaling.model.MetricType;
import com.amazonaws.services.applicationautoscaling.model.PolicyType;
import com.amazonaws.services.applicationautoscaling.model.PredefinedMetricSpecification;
import com.amazonaws.services.applicationautoscaling.model.PutScalingPolicyRequest;
import com.amazonaws.services.applicationautoscaling.model.RegisterScalableTargetRequest;
import com.amazonaws.services.applicationautoscaling.model.ScalableDimension;
import com.amazonaws.services.applicationautoscaling.model.ServiceNamespace;
import com.amazonaws.services.applicationautoscaling.model.TargetTrackingScalingPolicyConfiguration;

public class EnableDynamoDBAutoscaling {

	static AWSApplicationAutoScalingClient aaClient = (AWSApplicationAutoScalingClient) AWSApplicationAutoScalingClientBuilder
			.standard().build();

	public static void main(String args[]) {

		ServiceNamespace ns = ServiceNamespace.Dynamodb;
		ScalableDimension tableWCUs = ScalableDimension.DynamodbTableWriteCapacityUnits;
		String resourceID = "table/TestTable";

		// Define the scalable target
		RegisterScalableTargetRequest rstRequest = new RegisterScalableTargetRequest()
				.withServiceNamespace(ns)
				.withResourceId(resourceID)
				.withScalableDimension(tableWCUs)
				.withMinCapacity(5)
				.withMaxCapacity(10)
				.withRoleARN("SERVICE_ROLE_ARN_GOES_HERE");

		try {
			aaClient.registerScalableTarget(rstRequest);
		} catch (Exception e) {
			System.err.println("Unable to register scalable target: ");
			System.err.println(e.getMessage());
		}

		// Verify that the target was created
		DescribeScalableTargetsRequest dscRequest = new DescribeScalableTargetsRequest()
				.withServiceNamespace(ns)
				.withScalableDimension(tableWCUs)
				.withResourceIds(resourceID);
		try {
			DescribeScalableTargetsResult dsaResult = aaClient.describeScalableTargets(dscRequest);
			System.out.println("DescribeScalableTargets result: ");
			System.out.println(dsaResult);
			System.out.println();
		} catch (Exception e) {
			System.err.println("Unable to describe scalable target: ");
			System.err.println(e.getMessage());
		}

		System.out.println();

		// Configure a scaling policy
		TargetTrackingScalingPolicyConfiguration targetTrackingScalingPolicyConfiguration = new TargetTrackingScalingPolicyConfiguration()
				.withPredefinedMetricSpecification(
						new PredefinedMetricSpecification()
								.withPredefinedMetricType(MetricType.DynamoDBWriteCapacityUtilization))
				.withTargetValue(50.0)
				.withScaleInCooldown(60)
				.withScaleOutCooldown(60);

		// Create the scaling policy, based on your configuration
		PutScalingPolicyRequest pspRequest = new PutScalingPolicyRequest()
				.withServiceNamespace(ns)
				.withScalableDimension(tableWCUs)
				.withResourceId(resourceID)
				.withPolicyName("MyScalingPolicy")
				.withPolicyType(PolicyType.TargetTrackingScaling)
				.withTargetTrackingScalingPolicyConfiguration(targetTrackingScalingPolicyConfiguration);

		try {
			aaClient.putScalingPolicy(pspRequest);
		} catch (Exception e) {
			System.err.println("Unable to put scaling policy: ");
			System.err.println(e.getMessage());
		}

		// Verify that the scaling policy was created
		DescribeScalingPoliciesRequest dspRequest = new DescribeScalingPoliciesRequest()
				.withServiceNamespace(ns)
				.withScalableDimension(tableWCUs)
				.withResourceId(resourceID);

		try {
			DescribeScalingPoliciesResult dspResult = aaClient.describeScalingPolicies(dspRequest);
			System.out.println("DescribeScalingPolicies result: ");
			System.out.println(dspResult);
		} catch (Exception e) {
			e.printStackTrace();
			System.err.println("Unable to describe scaling policy: ");
			System.err.println(e.getMessage());
		}

	}

}
```

------

## Disabling Application Auto Scaling for a table
<a name="AutoScaling.HowTo.SDK-disable"></a>

The following program reverses the previous process. It removes the auto scaling policy and then deregisters the scalable target.

------
#### [ Java v2 ]

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.applicationautoscaling.ApplicationAutoScalingClient;
import software.amazon.awssdk.services.applicationautoscaling.model.ApplicationAutoScalingException;
import software.amazon.awssdk.services.applicationautoscaling.model.DeleteScalingPolicyRequest;
import software.amazon.awssdk.services.applicationautoscaling.model.DeregisterScalableTargetRequest;
import software.amazon.awssdk.services.applicationautoscaling.model.DescribeScalableTargetsRequest;
import software.amazon.awssdk.services.applicationautoscaling.model.DescribeScalableTargetsResponse;
import software.amazon.awssdk.services.applicationautoscaling.model.DescribeScalingPoliciesRequest;
import software.amazon.awssdk.services.applicationautoscaling.model.DescribeScalingPoliciesResponse;
import software.amazon.awssdk.services.applicationautoscaling.model.ScalableDimension;
import software.amazon.awssdk.services.applicationautoscaling.model.ServiceNamespace;

/**
 * Before running this Java V2 code example, set up your development environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */

public class DisableDynamoDBAutoscaling {
    public static void main(String[] args) {
        final String usage = """

            Usage:
               <tableId> <policyName>\s

            Where:
               tableId - The table Id value (for example, table/Music).\s
               policyName - The name of the policy (for example, $Music5-scaling-policy). 
        
            """;
        if (args.length != 2) {
            System.out.println(usage);
            System.exit(1);
        }

        ApplicationAutoScalingClient appAutoScalingClient = ApplicationAutoScalingClient.builder()
            .region(Region.US_EAST_1)
            .build();

        ServiceNamespace ns = ServiceNamespace.DYNAMODB;
        ScalableDimension tableWCUs = ScalableDimension.DYNAMODB_TABLE_WRITE_CAPACITY_UNITS;
        String tableId = args[0];
        String policyName = args[1];

        deletePolicy(appAutoScalingClient, policyName, tableWCUs, ns, tableId);
        verifyScalingPolicies(appAutoScalingClient, tableId, ns, tableWCUs);
        deregisterScalableTarget(appAutoScalingClient, tableId, ns, tableWCUs);
        verifyTarget(appAutoScalingClient, tableId, ns, tableWCUs);
    }

    public static void deletePolicy(ApplicationAutoScalingClient appAutoScalingClient, String policyName, ScalableDimension tableWCUs, ServiceNamespace ns, String tableId) {
        try {
            DeleteScalingPolicyRequest delSPRequest = DeleteScalingPolicyRequest.builder()
                .policyName(policyName)
                .scalableDimension(tableWCUs)
                .serviceNamespace(ns)
                .resourceId(tableId)
                .build();

            appAutoScalingClient.deleteScalingPolicy(delSPRequest);
            System.out.println(policyName +" was deleted successfully.");

        } catch (ApplicationAutoScalingException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
        }
    }

    // Verify that the scaling policy was deleted
    public static void verifyScalingPolicies(ApplicationAutoScalingClient appAutoScalingClient, String tableId, ServiceNamespace ns, ScalableDimension tableWCUs) {
        DescribeScalingPoliciesRequest dscRequest = DescribeScalingPoliciesRequest.builder()
            .scalableDimension(tableWCUs)
            .serviceNamespace(ns)
            .resourceId(tableId)
            .build();

        DescribeScalingPoliciesResponse response = appAutoScalingClient.describeScalingPolicies(dscRequest);
        System.out.println("DescribeScalableTargets result: ");
        System.out.println(response);
    }

    public static void deregisterScalableTarget(ApplicationAutoScalingClient appAutoScalingClient, String tableId, ServiceNamespace ns, ScalableDimension tableWCUs) {
        try {
            DeregisterScalableTargetRequest targetRequest = DeregisterScalableTargetRequest.builder()
                .scalableDimension(tableWCUs)
                .serviceNamespace(ns)
                .resourceId(tableId)
                .build();

            appAutoScalingClient.deregisterScalableTarget(targetRequest);
            System.out.println("The scalable target was deregistered.");

        } catch (ApplicationAutoScalingException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
        }
    }

    public static void verifyTarget(ApplicationAutoScalingClient appAutoScalingClient, String tableId, ServiceNamespace ns, ScalableDimension tableWCUs) {
        DescribeScalableTargetsRequest dscRequest = DescribeScalableTargetsRequest.builder()
            .scalableDimension(tableWCUs)
            .serviceNamespace(ns)
            .resourceIds(tableId)
            .build();

        DescribeScalableTargetsResponse response = appAutoScalingClient.describeScalableTargets(dscRequest);
        System.out.println("DescribeScalableTargets result: ");
        System.out.println(response);
    }
}
```

------
#### [ Java v1 ]

```
package com.amazonaws.codesamples.autoscaling;

import com.amazonaws.services.applicationautoscaling.AWSApplicationAutoScalingClient;
import com.amazonaws.services.applicationautoscaling.model.DeleteScalingPolicyRequest;
import com.amazonaws.services.applicationautoscaling.model.DeregisterScalableTargetRequest;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalableTargetsRequest;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalableTargetsResult;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalingPoliciesRequest;
import com.amazonaws.services.applicationautoscaling.model.DescribeScalingPoliciesResult;
import com.amazonaws.services.applicationautoscaling.model.ScalableDimension;
import com.amazonaws.services.applicationautoscaling.model.ServiceNamespace;

public class DisableDynamoDBAutoscaling {

	static AWSApplicationAutoScalingClient aaClient = new AWSApplicationAutoScalingClient();

	public static void main(String args[]) {

		ServiceNamespace ns = ServiceNamespace.Dynamodb;
		ScalableDimension tableWCUs = ScalableDimension.DynamodbTableWriteCapacityUnits;
		String resourceID = "table/TestTable";

		// Delete the scaling policy
		DeleteScalingPolicyRequest delSPRequest = new DeleteScalingPolicyRequest()
				.withServiceNamespace(ns)
				.withScalableDimension(tableWCUs)
				.withResourceId(resourceID)
				.withPolicyName("MyScalingPolicy");

		try {
			aaClient.deleteScalingPolicy(delSPRequest);
		} catch (Exception e) {
			System.err.println("Unable to delete scaling policy: ");
			System.err.println(e.getMessage());
		}

		// Verify that the scaling policy was deleted
		DescribeScalingPoliciesRequest descSPRequest = new DescribeScalingPoliciesRequest()
				.withServiceNamespace(ns)
				.withScalableDimension(tableWCUs)
				.withResourceId(resourceID);

		try {
			DescribeScalingPoliciesResult dspResult = aaClient.describeScalingPolicies(descSPRequest);
			System.out.println("DescribeScalingPolicies result: ");
			System.out.println(dspResult);
		} catch (Exception e) {
			e.printStackTrace();
			System.err.println("Unable to describe scaling policy: ");
			System.err.println(e.getMessage());
		}

		System.out.println();

		// Remove the scalable target
		DeregisterScalableTargetRequest delSTRequest = new DeregisterScalableTargetRequest()
				.withServiceNamespace(ns)
				.withScalableDimension(tableWCUs)
				.withResourceId(resourceID);

		try {
			aaClient.deregisterScalableTarget(delSTRequest);
		} catch (Exception e) {
			System.err.println("Unable to deregister scalable target: ");
			System.err.println(e.getMessage());
		}

		// Verify that the scalable target was removed
		DescribeScalableTargetsRequest dscRequest = new DescribeScalableTargetsRequest()
				.withServiceNamespace(ns)
				.withScalableDimension(tableWCUs)
				.withResourceIds(resourceID);

		try {
			DescribeScalableTargetsResult dsaResult = aaClient.describeScalableTargets(dscRequest);
			System.out.println("DescribeScalableTargets result: ");
			System.out.println(dsaResult);
			System.out.println();
		} catch (Exception e) {
			System.err.println("Unable to describe scalable target: ");
			System.err.println(e.getMessage());
		}

	}

}
```

------