Start and Stop Your EC2 Instances: The Ultimate Guide

AWS doesn’t charge users for a stopped instance.  When a stopped instance is started, you are automatically charged for a minute’s worth of usage. After one minute, AWS charges you by the second. So if you run an instance for 30 or 40 seconds, you are still charged for one minute but if you run it for 2 minutes and 15 seconds, you are charged for that exact time.

You can get a lot of benefits from deciding to automatically stop and start your EC2 instances.

  • Choose what period you want instances to run
  • Reduce costs
  • Dictate which instances will be worked on by employees and when

You can make changes to the volume of the instance when it is in a stopped state. You have the potential to treat the root volume of your instance the same as any other volume. You can detach it and add it to another machine, modify it, etc.

The difference between a stopped instance and a terminated instance is that once you stop it, you can still be charged for storage but if you terminate it, you are freed of all charges.

You can modify the following attributes of an instance only when it is stopped:

  • Instance type
  • RAM
  • Kernel
  • User data

Modifying these attributes while the instance is running gives the IncorrectInstanceState error.

What happens when you stop an Instance?

  • The instance will perform a shutdown and stop running. 
  • Amazon EBS volumes attached to the instance remain and their data persists.
  • If there is data stored in the RAM of the host computer or the instance storage volumes, they will be gone.
  • The private IPv4 and IPv6 addresses are retained when an instance is restarted.
  • Elastic IP addresses are also retained. AWS charges you for the Elastic IP addresses of an instance. This doesn’t apply for EC2-Classic, Elastic IP addresses are removed when they are stopped.

How to Stop and Start your EC2 Instance

The AWS Instance Scheduler Method

How to set up the AWS Instance Scheduler

The Instance Scheduler will give you the option to shut down, start or restart the specifically tagged instances according to the time you deem appropriate.

To set up the Instance Scheduler, we will first install the stack by provisioning all the resources onto AWS CloudFormation.

  • Open AWS Cloudformation. You can choose whichever region as Cloudformation allows cross-region configuration.
  • Specify the template
  • Provide a name for the stack
  •  Enter the tag Key that will be used on Instances that you want to schedule. The Value will be the name of the Schedule set in the DynamoDB table.
  • Enter the regions of the machines
  • Set the timezone
  • Set an adequate time for the SchedulerFrequency. I recommend 30 mins. 

Leave all the other options as it is and proceed.

Wait for the resources to be provisioned. You will see a success message when it is done.

With this process, you will have three resources set up.

  • AWS Lambda functions
  • DynamoDB tables
  • Cloudwatch Events

Setting up the shutdown tag

Now we’ll define the shutdown period. You can make the necessary configurations on DynamoDB.

  • Open DynamoDB
  • Open the table named ConfigTable
  • Delete the rows named period and schedule and leave the config row as is.

-- CODE language-js line-numbers -- { "description": { "S": "Shut-down period. Daily (end of the day)." }, "endtime": { "S": "20:00" }, "starttime": { "S": "9:00" }, "name": { "S": "office-hours" }, "type": { "S": "period" }, "weekdays": { "SS": [ "Mon-sun" ] } }

This defines the period to match the time we need the instances to shutdown. 

-- CODE language-js line-numbers -- { "description": { "S": "Office hours in Canada (AST)" }, "enforced": { "S": "false" }, "name": { "S": "ca-autostop" }, "periods": { "SS": [ "office-hours" ] }, "retain_running": { "S": "false" }, "stop_new_instances": { "S": "true" }, "timezone": { "S": "Canada/Atlantic" }, "type": { "S": "schedule" } }

This defines the schedule which will be used to match the instances according to tags. The tag used here is “ca-autostop”. The Schedule also contains information about the timezones so instances from other regions operate under the same scheduling hours. 

Now, any instance with the tag you have defined will be manipulated by the Instance Scheduler.

Downsides of AWS Instance Scheduler
  • You have to provision multiple resources to set up an instance scheduler
  • The management overhead for all the resources will make troubleshooting complicated
  • You have to pay for each of the service you make use of
  • You can only make configurations by updating the CloudFormation stack


AWS Tools for Windows Powershell

You can schedule your Instances through a PowerShell class as well. You will need to use the AWS Tools for Windows Powershell. 

You can install the AWS Power Shell module from the PowerShell Gallery.

-- CODE language-js line-numbers -- Install-Module -Name AWSPowerShell

Create a class named AWSInstance. This class will allow you to start and stop your machines.

Declare the class

-- CODE language-js line-numbers -- Class AwsInstance {}

Next, we define all the properties we need to manipulate the instance.

-- CODE language-js line-numbers -- [String] $TagName [String] $InstanceId [String] $Status  Hidden [Object] $EC2Instance

The hidden property is used to identify the right instance. The value that is passed to this class finds the Instance Tag or the Instance ID.

-- CODE language-js line-numbers -- AwsInstance([String]$name) { if ($name -match '^i-[a-f0-9]+$') { $this.InstanceId = $name $this.EC2Instance = $this.getInstanceFromInstanceId($name) $this.TagName = ($this.EC2Instance.RunningInstance.Tag).Where({ $_.key -eq 'Name' }).Value } else { $this.EC2Instance = $this.getInstanceFromTagName($name) $this.TagName = $name $this.InstanceId = $this.EC2Instance.RunningInstance.InstanceId } $this.GetStatus()

The AWSinstance constructor takes either the instanceid or the tagname and compares it with the machines using regexp in an if condition.

-- CODE language-js line-numbers -- [Amazon.EC2.Model.Reservation] getInstanceFromTagName([String]$name) { $Filter1 = [Amazon.EC2.Model.Filter]::new("key", ('Name', 'name')) $Filter2 = [Amazon.EC2.Model.Filter]::new('value', $name) $ResourceId = (Get-EC2Tag -Filter @($filter1, $filter2)).Where({$_.ResourceType -eq 'instance'}) return Get-EC2Instance -InstanceId $ResourceId.ResourceId } [Amazon.EC2.Model.Reservation] getInstanceFromInstanceId([String]$name) { return Get-EC2Instance -InstanceId $name } [Void] Start() { try { $this.EC2Instance | Start-EC2Instance $this.GetStatus() } catch { $this.Status = $_.Exception.Message } } [Void] Restart() { try { $this.EC2Instance | Restart-EC2Instance $this.GetStatus() } catch { $this.Status = $_.Exception.Message } } [Void] Stop() { try { $this.EC2Instance | Stop-EC2Instance $this.GetStatus() } catch { $this.Status = $_.Exception.Message } } [Void] GetStatus() { try { $this.Status = ($this.EC2Instance | Get-EC2InstanceStatus).InstanceState.Name.Value } catch { $this.Status = $_.Exception.Message } } Hidden [Void] getInstance() { $this.EC2Instance = Get-EC2Instance -InstanceId $this.InstanceId } static [String] Start([String]$name) { $instance = [AwsInstance]::new($name) $instance.Start() return "Status: " + $instance.Status } static [String] Stop([String]$name) { $instance = [AwsInstance]::new($name) $instance.Stop() return "Status: " + $(if (-not $instance.Status) { "Stopped" }) } static [String] Restart([String]$name) { $instance = [AwsInstance]::new($name) $instance.Restart() return "Status: " + $instance.Status } static [AwsInstance] GetStatus([String]$name) { $instance = [AwsInstance]::new($name) $instance.GetStatus() return $instance } } Each static method creates an instance of the class: $instance = [AwsInstance]::new($name)

Each static method creates an instance of the class:

-- CODE language-js line-numbers -- $instance = [AwsInstance]::new($name)

Once the static method has created an instance of the machine, it can call methods to change the running state. 

You can also get the status of a machine using this command:

-- CODE language-js line-numbers -- [AwsInstance]::GetStatus('Server2016Test')

By changing the status method as shown below, you can start, stop or restart the instances.

-- CODE language-js line-numbers -- AwsInstance]::Start(‘Server2016Test’) [AwsInstance]::Stop(‘Server2016Test’) [AwsInstance]::Restart(‘Server2016Test’)


This is an open-source tool run on Terraform. You can find it here.

To run this you need to install kitchen-terraform and awspec.

gem install bundler 

bundle install

This will install the dependencies.

Launch the Kitchen tests.

-- CODE language-js line-numbers -- # List all tests with kitchen kitchen list # Build, and tests terraform module kitchen test lambda-scheduler-aws # for development, create environment kitchen converge lambda-scheduler-aws # Apply awspec tests kitchen verify lambda-scheduler-aws

Start and Stop EC2 Instance

-- CODE language-js line-numbers -- module "stop_ec2_instance" { source = "diodonfrost/lambda-scheduler-stop-start/aws" name = "ec2_stop" cloudwatch_schedule_expression = "cron(0 00 ? * FRI *)" schedule_action = "stop" ec2_schedule = "true" rds_schedule = "false" autoscaling_schedule = "false" resources_tag = { key = "tostop" value = "true" } }

Change the values according to your choice to initiate the schedule.


The Totalcloud tool allows you to perform these operations in an intuitive and user-friendly platform. For this, you will need to log in to the platform here.

  • Once you are on the platform, choose Schedules.
  • Click Add Schedules
  • Choose EC2 scheduling template
  • Choose your scheduling period
  • Filter out the instances based on tagname or instanceid
  • You can also choose to schedule based on activity or other metrics, this can be determined in the last field named, ‘Smart Schedule’.
  • Save and Deploy the schedule.

The Next step

Utilise the right start and stop method with whatever tools you deem most suitable. Once you are confident in your scheduling method, the next step is to make sure you are following the best scheduling practices to spend the least amount of money on your resources. Hope you can cut down your expenses and manage your instances with the techniques provided in this guide.

Start and Stop Your EC2 Instances: The Ultimate Guide

Smart Scheduling at your fingertips

Go from simple to smart, real-time AWS resource scheduling to save cost and increase team productivity.

Learn More
More Posts

You Might Also Like

Cloud Computing
How To Migrate To Azure Faster?
Migrating from on premise data centers to a cloud provider is always considered a difficult endeavor. From the cost, to the planning and resource allocation, plenty of preliminary work is gone to setting up a cloud infrastructure. Which is why, Microsoft Azure’s new program stands to benefit many organizations still on the fence about migrating to the cloud.
July 21, 2021
Cloud Computing
Everything You Need To Know About Kubernetes Scheduler
When creating a Kubernetes cluster, scheduling the pod to an available node is an important component of the process. This component works under specific rules and technicalities that I’d like to explore in this article...
September 23, 2020
Cloud Computing
20 Cloud Influencers You Should Be Following in 2020
It’s important to follow the right individuals so that you remain on the loop and always find yourself learning things that you were unaware of. These thought leaders and influencers can only be the avenues by which you meet other interesting technologists.
September 23, 2020
Cloud Automation
New In: No-code cloud management workflows for Azure, VMware & Private Cloud (in addition to AWS)
At TotalCloud, we’ve been enabling workflow-based cloud management for AWS to make it intuitive, accelerated, and no-code. Instead of programming cloud management use cases or depending on siloed solutions, we built out a platform that gives you building blocks to assemble any cloud management solution. 
September 4, 2020
Cloud Computing
List of Essential Kubernetes Tools
Kubernetes is a Container-as-a-Service with tons of unique tools to choose from. External tools play a role in integrating with different systems or maintaining control over the clusters you deploy. Manual health checks and troubleshooting is not ideal to keep a system in full health.This list of tools will provide ample support to your containers and have enough configuration to leave management flexible...
August 12, 2020
AWS Use Case Files
TotalCloud Inventory Actions: Giving a new meaning to Cloud Inventory
Learn how the TotalCloud Inventory Dashboard can become equivalent to your cloud provider’s SDK. Carry out any action on any discovered resource with Inventory Actions.
July 30, 2020