How do I avoid RequestLimitExceeded errors when programmatically launching multiple Amazon EC2 instances using PowerShell?

Last updated: 2020-09-24

When I try to launch multiple Amazon Elastic Compute Cloud (Amazon EC2) instances, I sometimes receive RequestLimitExceeded errors. How can I prevent receiving this error? 

Resolution

A RequestLimitExceeded error for Amazon EC2 APIs usually indicates request rate limiting or resource rate limiting API throttling. You can use a combination of retry logic and exponential backoff strategies to work around this issue.

Launching an Amazon EC2 instance is a mutating call, and is subject to both request rate and resource rate limiting. The script that you use to launch the instances must accommodate the refill rate of the token bucket.

Use one of these delayed invocation or retry strategies to avoid RequestLimitExceeded errors.

Note: AWS SDK for .NET has a built-in retry mechanism that is enabled by default. To customize the timeouts, see Retries and timeouts.

The following example includes a delayed invocation mechanism for your requests, which allows the request bucket to fill up:

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0

# Example Code to launch 50 EC2 instances of type 'm5a.large'.
try {    
  $params = @{
    ImageId = '<AMI_ID>'
    InstanceType = 'm5a.large'
    AssociatePublicIp = $false
    SubnetId = '<Subnet_ID>'
    MinCount = 10
    MaxCount = 10
     }
  for ($i=0;$i<=5;$i++){
    $instance = New-EC2Instance @params
    Start-Sleep 5000 #Sleep for 5 seconds to allow Request bucket to refill at the rate of 2 requests per second
    }
} catch {
    Write-Error "An Exception Occurred!"
}

The following example includes retry logic in the script:

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0

#Example Code to launch 50 EC2 instances of type 'm5a.large'.
$Stoploop = $false
[int] $Retrycount = "0"
do {
    try {
        $params = @{
            ImageId = '<AMI_ID>'
            InstanceType = 'm5a.large'
            AssociatePublicIp = $false
            SubnetId = '<Subnet_ID>'
            MinCount = 50
            MaxCount = 50
        }
    $instance = New-EC2Instance @params
    $Stoploop = $true
    } catch {
        if ($Retrycount -gt 3) {
            Write - Host "Could not complete request after 3 retries."
            $Stoploop = $true
        } else {
           Write-Host "Could not complete request retrying in 5 seconds."
           Start-Sleep -Seconds 25 
           #25 seconds of sleep allows for 50 request tokens to be refilled at the rate of 2/sec
           $Retrycount = $Retrycount + 1
           }
        }
    } While($Stoploop -eq $false)

Did this article help?


Do you need billing or technical support?