

# Programmatic access to Amazon EC2
<a name="ec2-api-intro"></a>

You can create and manage your Amazon EC2 resources using the AWS Management Console or a programmatic interface. For information about using the Amazon EC2 console, see the [Amazon EC2 User Guide](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/).

**How it works**
+ [Amazon EC2 endpoints](ec2-endpoints.md)
+ [Eventual consistency](eventual-consistency.md)
+ [Idempotency](ec2-api-idempotency.md)
+ [Request throttling](ec2-api-throttling.md)
+ [Pagination](ec2-api-pagination.md)

**Programmatic interfaces**
+ [AWS Command Line Interface (AWS CLI)](ec2-aws-cli.md)
+ [AWS CloudFormation](ec2-cloudformation.md)
+ [AWS SDKs](sdk-general-information-section.md)
+ [Low-level API](ec2-low-level-api.md)

**Getting started**
+ [Code examples](service_code_examples.md)
+ [Console-to-Code](console-to-code.md)

**Monitoring**
+ [AWS CloudTrail](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitor-with-cloudtrail.html)
+ [Monitor requests](monitor.md)

# Amazon EC2 service endpoints
<a name="ec2-endpoints"></a>

An endpoint is a URL that serves as an entry point for an AWS web service. Amazon EC2 supports the following endpoint types:
+ [IPv4 endpoints](#ipv4)
+ [Dual-stack endpoints](#ipv6) (support both IPv4 and IPv6)
+ [ FIPS endpoints](https://docs.aws.amazon.com/general/latest/gr/rande.html#FIPS-endpoints)

When you make a request, you can specify the endpoint to use. If you do not specify an endpoint, the IPv4 endpoint is used by default. To use a different endpoint type, you must specify it in your request. For examples of how to do this, see [Specifying endpoints](#examples). For a table of available endpoints, see [Service endpoints by Region](#service-endpoints).

## IPv4 endpoints
<a name="ipv4"></a>

IPv4 endpoints support IPv4 traffic only. IPv4 endpoints are available for all Regions.

If you specify the general endpoint, `ec2.amazonaws.com`, we use the endpoint for `us-east-1`. To use a different Region, specify its associated endpoint. For example, if you specify `ec2.us-east-2.amazonaws.com` as the endpoint, we direct your request to the `us-east-2` endpoint. 

IPv4 endpoint names use the following naming convention: 
+ `service.region.amazonaws.com`

For example, the IPv4 endpoint name for the `eu-west-1` Region is `ec2.eu-west-1.amazonaws.com`.

## Dual-stack (IPv4 and IPv6) endpoints
<a name="ipv6"></a>

Dual-stack endpoints support both IPv4 and IPv6 traffic. When you make a request to a dual-stack endpoint, the endpoint URL resolves to an IPv6 or an IPv4 address, depending on the protocol used by your network and client.

Amazon EC2 supports only regional dual-stack endpoints, which means that you must specify the Region as part of the endpoint name. Dual-stack endpoint names use the following naming convention:
+ `ec2.region.api.aws`

For example, the dual-stack endpoint name for the `eu-west-1` Region is `ec2.eu-west-1.api.aws`.

## Service endpoints by Region
<a name="service-endpoints"></a>

The following are the service endpoints for Amazon EC2. For more information about Regions, see [Regions and Availability Zones](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html) in the *Amazon EC2 User Guide*.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ec2/latest/devguide/ec2-endpoints.html)

## Specifying endpoints
<a name="examples"></a>

This section provides some examples of how to specify an endpoint when making a request.

------
#### [ AWS CLI ]

The following examples show how to specify an endpoint for the `us-east-2` Region using the AWS CLI.
+ **Dual-stack**

  ```
  aws ec2 describe-regions --region us-east-2 --endpoint-url https://ec2.us-east-2.api.aws
  ```
+ **IPv4**

  ```
  aws ec2 describe-regions --region us-east-2 --endpoint-url https://ec2.us-east-2.amazonaws.com
  ```

------
#### [ AWS SDK for Java 2.x ]

The following examples show how to specify an endpoint for the `us-east-2` Region using the AWS SDK for Java 2.x.
+ **Dual-stack**

  ```
  Ec2Client client = Ec2Client.builder()
      .region(Region.US_EAST_2)
      .endpointOverride(URI.create("https://ec2.us-east-2.api.aws"))
      .build();
  ```
+ **IPv4**

  ```
  Ec2Client client = Ec2Client.builder()
      .region(Region.US_EAST_2)
      .endpointOverride(URI.create("https://ec2.us-east-2.amazonaws.com"))
      .build();
  ```

------
#### [ AWS SDK for Java 1.x ]

The following examples show how to specify an endpoint for the `eu-west-1` Region using the AWS SDK for Java 1.x.
+ **Dual-stack**

  ```
  AmazonEC2 s3 = AmazonEC2ClientBuilder.standard()
       .withEndpointConfiguration(new EndpointConfiguration(
            "https://ec2.eu-west-1.api.aws",
            "eu-west-1"))
       .build();
  ```
+ **IPv4**

  ```
  AmazonEC2 s3 = AmazonEC2ClientBuilder.standard()
       .withEndpointConfiguration(new EndpointConfiguration(
            "https://ec2.eu-west-1.amazonaws.com",
            "eu-west-1"))
       .build();
  ```

------
#### [ AWS SDK for Go ]

The following examples show how to specify an endpoint for the `us-east-1` Region using the AWS SDK for Go.
+ **Dual-stack**

  ```
  sess := session.Must(session.NewSession())
  svc := ec2.New(sess, &aws.Config{
      Region: aws.String(endpoints.UsEast1RegionID),
      Endpoint: aws.String("https://ec2.us-east-1.api.aws")
  })
  ```
+ **IPv4**

  ```
  sess := session.Must(session.NewSession())
  svc := ec2.New(sess, &aws.Config{
      Region: aws.String(endpoints.UsEast1RegionID),
      Endpoint: aws.String("https://ec2.us-east-1.amazonaws.com")
  })
  ```

------

# Eventual consistency in the Amazon EC2 API
<a name="eventual-consistency"></a>

The Amazon EC2 API follows an eventual consistency model, due to the distributed nature of the system supporting the API. This means that the result of an API command you run that affects your Amazon EC2 resources might not be immediately visible to all subsequent commands you run. You should keep this in mind when you carry out an API command that immediately follows a previous API command.

Eventual consistency can affect the way you manage your resources. For example, if you run a command to create a resource, it will eventually be visible to other commands. This means that if you run a command to modify or describe the resource that you just created, its ID might not have propagated throughout the system, and you will get an error responding that the resource does not exist.

To manage eventual consistency, you can do the following:
+ Confirm the state of the resource before you run a command to modify it. Run the appropriate `Describe` command using an exponential backoff algorithm to ensure that you allow enough time for the previous command to propagate through the system. To do this, run the `Describe` command repeatedly, starting with a couple of seconds of wait time, and increasing gradually up to a few minutes of wait time. 
+ Add wait time between subsequent commands, even if a `Describe` command returns an accurate response. Apply an exponential backoff algorithm starting with a couple of seconds of wait time, and increase gradually up to a few minutes of wait time.

**Eventual consistency error examples**  
The following are examples of error codes you may encounter as a result of eventual consistency.
+ `InvalidInstanceID.NotFound`

  If you successfully run the `RunInstances` command, and then immediately run another command using the instance ID that was provided in the response of `RunInstances`, it may return an `InvalidInstanceID.NotFound` error. This does not mean the instance does not exist. 

  Some specific commands that may be affected are:
  + `DescribeInstances`: To confirm the actual state of the instance, run this command using an exponential backoff algorithm.
  + `TerminateInstances`: To confirm the state of the instance, first run the `DescribeInstances` command using an exponential backoff algorithm.
**Important**  
If you get an `InvalidInstanceID.NotFound` error after running `TerminateInstances`, this does not mean that the instance is or will be terminated. Your instance could still be running. This is why it is important to first confirm the instance’s state using `DescribeInstances`.
+ `InvalidGroup.NotFound`

  If you successfully run the `CreateSecurityGroup` command, and then immediately run another command using the security group ID that was provided in the response of `CreateSecurityGroup`, it may return an `InvalidGroup.NotFound` error. To confirm the state of the security group, run the `DescribeSecurityGroups` command using an exponential backoff algorithm.
+ `InstanceLimitExceeded`

  You have requested more instances than your current instance limit allows for the specified instance type. You could reach this limit unexpectedly if you are launching and terminating instances rapidly, as terminated instances count toward your instance limit for a while after they've been terminated.

# Ensuring idempotency in Amazon EC2 API requests
<a name="ec2-api-idempotency"></a>

When you make a mutating API request, the request typically returns a result before the operation's asynchronous workflows have completed. Operations might also time out or encounter other server issues before they complete, even though the request has already returned a result. This could make it difficult to determine whether the request succeeded or not, and could lead to multiple retries to ensure that the operation completes successfully. However, if the original request and the subsequent retries are successful, the operation is completed multiple times. This means that you might create more resources than you intended.

*Idempotency* ensures that an API request completes no more than one time. With an idempotent request, if the original request completes successfully, any subsequent retries complete successfully without performing any further actions. However, the result might contain updated information, such as the current creation status.

**Topics**
+ [

## Idempotency in Amazon EC2
](#client-tokens)
+ [

## RunInstances idempotency
](#run-instances-idempotency)
+ [

## Examples
](#Run_Instance_Idempotency_CLI)
+ [

## Retry recommendations for idempotent requests
](#recommended-actions)

## Idempotency in Amazon EC2
<a name="client-tokens"></a>

The following API actions are idempotent by default, and do not require additional configuration. The corresponding AWS CLI commands also support idempotency by default.

**Idempotent by default**
+ AssociateAddress
+ CreateVpnConnection
+ DisassociateAddress
+ ReplaceNetworkAclAssociation
+ TerminateInstances

The following API actions optionally support idempotency using a *client token*. The corresponding AWS CLI commands also support idempotency using a client token. A client token is a unique, case-sensitive string of up to 64 ASCII characters. To make an idempotent API request using one of these actions, specify a client token in the request. You should not reuse the same client token for other API requests. If you retry a request that completed successfully using the same client token and the same parameters, the retry succeeds without performing any further actions. If you retry a successful request using the same client token, but one or more of the parameters are different, other than the Region or Availability Zone, the retry fails with an `IdempotentParameterMismatch` error.

**Idempotent using a client token**
+ AllocateHosts
+ AllocateIpamPoolCidr
+ AssociateClientVpnTargetNetwork
+ AssociateIpamResourceDiscovery
+ AttachVerifiedAccessTrustProvider
+ AuthorizeClientVpnIngress
+ CopyFpgaImage
+ CopyImage
+ CreateCapacityReservation
+ CreateCapacityReservationFleet
+ CreateClientVpnEndpoint
+ CreateClientVpnRoute
+ CreateEgressOnlyInternetGateway
+ CreateFleet
+ CreateFlowLogs
+ CreateFpgaImage
+ CreateInstanceConnectEndpoint
+ CreateIpam
+ CreateIpamPool
+ CreateIpamResourceDiscovery
+ CreateIpamScope
+ CreateLaunchTemplate
+ CreateLaunchTemplateVersion
+ CreateManagedPrefixList
+ CreateNatGateway
+ CreateNetworkAcl
+ CreateNetworkInsightsAccessScope
+ CreateNetworkInsightsPath
+ CreateNetworkInterface
+ CreateReplaceRootVolumeTask
+ CreateReservedInstancesListing
+ CreateRouteTable
+ CreateTrafficMirrorFilter
+ CreateTrafficMirrorFilterRule
+ CreateTrafficMirrorSession
+ CreateTrafficMirrorTarget
+ CreateVerifiedAccessEndpoint
+ CreateVerifiedAccessGroup
+ CreateVerifiedAccessInstance
+ CreateVerifiedAccessTrustProvider
+ CreateVolume
+ CreateVpcEndpoint
+ CreateVpcEndpointConnectionNotification
+ CreateVpcEndpointServiceConfiguration
+ DeleteVerifiedAccessEndpoint
+ DeleteVerifiedAccessGroup
+ DeleteVerifiedAccessInstance
+ DeleteVerifiedAccessTrustProvider
+ DetachVerifiedAccessTrustProvider
+ ExportImage
+ ImportImage
+ ImportSnapshot
+ ModifyInstanceCreditSpecification
+ ModifyLaunchTemplate
+ ModifyReservedInstances
+ ModifyVerifiedAccessEndpoint
+ ModifyVerifiedAccessEndpointPolicy
+ ModifyVerifiedAccessGroup
+ ModifyVerifiedAccessGroupPolicy
+ ModifyVerifiedAccessInstance
+ ModifyVerifiedAccessInstanceLoggingConfiguration
+ ModifyVerifiedAccessTrustProvider
+ ProvisionIpamPoolCidr
+ PurchaseHostReservation
+ RequestSpotFleet
+ RequestSpotInstances
+ RunInstances
+ StartNetworkInsightsAccessScopeAnalysis
+ StartNetworkInsightsAnalysis

**Types of idempotency**
+ Regional – Requests are idempotent in each Region. However, you can use the same request, including the same client token, in a different Region.
+ Zonal – Requests are idempotent in each Availability Zone in a Region. For example, if you specify the same client token in two calls to **AllocateHosts** in the same Region, the calls succeed if they specify different values for the **AvailabilityZone** parameter.

## RunInstances idempotency
<a name="run-instances-idempotency"></a>

The [RunInstances](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html) API action uses both Regional and zonal idempotency.

The type of idempotency that is used depends on how you specify the Availability Zone in your RunInstances API request. The request uses **zonal idempotency** in the following cases:
+ If you explicitly specify an Availability Zone using the **AvailabilityZone** parameter in the **Placement** data type
+ If you implicitly specify an Availability Zone using the **SubnetId** parameter

If you do not explicitly or implicitly specify an Availability Zone, the request uses **Regional idempotency**.

### Zonal idempotency
<a name="zonal-idempotency"></a>

Zonal idempotency ensures that a RunInstances API request is idempotent in each Availability Zone in a Region. This ensures that a request with the same client token can complete only once within each Availability Zone in a Region. However, the same client token can be used to launch instances in other Availability Zones in the Region.

For example, if you send an idempotent request to launch an instance in the `us-east-1a` Availability Zone, and then use the same client token in a request in the `us-east-1b` Availability Zone, we launch instances in each of those Availability Zones. If one or more of the parameters are different, subsequent retries with the same client token in those Availability Zones either return successfully without performing any further actions or fail with an `IdempotentParameterMismatch` error.

### Regional idempotency
<a name="regional-idempotency"></a>

Regional idempotency ensures that a RunInstances API request is idempotent in a Region. This ensures that a request with the same client token can complete only once within a Region. However, the exact same request, with the same client token, can be used to launch instances in a different Region.

For example, if you send an idempotent request to launch an instance in the `us-east-1` Region, and then use the same client token in a request in the `eu-west-1` Region, we launch instances in each of those Regions. If one or more of the parameters are different, subsequent retries with the same client token in those Regions either return successfully without performing any further actions or fail with an `IdempotentParameterMismatch` error.

**Tip**  
If one of the Availability Zones in the requested Region is not available, RunInstances requests that use regional idempotency could fail. To leverage the Availability Zone features offered by the AWS infrastructure, we recommend that you use zonal idempotency when launching instances. RunInstances requests that use zonal idempotency and target an available Availability Zone succeed even if another Availability Zone in the requested Region is not available.

## Examples
<a name="Run_Instance_Idempotency_CLI"></a>

### AWS CLI command examples
<a name="cli-example"></a>

To make an AWS CLI command idempotent, add the `--client-token` option. 

**Example 1: Idempotency**  
The following [allocate-hosts](https://docs.aws.amazon.com/cli/latest/reference/ec2/allocate-hosts.html) command uses idempotency as it includes a client token.

```
aws ec2 allocate-hosts  --instance-type m5.large  --availability-zone eu-west-1a  --auto-placement on  --quantity 1 --client-token 550e8400-e29b-41d4-a716-446655440000
```

**Example 2: run-instances regional idempotency**  
The following [run-instances](https://docs.aws.amazon.com/cli/latest/reference/ec2/run-instances.html) command uses regional idempotency as it includes a client token but does not explicitly or implicitly specify an Availability Zone.

```
aws ec2 run-instances --image-id ami-b232d0db --count 1 --key-name my-key-pair --client-token 550e8400-e29b-41d4-a716-446655440000
```

**Example 3: run-instances zonal idempotency**  
The following [run-instances](https://docs.aws.amazon.com/cli/latest/reference/ec2/run-instances.html) command uses zonal idempotency as it includes a client token and an explicitly specified Availability Zone.

```
aws ec2 run-instances  --placement "AvailabilityZone=us-east-1a" --image-id ami-b232d0db --count 1 --key-name my-key-pair --client-token 550e8400-e29b-41d4-a716-446655440000
```

### API request examples
<a name="api-example"></a>

To make an API request idempotent, add the `ClientToken` parameter.

**Example 1: Idempotency**  
The following [AllocateHosts](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_AllocateHosts.html) API request uses idempotency as it includes a client token.

```
https://ec2.amazonaws.com/?Action=AllocateHosts
&AvailabilityZone=us-east-1b
&InstanceType=m5.large
&Quantity=1
&AutoPlacement=off
&ClientToken=550e8400-e29b-41d4-a716-446655440000
&AUTHPARAMS
```

**Example 2: RunInstances regional idempotency**  
The following [RunInstances](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html) API request uses regional idempotency as it includes a client token but does not explicitly or implicitly specify an Availability Zone.

```
https://ec2.amazonaws.com/?Action=RunInstances
&ImageId=ami-3ac33653
&MaxCount=1
&MinCount=1
&KeyName=my-key-pair
&ClientToken=550e8400-e29b-41d4-a716-446655440000
&AUTHPARAMS
```

**Example 3: RunInstances zonal idempotency**  
The following [RunInstances](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html) API request uses zonal idempotency as it includes a client token and an explicitly specified Availability Zone.

```
https://ec2.amazonaws.com/?Action=RunInstances
&Placement.AvailabilityZone=us-east-1d
&ImageId=ami-3ac33653
&MaxCount=1
&MinCount=1
&KeyName=my-key-pair
&ClientToken=550e8400-e29b-41d4-a716-446655440000
&AUTHPARAMS
```

## Retry recommendations for idempotent requests
<a name="recommended-actions"></a>

The following table shows some common responses that you might get for idempotent API requests, and provides retry recommendations.


| Response | Recommendation | Comments | 
| --- | --- | --- | 
|  200 (OK)  |  Do not retry  |  The original request completed successfully. Any subsequent retries return successfully.  | 
|  400-series response codes ([client errors](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html#CommonErrors))  |  Do not retry  |  There is a problem with the request, from among the following:  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ec2/latest/devguide/ec2-api-idempotency.html) If the request involves a resource that is in the process of changing states, retrying the request could possibly succeed.  | 
|  500-series response codes ([server errors](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html#api-error-codes-table-server))  |  Retry  |  The error is caused by an AWS server-side issue and is generally transient. Repeat the request with an appropriate backoff strategy.  | 

# Request throttling for the Amazon EC2 API
<a name="ec2-api-throttling"></a>

Amazon EC2 throttles EC2 API requests for each AWS account on a per-Region basis. We do this to help the performance of the service, and to ensure fair usage for all Amazon EC2 customers. Throttling ensures that requests to the Amazon EC2 API do not exceed the maximum allowed API request limits. API requests are subject to the request limits whether they originate from:
+ A third-party application
+ A command line tool
+ The Amazon EC2 console

If you exceed an API throttling limit, you get the `RequestLimitExceeded` error code.

**Topics**
+ [

## How throttling is applied
](#throttling-how)
+ [Request token limits](#throttling-limits-rate-based)
+ [Resource token limits](#throttling-limits-cost-based)
+ [

## Monitor API throttling
](#throttling-monitor)
+ [

## Retries and exponential backoff
](#api-backoff)
+ [

## Request a limit increase
](#throttling-increase)

## How throttling is applied
<a name="throttling-how"></a>

Amazon EC2 uses the [token bucket algorithm](https://en.wikipedia.org/wiki/Token_bucket) to implement API throttling. With this algorithm, your account has a *bucket* that holds a specific number of *tokens*. The number of tokens in the bucket represents your throttling limit at any given second.

Amazon EC2 implements two types of API throttling:

**Topics**
+ [

### Request rate limiting
](#throttling-rate-based)
+ [

### Resource rate limiting
](#throttling-cost-based)

### Request rate limiting
<a name="throttling-rate-based"></a>

With request rate limiting, each API is evaluated individually, and you are throttled on the number of requests you make on a per-API basis. Each request that you make removes one token from the API's bucket. For example, the token bucket size for `DescribeHosts`, a *non-mutating * API action, is 100 tokens. You can make up to 100 `DescribeHosts` requests in one second. If you exceed 100 requests in a second, you are throttled on that API and the remaining requests within that second fail, however, requests for other API are not affected.

Buckets automatically refill at a set rate. If the bucket is below its maximum capacity, a set number of tokens is added back to it every second until it reaches its maximum capacity. If the bucket is full when refill tokens arrive, they are discarded. The bucket can't hold more than its maximum number of tokens. For example, the bucket size for `DescribeHosts`, a *non-mutating* API action, is 100 tokens and the refill rate is 20 tokens per second. If you make 100 `DescribeHosts` requests in one second, the bucket is reduced to zero (0) tokens. The bucket is then refilled by 20 tokens every second, until it reaches its maximum capacity of 100 tokens. This means that an empty bucket reaches its maximum capacity after 5 seconds if no requests are made during that time.

You do not need to wait for the bucket to be completely full before you can make API requests. You can use refill tokens as they are added to the bucket. If you immediately use the refill tokens, the bucket does not reach its maximum capacity. For example, the bucket size for `DescribeHosts`, a *non-mutating* API action, is 100 tokens and the refill rate is 20 tokens per second. If you deplete the bucket by making 100 API requests in a second, you can continue to make 20 API requests per second by using the refill tokens as they are added to the bucket. The bucket can refill to the maximum capacity only if you make fewer than 20 API requests per second.

For more information, see [Request token bucket sizes and refill rates](#throttling-limits-rate-based).

### Resource rate limiting
<a name="throttling-cost-based"></a>

Some API actions, such as `RunInstances` and `TerminateInstances`, as described in the table that follows, use resource rate limiting in addition to request rate limiting. These API actions have a separate resource token bucket that depletes based on the number of resources that are impacted by the request. Like request token buckets, resource token buckets have a bucket maximum that allows you to burst, and a refill rate that allows you to sustain a steady rate of requests for as long as needed. If you exceed a specific bucket limit for an API, including when a bucket has not yet refilled to support the next API request, the action of the API is limited even though you have not reached the total API throttle limit.

For example, the resource token bucket size for `RunInstances` is 1000 tokens, and the refill rate is two tokens per second. Therefore, you can immediately launch 1000 instances, using any number of API requests, such as one request for 1000 instances or four requests for 250 instances. After the resource token bucket is empty, you can launch up to two instances every second, using either one request for two instances or two requests for one instance.

For more information, see [Resource token bucket sizes and refill rates](#throttling-limits-cost-based).

## Request token bucket sizes and refill rates
<a name="throttling-limits-rate-based"></a>

For request rate limiting purposes, API actions are grouped into the following categories:
+ **Non-mutating actions** — API actions that retrieve data about resources. This category generally includes all `Describe*`, `List*`, `Search*`, and `Get*` API actions, such as `DescribeRouteTables`, `SearchTransitGatewayRoutes`, and `GetIpamPoolCidrs`. These API actions typically have the highest API throttling limits.
+ **Unfiltered and unpaginated non-mutating actions** — A specific subset of non-mutating API actions that, when requested without specifying either [pagination](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-pagination.html) or a [filter](https://docs.aws.amazon.com//AWSEC2/latest/UserGuide/Using_Filtering.html#Filtering_Resources_CLI), use tokens from a smaller token bucket. It is recommended that you make use of pagination and filtering so that tokens are deducted from the standard (larger) token bucket.
+ **Mutating actions** — API actions that create, modify, or delete resources. This category generally includes all API actions that are not categorized as *non-mutating actions*, such as `AllocateHosts`, `ModifyHosts`, and `CreateCapacityReservation`. These actions have a lower throttling limit than non-mutating API actions.
+ **Resource-intensive actions** — Mutating API actions that take the most time and consume the most resources to complete. These actions have an even lower throttling limit than *mutating actions*. They are throttled separately from other *mutating actions*.
+ **Console non-mutating actions** — Non-mutating API actions that are requested from the Amazon EC2 console. These API actions are throttled separately from other non-mutating API actions.
+ **Uncategorized actions** — These are API actions that receive their own token bucket sizes and refill rates, even though by definition they fit in one of the other categories.


| API action category | Actions | Bucket maximum capacity | Bucket refill rate | 
| --- | --- | --- | --- | 
| Non-mutating actions |  The `Describe*`, `List*`, `Search*`, and `Get*` API actions that are not included in another category.  | 100 | 20 | 
| Unfiltered and unpaginated non-mutating actions |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ec2/latest/devguide/ec2-api-throttling.html)  | 50 | 10 | 
| Mutating actions | All mutating API actions that are not *Resource-intensive actions* or *Uncategorized actions*. | 50 | 5 | 
| Resource-intensive actions |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ec2/latest/devguide/ec2-api-throttling.html)  | 50 | 5 | 
| Console non-mutating actions |  The `Describe*`, `List*`, `Search*`, and `Get*` API actions, that are called by the Amazon EC2 console, but not included in another category.  | 100 | 10 | <a name="uncategorized"></a>


| Uncategorized actions | Bucket maximum capacity | Bucket refill rate | 
| --- | --- | --- | 
| AcceptVpcEndpointConnections | 10 | 1 | 
| AdvertiseByoipCidr | 1 | 0.1 | 
| AssignIpv6Addresses | 100 | 5 | 
| AssignPrivateIpAddresses | 100 | 5 | 
| AssignPrivateNatGatewayAddress | 10 | 1 | 
| AssociateCapacityReservationBillingOwner | 1 | 0.5 | 
| AssociateEnclaveCertificateIamRole | 10 | 1 | 
| AssociateIamInstanceProfile | 100 | 5 | 
| AssociateNatGatewayAddress | 10 | 1 | 
| AttachVerifiedAccessTrustProvider | 10 | 2 | 
| AuthorizeClientVpnIngress | 5 | 2 | 
| CancelDeclarativePoliciesReport | 1 | 1 | 
| CopyImage | 100 | 1 | 
| CreateClientVpnRoute | 5 | 2 | 
| CreateCoipCidr | 5 | 1 | 
| CreateCoipPool | 5 | 1 | 
| CreateDefaultSubnet | 1 | 1 | 
| CreateDefaultVpc | 1 | 1 | 
| CreateLaunchTemplateVersion | 100 | 5 | 
| CreateNatGateway | 10 | 1 | 
| CreateNetworkInterface | 100 | 5 | 
| CreateRestoreImageTask | 50 | 0.1 | 
| CreateSnapshot | 100 | 5 | 
| CreateSnapshots | 100 | 5 | 
| CreateSpotDatafeedSubscription | 50 | 3 | 
| CreateStoreImageTask | 50 | 0.1 | 
| CreateSubnetCidrReservation | 5 | 1 | 
| CreateTags | 100 | 10 | 
| CreateVerifiedAccessEndpoint | 20 | 4 | 
| CreateVerifiedAccessGroup | 10 | 2 | 
| CreateVerifiedAccessInstance | 10 | 2 | 
| CreateVerifiedAccessTrustProvider | 10 | 2 | 
| CreateVolume | 100 | 5 | 
| CreateVpcEndpoint | 4 | 0.3 | 
| CreateVpcEndpointServiceConfiguration | 10 | 1 | 
| DeleteClientVpnRoute | 5 | 2 | 
| DeleteCoipCidr | 5 | 1 | 
| DeleteCoipPool | 5 | 1 | 
| DeleteCoipPoolPermission | 5 | 1 | 
| DeleteNatGateway | 10 | 1 | 
| DeleteNetworkInterface | 100 | 5 | 
| DeleteSnapshot | 100 | 5 | 
| DeleteSpotDatafeedSubscription | 50 | 3 | 
| DeleteSubnetCidrReservation | 5 | 1 | 
| DeleteQueuedReservedInstances | 5 | 5 | 
| DeleteTags | 100 | 10 | 
| DeleteVerifiedAccessEndpoint | 20 | 4 | 
| DeleteVerifiedAccessGroup | 10 | 2 | 
| DeleteVerifiedAccessInstance | 10 | 2 | 
| DeleteVerifiedAccessTrustProvider | 10 | 2 | 
| DeleteVolume | 100 | 5 | 
| DeleteVpcEndpoints | 4 | 0.3 | 
| DeleteVpcEndpointServiceConfigurations | 10 | 1 | 
| DeprovisionByoipCidr | 1 | 0.1 | 
| DeregisterImage | 100 | 5 | 
| DescribeAggregateIdFormat | 10 | 10 | 
| DescribeByoipCidrs | 1 | 0.5 | 
| DescribeCapacityBlockExtensionOfferings | 10 | 0.15 | 
| DescribeCapacityBlockOfferings | 10 | 0.15 | 
| DescribeDeclarativePoliciesReports | 5 | 5 | 
| DescribeHostReservations | 5 | 2 | 
| DescribeHostReservationOfferings | 5 | 2 | 
| DescribeIdentityIdFormat | 10 | 10 | 
| DescribeIdFormat | 10 | 10 | 
| DescribeInstanceTopology | 1 | 1 | 
| DescribeMovingAddresses | 1 | 1 | 
| DescribePrincipalIdFormat | 10 | 10 | 
| DescribeReservedInstancesOfferings | 10 | 10 | 
| DescribeSecurityGroupReferences | 20 | 5 | 
| DescribeSpotDatafeedSubscription | 100 | 13 | 
| DescribeSpotFleetInstances | 100 | 5 | 
| DescribeSpotFleetRequestHistory | 100 | 5 | 
| DescribeSpotFleetRequests | 50 | 3 | 
| DescribeStaleSecurityGroups | 20 | 5 | 
| DescribeStoreImageTasks | 50 | 0.5 | 
| DescribeVerifiedAccessInstanceLoggingConfigurations | 10 | 2 | 
| DetachVerifiedAccessTrustProvider | 10 | 2 | 
| DisableFastLaunch | 5 | 2 | 
| DisableImageBlockPublicAccess | 1 | 0.1 | 
| DisableSnapshotBlockPublicAccess | 1 | 0.1 | 
| DisassociateCapacityReservationBillingOwner | 1 | 0.5 | 
| DisassociateEnclaveCertificateIamRole | 10 | 1 | 
| DisassociateIamInstanceProfile | 100 | 5 | 
| DisassociateNatGatewayAddress | 10 | 1 | 
| EnableFastLaunch | 5 | 2 | 
| EnableImageBlockPublicAccess | 1 | 0.1 | 
| EnableSnapshotBlockPublicAccess | 1 | 0.1 | 
| GetAssociatedEnclaveCertificateIamRoles | 10 | 1 | 
| GetDeclarativePoliciesReportSummary | 5 | 5 | 
| GetHostReservationPurchasePreview | 5 | 2 | 
| ModifyImageAttribute | 100 | 5 | 
| ModifyInstanceMetadataDefaults | 2 | 2 | 
| ModifyInstanceMetadataOptions | 100 | 5 | 
| ModifyLaunchTemplate | 100 | 5 | 
| ModifyNetworkInterfaceAttribute | 100 | 5 | 
| ModifySnapshotAttribute | 100 | 5 | 
| ModifyVerifiedAccessEndpoint | 20 | 4 | 
| ModifyVerifiedAccessEndpointPolicy | 20 | 4 | 
| ModifyVerifiedAccessGroup | 10 | 2 | 
| ModifyVerifiedAccessGroupPolicy | 20 | 4 | 
| ModifyVerifiedAccessInstance | 10 | 2 | 
| ModifyVerifiedAccessInstanceLoggingConfiguration | 10 | 2 | 
| ModifyVerifiedAccessTrustProvider | 10 | 2 | 
| ModifyVpcEndpoint | 4 | 0.3 | 
| ModifyVpcEndpointServiceConfiguration | 10 | 1 | 
| MoveAddressToVpc | 1 | 1 | 
| ProvisionByoipCidr | 1 | 0.1 | 
| PurchaseCapacityBlock | 10 | 0.15 | 
| PurchaseCapacityBlockExtension | 10 | 0.15 | 
| PurchaseHostReservation | 5 | 2 | 
| PurchaseReservedInstancesOffering | 5 | 5 | 
| RejectVpcEndpointConnections | 10 | 1 | 
| RestoreAddressToClassic | 1 | 1 | 
| RevokeClientVpnIngress | 5 | 2 | 
| RunInstances | 5 | 2 | 
| StartDeclarativePoliciesReport | 1 | 1 | 
| StartInstances | 5 | 2 | 
| TerminateInstances | 100 | 5 | 
| UnassignPrivateIpAddresses | 100 | 5 | 
| UnassignPrivateNatGatewayAddress | 10 | 1 | 
| WithdrawByoipCidr | 1 | 0.1 | 

## Resource token bucket sizes and refill rates
<a name="throttling-limits-cost-based"></a>

The following table lists the resource token bucket sizes and refill rates for API actions that use resource rate limiting.


| API action | Bucket maximum capacity | Bucket refill rate | 
| --- | --- | --- | 
| RunInstances | 1000 | 2 | 
| TerminateInstances | 1000 | 20 | 
| StartInstances | 1000 | 2 | 
| StopInstances | 1000 | 20 | 

## Monitor API throttling
<a name="throttling-monitor"></a>

You can use Amazon CloudWatch to monitor your Amazon EC2 API requests and to collect and track metrics around API throttling. You can also create an alarm to warn you when you are close to reaching the API throttling limits. For more information, see [Monitor Amazon EC2 API requests using Amazon CloudWatchMonitor API requests using CloudWatch](monitor.md).

## Retries and exponential backoff
<a name="api-backoff"></a>

Your application might need to retry an API request. For example:
+ To check for an update in the status of a resource
+ To enumerate a large number of resources (for example, all your volumes)
+ To retry a request after it fails with a server error (5xx) or a throttling error

However, for a client error (4xx), you must revise the request to correct the problem before trying the request again.

**Resource status changes**  
Before you start polling to check for status updates, give the request time to potentially complete. For example, wait a few minutes before checking whether your instance is active. When you begin polling, use an appropriate sleep interval between successive requests to lower the rate of API requests. For best results, use an increasing or variable sleep interval.

Alternatively, you can use Amazon EventBridge to notify you of the status of some resources. For example, you can use the **EC2 Instance State-change Notification** event to notify you of a state change for an instance. For more information, see [Automate Amazon EC2 using EventBridge](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/automating_with_eventbridge.html).

**Retries**  
When you need to poll or retry an API request, we recommend using an exponential backoff algorithm to calculate the sleep interval between API requests. The idea behind exponential backoff is to use progressively longer waits between retries for consecutive error responses. You should implement a maximum delay interval, as well as a maximum number of retries. You can also use jitter (randomized delay) to prevent successive collisions. For more information, see [Timeouts, retries, and backoff with jitter](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/).

Each AWS SDK implements automatic retry logic. For more information, see [Retry behavior](https://docs.aws.amazon.com/sdkref/latest/guide/feature-retry-behavior.html) in the *AWS SDKs and Tools Reference Guide*.

## Request a limit increase
<a name="throttling-increase"></a>

You can request an increase for API throttling limits for your AWS account.

**Recommendations**
+ Request at most three times your existing limit in a single request.
+ Prioritize increasing bucket refill rates before increasing bucket maximum capacity.
+ If the requested bucket refill rate would exceed the bucket maximum capacity, increase the bucket maximum capacity at the same time.
+ Provide all API actions that require an increase. Limits are applied to individual API actions, not API action categories.
+ There are both request rate and resource rate limits for the following API actions: `RunInstances`, `StartInstances`, `StopInstances`, and `TerminateInstances`. Be sure to indicate which limit should be increased

**To request access to this feature**

1. Open [AWS Support Center](https://console.aws.amazon.com/support/home#/).

1. Choose **Create case**.

1. Choose **Account and billing**.

1. For **Service**, choose **General Info and Getting Started**.

1. For **Category**, choose **Using AWS & Services**.

1. Choose **Next step: Additional information**.

1. For **Subject**, enter **Request an increase in my Amazon EC2 API throttling limits**.

1. For **Description**, copy the following template and provide the required information.

   ```
   Please increase the API throttling limits for my account. 
   Related page: https://docs.aws.amazon.com/ec2/latest/devguide/ec2-api-throttling.html
   Description: Brief notes about your use case. If available, include the IDs
       of a few Amazon EC2 requests that were throttled.
   Time window: One-hour window when peak throttling or usage occurred.
   region_1 request rate increases:
       action: new_bucket_maximum_capacity
       action: new_bucket_refill_rate
       action: new_bucket_maximum_capacity|new_bucket_refill_rate
   region_1 resource rate increases:
       action: new_bucket_maximum_capacity
       action: new_bucket_refill_rate
       action: new_bucket_maximum_capacity|new_bucket_refill_rate
   region_2 request rate increases:
       action: new_bucket_maximum_capacity
       action: new_bucket_refill_rate
       action: new_bucket_maximum_capacity|new_bucket_refill_rate
   region_2 resource rate increases:
       action: new_bucket_maximum_capacity
       action: new_bucket_refill_rate
       action: new_bucket_maximum_capacity|new_bucket_refill_rate
   ```

1. Choose **Next step: Solve now or contact us**.

1. On the **Contact us** tab, choose your preferred contact language and method of contact.

1. Choose **Submit**.

# Pagination in the Amazon EC2 API
<a name="ec2-api-pagination"></a>

We recommend that you use pagination when calling describe actions that can potentially return a large number of results, such as `DescribeInstances`. Using pagination bounds the number of items returned by a describe call and the time it takes for the call to return. If you have a large number of resources, unpaginated calls might be throttled and could time out. Therefore, overall latency is better with paginated calls than with unpaginated calls because paginated calls are consistently successful.

For more information, see [Pagination](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination) in the *Amazon EC2 API Reference*.

## Best practices
<a name="pagination-best-practices"></a>

Where possible, specify a list of resource IDs in your describe calls. This is the fastest way to describe a large number of resources. Note that you should not specify more than 1,000 IDs in a single call. The following is an example.

```
private List<Reservation> describeMyInstances(List<String> ids){
    if (ids == null || ids.isEmpty()) {
        return ImmutableList.of();
    }
        
    final DescribeInstancesRequest request = new DescribeInstancesRequest()
            .withInstanceIds(ids);

    return ec2.describeInstances(request).getReservations();
}
```

If you can't specify resource IDs in your describe calls, we strongly recommend using pagination. The following is an example.

```
private List<Reservation> describeMyInstances(final Collection<Filter> filters){
    final DescribeInstancesRequest request = new DescribeInstancesRequest()
            .withFilters(filters)
            .withMaxResults(1000);

    List<Reservation> reservations = new ArrayList<>();
    String nextToken = null;
    do {
        request.setNextToken(nextToken);
        final DescribeInstancesResult response = ec2.describeInstances(request);
        reservations.addAll(response.getReservations());
        nextToken = response.getNextToken();
    } while (nextToken != null);

    return reservations;
}
```

If you need to retry a paginated call, use [exponential back-off with jitter](ec2-api-throttling.md#api-backoff).

## Common issues
<a name="pagination-common-issues"></a>

The following are examples of code that inadvertently makes unpaginated calls.

**Example issue: Passing an empty list of resource IDs**  
The following code uses a list of IDs. However, if the list is empty, the result is an unpaginated call.  

```
private List<Reservation> describeMyInstances(List<String> ids){
    final DescribeInstancesRequest request = new DescribeInstancesRequest()
            .withInstanceIds(ids);

    return ec2.describeInstances(request).getReservations();
}
```
To correct this issue, ensure that the list is not empty before making the describe call.  

```
private List<Reservation> describeMyInstances(List<String> ids){
    if (ids == null || ids.isEmpty()) {
        return ImmutableList.of();
        // OR
        return Lists.newArrayList();
        // OR
        return new ArrayList<>();
    }
        
    final DescribeInstancesRequest request = new DescribeInstancesRequest()
            .withInstanceIds(ids);

    return ec2.describeInstances(request).getReservations();
}
```

**Example issue: Not setting MaxResults**  
The following code checks and uses `nextToken`, but does not set `MaxResults`.  

```
private List<Reservation> describeMyInstances(final Collection<Filter> filters){
    final DescribeInstancesRequest request = new DescribeInstancesRequest()
            .withFilters(filters);

    List<Reservation> reservations = new ArrayList<>();
    String nextToken = null;
    do {
        request.setNextToken(nextToken);
        final DescribeInstancesResult response = ec2.describeInstances(request);
        reservations.addAll(response.getReservations());
        nextToken = response.getNextToken();
    } while (nextToken != null);

    return reservations;
}
```
To correct this issue, add `withMaxResults` as follows.  

```
private List<Reservation> describeMyInstances(final Collection<Filter> filters){
    final DescribeInstancesRequest request = new DescribeInstancesRequest()
            .withFilters(filters)
            .withMaxResults(1000);

    List<Reservation> reservations = new ArrayList<>();
    String nextToken = null;
    do {
        request.setNextToken(nextToken);
        final DescribeInstancesResult response = ec2.describeInstances(request);
        reservations.addAll(response.getReservations());
        nextToken = response.getNextToken();
    } while (nextToken != null);

    return reservations;
}
```