How to Reduce AWS Costs with FinOps as a Solo DevOps Engineer (2026)

Published · Updated

Every FinOps guide assumes you have a cost analyst, a Cloud Center of Excellence, and a #finops-weekly Slack channel with three people arguing about Savings Plans coverage. Most solo DevOps engineers have none of that. You are the only person touching the AWS account, and cost review happens somewhere between an incident at 2 AM and a feature you promised on Friday.

You do not need a maturity model. You need automated guardrails that keep working when you forget to open the billing console for three weeks.

This is the lean version: what one engineer can realistically build, automate, and maintain in 2026 — with real numbers, real commands, and the two or three line items that actually move your invoice.

Why solo engineers get blindsided hardest

On a team, cost waste gets caught by accident. Someone reviews your pull request and asks why you picked an m5.4xlarge. Finance queries a daily spike. A platform engineer notices the dev cluster never scales to zero.

Solo, none of those safety nets exist. You spin up an m5.4xlarge for a weekend data migration, the migration slips, you move on to the next fire, and the instance runs for 21 days before the invoice reminds you it exists. At roughly $0.77/hour in Mumbai, that “temporary” box quietly billed you around $390 while you weren’t looking.

The fix is not more discipline or a better memory. The fix is small automated defenses that fire without you. Discipline fails under load; a billing alarm does not.

Quick wins: one-hour, set-and-forget defenses

These four steps take about an hour total and target the most common sources of silent waste. Do them once, and they keep paying off every month.

1. Enable AWS Cost Anomaly Detection (free)

Cost Anomaly Detection uses machine learning to learn your normal spend pattern and flags statistically unusual spikes. It is completely free, and it is the single highest-leverage thing a solo engineer can turn on.

  • Go to Billing and Cost Management → Cost Anomaly Detection.
  • Create a monitor of type AWS services so every service is watched.
  • Attach an alert subscription. Route it to an SNS topic that fans out to Slack (via a Lambda or a chat webhook) or to SMS — anywhere you will actually see it. A dead inbox rule defeats the purpose.
  • Set the alert threshold low. For a solo account, get pinged on any anomaly above $50 or a 20% variance. You would rather get a false positive than miss a runaway autoscaling group.

The reason this matters: anomaly detection catches the category of failure you cannot predict — a recursive Lambda, a log group with no retention, an S3 bucket someone is scraping. Budgets catch known thresholds; anomaly detection catches the unknown-unknowns.

2. Aggressive S3 lifecycle rules

Build artifacts, container layers, CloudTrail logs, VPC Flow Logs, database dumps, and old deploy bundles pile up silently. S3 Standard is $0.023/GB/month in most regions — cheap per GB, expensive when a forgotten bucket holds two terabytes of logs from a pipeline you deleted last year.

  • Apply a lifecycle rule that transitions objects to S3 Intelligent-Tiering after 30 days if access patterns are unpredictable. Intelligent-Tiering moves objects between tiers automatically and has no retrieval fees.
  • For write-once, read-rarely data (log archives, backups), transition to Glacier Instant Retrieval ($0.004/GB/month) or Glacier Deep Archive ($0.00099/GB/month) for true cold storage.
  • For pure log buckets, add an expiration rule — delete after 90 days unless compliance requires longer. Logs you will never read are not an asset; they are a recurring charge.
{
  "Rules": [{
    "ID": "archive-then-expire-logs",
    "Filter": { "Prefix": "logs/" },
    "Status": "Enabled",
    "Transitions": [
      { "Days": 30, "StorageClass": "GLACIER_IR" }
    ],
    "Expiration": { "Days": 90 }
  }]
}

3. Clean unused EBS volumes and idle Elastic IPs

Two of the most common orphaned resources on any AWS account:

  • Unattached EBS volumes. When you terminate an EC2 instance without checking “delete on termination,” the root or data volume survives — and keeps billing at $0.08/GB/month for gp3. A handful of forgotten 100 GB volumes is $8–$40/month for nothing.
  • Idle Elastic IPs. An Elastic IP is free only while attached to a running instance. Once the instance stops or terminates, that same IP starts costing about $0.005/hour (~$3.6/month each). Ten stale EIPs is a rounding error until it is $36/month.

Find orphaned volumes:

aws ec2 describe-volumes \
  --filters Name=status,Values=available \
  --query "Volumes[*].{ID:VolumeId,Size:Size,Type:VolumeType,AZ:AvailabilityZone}" \
  --output table

Find unassociated Elastic IPs:

aws ec2 describe-addresses \
  --query "Addresses[?AssociationId==null].{IP:PublicIp,AllocId:AllocationId}" \
  --output table

Snapshot anything you might need, then delete the orphaned volumes and release the unassociated EIPs. This is the cleanup that pays for itself in the first month.

4. Default every volume to gp3

Older instances still run on gp2 root volumes. gp3 is the newer general-purpose SSD and it is about 20% cheaper per GB ($0.08/GB/month vs $0.10/GB/month for gp2) while decoupling IOPS and throughput from volume size. On gp2 you had to over-provision size just to get IOPS; on gp3 you get a 3,000 IOPS and 125 MB/s baseline free at any size.

Migrate live, with zero downtime, no snapshot-restore dance:

aws ec2 modify-volume --volume-id vol-0abc123 --volume-type gp3

The volume enters an optimizing state and stays fully available throughout. Sweep every gp2 volume in the account — it is free money.

The trap: optimizing compute before data transfer

Here is the mistake almost every solo engineer makes first. You see a big bill, so you downscale EC2, move a service to Lambda, and feel productive. But data transfer frequently outgrows the compute savings, and it hides in billing lines that never say the word “transfer” plainly.

The NAT Gateway tax

Workloads in private subnets reach the internet through a NAT Gateway. You pay two ways: an hourly charge just for the gateway to exist ($0.056/hour, roughly $40/month in ap-south-1) plus a per-GB data processing charge ($0.056/GB). Pull large objects from S3 through a public endpoint and you get billed twice — once for S3 data transfer and again for NAT processing on the same bytes.

Fix: add a free S3 Gateway Endpoint and a free DynamoDB Gateway Endpoint to your VPC. Traffic to those services then stays on the AWS private network and skips the NAT Gateway entirely — no data processing charge.

aws ec2 create-vpc-endpoint \
  --vpc-id vpc-0abc123 \
  --service-name com.amazonaws.ap-south-1.s3 \
  --route-table-ids rtb-0abc123

For a workload that pulls container images, reads from S3, or hits DynamoDB constantly, this one change can shave more off the bill than a full round of instance downsizing.

Cross-AZ data transfer

Multi-AZ is the correct architecture for failover — but AWS charges for data crossing Availability Zone boundaries (~$0.01/GB each direction, so ~$0.02/GB round trip). A chatty app that talks to a database placed randomly in a different AZ leaks money on every single request, and it never shows up as a scary line item — it is smeared across your networking charges.

Fix: keep high-throughput internal paths (app ↔ cache, app ↔ database) in the same AZ where you can. Use multi-AZ for redundancy and failover, not for constant cross-AZ chatter on your hot path.

Right-sizing without guessing

Once the structural waste is gone, right-sizing is where you tune. Do not guess — AWS gives you the data for free.

  • AWS Compute Optimizer (free) analyzes CloudWatch metrics and tells you which instances are over- or under-provisioned, with a specific recommended type. It is conservative and safe to trust as a starting point.
  • Watch memory and network, not just CPU. Compute Optimizer’s default view leans on CPU. An app can sit at 8% CPU and still be pinned on memory or network — downsize on CPU alone and you will page yourself at midnight. Install the CloudWatch Agent to get real memory metrics before you cut.
  • Consider Graviton. AWS’s ARM-based Graviton instances (the g family — t4g, m7g, c7g, r7g) deliver roughly 20% better price-performance than the equivalent x86 instance. If your stack is Go, Node, Python, Java, or a mainstream container base image, the port is usually just a base-image change and a rebuild. Test in staging, then migrate.

Free tooling that actually matters

You do not need a FinOps SaaS subscription as a team of one. These four cover the ground:

ToolCostWhy it matters
AWS BudgetsFree (first 2 budgets)Alert at 80% and 100% of forecasted spend, not just actual — forecast warns you before the month closes
AWS Compute OptimizerFreeRightsizing recommendations from real CloudWatch CPU/memory/network data
Cost Anomaly DetectionFreeML-based spike detection for the failures you cannot predict
InfracostFree / open sourceTerraform cost delta in the pull request, before terraform apply

Infracost shift-left: catching a $300/month mistake in a pull-request comment beats catching it on next month’s invoice. Wire it into CI and it comments the monthly cost delta on every Terraform change.

# .github/workflows/infracost.yml (excerpt)
- name: Infracost breakdown
  run: |
    infracost breakdown --path=. \
      --format=json --out-file=/tmp/infracost.json
- name: Post PR comment
  run: infracost comment github --path=/tmp/infracost.json \
      --repo=$GITHUB_REPOSITORY --pull-request=${{ github.event.pull_request.number }} \
      --github-token=${{ secrets.GITHUB_TOKEN }} --behavior=update

For a deeper playbook — reserved capacity math, a full tagging strategy, and the monthly review I actually run — see How I Built a System to Cut AWS Bills by 20–40%.

The weekly 15-minute FinOps ritual

Do not make cost work continuous — that is how it gets skipped entirely. Box it into one recurring Friday slot and protect it like a meeting.

[Friday 10:00]
  ├── Cost Explorer — last 7 days, grouped by Service
  │     └── Anything up more than ~20% week over week?
  ├── Compute Optimizer — any new "Over-provisioned" flags?
  ├── Untagged resources created this week (tag or delete)
  └── Budgets — forecasted vs actual for month-end
[Friday 10:15] → back to shipping features

The math on this is simple. Catching a wrong instance size on day 4 costs you pocket change. Catching the same mistake on day 30 — after it has compounded across a full billing cycle — is what blows the budget. Fifteen minutes a week is the cheapest insurance in your stack.

Monthly cost review template

Once a month, block 30 minutes for a slightly deeper pass. Copy this into your runbook repo so it is a checklist, not a memory test:

# AWS Cost Review: [Month, Year]

## Topline
- Actual spend:      $____
- Budget target:     $____
- Variance vs last month: [+/-] ____%

## Top 3 cost drivers
1. [Service] — $____  (expected? Y/N)
2. [Service] — $____  (expected? Y/N)
3. [Service] — $____  (expected? Y/N)

## Structural checks
- [ ] Compute Optimizer recommendations reviewed/applied?
- [ ] Orphan EBS volumes deleted?
- [ ] Unassociated Elastic IPs released?
- [ ] Any new NAT Gateway data-processing spikes?
- [ ] Untagged resources tagged or removed?

## One fix this month
- Focus: ________________________________

Pick exactly one optimization to ship each month — a small Compute Savings Plan on your steady baseline, an idle RDS cluster to stop, a high-egress service to refactor behind a VPC endpoint. One real change beats five half-finished ones.

A realistic first-month order of operations

If you are staring at a bill right now and want a concrete sequence:

  1. Hour 1 — turn on Cost Anomaly Detection + two Budgets (80% and 100% forecast). Now you have alarms.
  2. Hour 2 — run the orphan-volume and idle-EIP scans; delete/release. Add S3 lifecycle rules to your biggest buckets.
  3. Week 1 — add S3 and DynamoDB Gateway Endpoints; sweep gp2 → gp3 across the account.
  4. Week 2 — read Compute Optimizer, install the CloudWatch Agent for memory, and right-size the top 3 offenders in staging first.
  5. Ongoing — Infracost in CI, the 15-minute Friday ritual, one fix per month.

Bottom line

Solo FinOps is not about perfect optimization or a spreadsheet with 40 tabs. It is about eliminating structural waste and killing invoice surprises with about one hour of guardrails, 15 minutes a week, and cost deltas surfaced in your Terraform pull requests. Get the NAT Gateway, orphaned volumes, S3 lifecycle, and gp3 basics right, and you have captured most of the savings a whole FinOps team would find — without hiring one.

When you are ready for a role that owns this kind of work, browse DevOps and cloud roles on FzlOps — many listings explicitly mention AWS, Terraform, and cost ownership.