CloudBudgetMasterCloudBudgetMaster

← All articles

Strategy

Advanced Cloud Cost Optimization Strategy Teams Overlook

August 17, 2026·8 min read·CloudBudgetMaster

The tactic you’re missing: Scheduled scaling + Spot mix + automated rightsizing

Most engineering and platform teams focus on obvious levers—reserved instances, idle volumes, or unused IPs. The next‑level tactic that consistently delivers double‑digit savings is a combined schedule‑driven start/stop policy, Spot‑instance blending, and continuous rightsizing. By treating idle compute as a predictable, time‑bound workload and letting the cloud automatically replace it with the cheapest capacity, you turn waste into a cost‑neutral or even revenue‑positive resource.

The approach works for EC2, RDS, Elasticache, and even container workloads in ECS/EKS. It requires three core pieces: 1. Accurate usage profiling – know when a resource is truly idle. 2. Scheduled actions – start only when needed, stop otherwise. 3. Spot‑fallback automation – run on Spot when possible, fall back to On‑Demand for SLA protection.

When these pieces are orchestrated with AWS native services (CloudWatch Events, Lambda, EC2 Fleet, and Compute Optimizer), the result is a self‑healing cost engine that runs 24/7 without manual intervention.


1. Profile usage patterns to find predictable idle windows

Before you can schedule anything you need data. AWS provides several sources:

Step‑by‑step profiling

  1. Open the CloudWatch consoleMetricsEC2Per‑Instance Metrics.
  2. Create a metric math expression that averages CPUUtilization over a 7‑day window: SELECT AVG([CPUUtilization]) FROM "AWS/EC2" WHERE InstanceId = 'i-0abcd1234efgh5678' PERIOD 86400
  3. Export the data to CSV via the Actions → Download CSV button.
  4. Load the CSV into a spreadsheet and look for daily patterns (e.g., 0‑5 % CPU from 22:00‑06:00 UTC).
  5. Repeat for RDS (CPUUtilization, DatabaseConnections) and Elasticache (EngineCPUUtilization).

If you see a consistent low‑usage window of > 6 hours, that resource is a candidate for scheduled stop/start.


2. Implement scheduled start/stop with CloudWatch Events and Lambda

AWS provides a serverless way to start and stop instances on a cron schedule.

Create the IAM role

aws iam create-role \
  --role-name ScheduleEC2Role \
  --assume-role-policy-document file://trust-policy.json

trust-policy.json should allow lambda.amazonaws.com to assume the role. Attach the managed policy AmazonEC2FullAccess (or a scoped custom policy with ec2:StartInstances and ec2:StopInstances).

Deploy the Lambda function

aws lambda create-function \
  --function-name ec2-schedule-handler \
  --runtime python3.11 \
  --role arn:aws:iam::123456789012:role/ScheduleEC2Role \
  --handler handler.lambda_handler \
  --zip-file fileb://ec2-schedule.zip

The handler code (Python) looks like:

import boto3, os

ec2 = boto3.client('ec2')

def lambda_handler(event, context):
    action = event['detail']['action']  # "start" or "stop"
    ids = os.getenv('INSTANCE_IDS').split(',')
    if action == 'start':
        ec2.start_instances(InstanceIds=ids)
    else:
        ec2.stop_instances(InstanceIds=ids)

Set the environment variable INSTANCE_IDS to a comma‑separated list of target instance IDs.

Schedule the events

aws events put-rule \
  --name "StartInstancesNight" \
  --schedule-expression "cron(0 6 * * ? *)"   # 06:00 UTC daily
aws events put-targets \
  --rule "StartInstancesNight" \
  --targets "Id"="1","Arn"="arn:aws:lambda:us-east-1:123456789012:function:ec2-schedule-handler","Input"='{"detail": {"action": "start"}}'

aws events put-rule \
  --name "StopInstancesNight" \
  --schedule-expression "cron(0 22 * * ? *)"   # 22:00 UTC daily
aws events put-targets \
  --rule "StopInstancesNight" \
  --targets "Id"="1","Arn"="arn:aws:lambda:us-east-1:123456789012:function:ec2-schedule-handler","Input"='{"detail": {"action": "stop"}}'

Repeat the same pattern for RDS (rds:start-db-instance, rds:stop-db-instance) and Elasticache (elasticache:start-cache-cluster, elasticache:stop-cache-cluster).


3. Blend Spot Instances with On‑Demand fallback using EC2 Fleet

Scheduled start/stop removes waste during off‑hours, but you can still overpay during on‑hours if you rely solely on On‑Demand. EC2 Fleet lets you request a mix of Spot and On‑Demand capacity with a single API call.

Define the fleet request JSON

{
  "TargetCapacitySpecification": {
    "TotalTargetCapacity": 4,
    "OnDemandTargetCapacity": 1,
    "SpotTargetCapacity": 3,
    "DefaultTargetCapacityType": "spot"
  },
  "LaunchTemplateConfigs": [{
    "LaunchTemplateSpecification": {
      "LaunchTemplateId": "lt-0abcd1234efgh5678",
      "Version": "$Latest"
    },
    "Overrides": [
      {"InstanceType": "c5.large"},
      {"InstanceType": "c5a.large"}
    ]
  }],
  "SpotOptions": {
    "AllocationStrategy": "capacity-optimized",
    "InstanceInterruptionBehavior": "stop"
  }
}

Save as fleet-request.json.

Submit the fleet

aws ec2 create-fleet --cli-input-json file://fleet-request.json

The fleet will launch up to three Spot instances. If Spot capacity is unavailable, the request automatically falls back to the single On‑Demand instance, guaranteeing baseline performance.

Automate fleet updates

Use a CloudWatch Event that triggers a Lambda function after each scheduled start. The Lambda can call create-fleet with the latest price‑limit (SpotMaxPrice) derived from aws pricing get-products. This keeps Spot costs at or below your budgeted ceiling.


4. Continuous rightsizing with Compute Optimizer recommendations

Even after you schedule and blend, instances can drift from the optimal size. Compute Optimizer provides a recommendation score (0‑100) and suggested instance types.

Pull recommendations via CLI

aws compute-optimizer get-recommendations \
  --service-name EC2 \
  --account-ids 123456789012 \
  --max-results 100 > ec2-recs.json

Parse ec2-recs.json for entries where recommendationOptions[0].performanceRisk > 0.2 and currentInstanceType differs from recommendedInstanceType.

Apply rightsizing automatically

Create a Lambda that reads the JSON, checks CloudWatch metrics to confirm low utilization, and then calls modify-instance-attribute:

aws ec2 modify-instance-attribute \
  --instance-id i-0abcd1234efgh5678 \
  --instance-type "{\"Value\": \"c5.large\"}"

Schedule this Lambda to run weekly so the fleet stays lean.


5. Tag‑driven cost allocation for ongoing visibility

Tagging is the glue that lets you track the financial impact of the above tactics.

Tag key Recommended value format Why it matters
CostCenter team‑frontend, team‑ml Enables Cost Explorer grouping
Env prod, stage, dev Filters out non‑production waste
Schedule night‑stop, always‑on Drives automation rules
SpotEnabled true / false Quick audit of Spot‑eligible resources

Apply tags via the console or CLI:

aws ec2 create-tags --resources i-0abcd1234efgh5678 \
  --tags Key=CostCenter,Value=team-frontend Key=Schedule,Value=night-stop

Then enable Cost Allocation Tags in the Billing console so they appear in Cost Explorer reports.


6. Measure the dollar impact with the free AWS waste finder

Before you invest time, run CloudBudgetMaster’s free AWS waste finder to see a baseline of idle resources and their estimated monthly cost. The tool scans your account in read‑only mode and produces a CSV with: - Resource ARN - Current monthly spend estimate - Suggested action (stop/start, Spot, rightsizing)

Visit /tools/aws-waste-finder to launch the scan. Use the output as a checklist for the steps above.


7. Comparison of common optimization approaches

Approach Setup effort Ongoing maintenance Typical savings Risk level
Manual shutdown scripts Low High (needs updates) 5‑10 % Low (human error)
Scheduled start/stop (Lambda) Medium Low (once deployed) 15‑25 % Low (controlled windows)
Spot‑mix with EC2 Fleet Medium Medium (price monitoring) 30‑45 % Medium (interruption handling)
Continuous rightsizing (Compute Optimizer) High Low (weekly Lambda) 20‑35 % Low (AWS‑recommended)
Full strategy (schedule + Spot + rightsizing) High Low 40‑60 % Medium (requires proper fallback)

The table shows why the full strategy—the subject of this post—delivers the highest ROI despite a larger initial investment.


Frequently asked questions

How do I know if my workload can tolerate Spot interruptions?

Spot instances can be terminated with a two‑minute warning. Use them for stateless, batch, or horizontally scalable services. For stateful workloads, configure the InstanceInterruptionBehavior as stop and rely on EBS snapshots for data safety.

Can I apply the schedule‑stop/start pattern to RDS Multi‑AZ deployments?

Yes, but only for read replicas or dev/test instances. Primary production Multi‑AZ instances must remain online for HA. Use the rds:stop-db-instance permission on the replica and re‑enable it during the start window.

Does using Compute Optimizer affect my existing Reserved Instances or Savings Plans?

Compute Optimizer recommendations are agnostic to existing contracts. It will suggest a smaller instance type that still satisfies your Reserved Instance coverage, allowing you to keep the reservation while reducing on‑demand usage.

Will the free AWS waste finder impact my production environment?

No. The scanner uses read‑only API calls; it never modifies resources. It only reads configuration and usage metrics to calculate potential waste.


Key takeaways


CloudBudgetMaster automates this workflow. Today it scans AWS accounts in read‑only mode, identifies idle and under‑utilized resources, and reports the dollar impact of each waste source. Support for GCP, Azure, and Snowflake is coming soon. To try the automation, create a free account and let the platform handle the heavy lifting.

Stop guessing where your AWS bill comes from

Upload a CSV, no signup. CloudBudgetMaster finds idle, unused, and overspending AWS resources automatically. GCP and Azure coming soon.

Run a free check