
Developer guides for DigitalOcean cost optimization and rightsizing: practical guide for developers
Is the monthly DigitalOcean bill growing without clear value? Are Droplets, node pools or volumes overprovisioned and underutilized? This guide provides developer-focused, step-by-step procedures, scripts, queries and automation to reduce spend with measurable rightsizing on DigitalOcean. It centers exclusively on Developer guides for DigitalOcean cost optimization and rightsizing and delivers CLI/API examples, Terraform patterns, Prometheus/Grafana queries, CI/CD playbooks and a small simulation to estimate savings.
Key takeaways: what to know in 1 minute ✅
- ✅ Start with data: collect 14–30 days of CPU, memory, disk I/O and network metrics per Droplet or node pool using doctl metrics or Prometheus to identify overprovisioning.
- ✅ Automate rightsizing: use the DigitalOcean API and doctl scripts or Terraform to create an automated rightsizing pipeline that suggests or applies changes during maintenance windows.
- ✅ Combine vertical and horizontal scaling: use vertical downsizing for stable low-load services and horizontal scaling for bursty workloads to control baseline cost.
- ✅ Protect production: tag critical production resources, set alerts and require approvals before resizing or destroying nodes.
- ✅ Measure ROI: run an A/B rightsizing pilot for 7–14 days to quantify % savings, then scale the playbook across projects.
Why developer-focused rightsizing matters 💡
Developers deploy and operate infrastructure. Developer-focused rightsizing closes the gap between cloud billing and code-level decisions. It ties observable runtime metrics to concrete actions (doctl resize, API instance update, Terraform plan/apply). This approach reduces bill surprises and keeps velocity.
Data collection: gather the right metrics first 🛠️
Accurate rightsizing starts with metrics. Collect at least 14 days of time-series for:
- 💰 CPU usage (user + system) average and 95th percentile
- ⚖️ Memory used vs allocated (RSS, cache excluded if possible)
- 🔁 Disk I/O and latency (read/write per second, IOPS)
- 📶 Network egress/ingress (peak and average)
- 🧾 Process-level metrics when possible (container CPU/memory limits)
Recommended sources:
Sample Prometheus queries to find overprovisioning 📊
- CPU 95th percentile per node (last 14 days):
avg_over_time(instance:node_cpu:rate5m[14d])
- Memory usage ratio: (used/total) 95th percentile
max_over_time((node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes[14d])
histogram_quantile(0.95, sum(rate(node_disk_io_time_seconds_bucket[5m])) by (le, instance))
Use these queries in Grafana panels to create a rightsizing dashboard.
Analysis and classification: how to decide what to resize ⚖️
Classify workloads into three groups:
- 💡 Stable low-load: average CPU < 20% and memory < 50%, candidate for vertical downsizing.
- ⚡ Bursty: low average but high peaks (p95 CPU > 60%), candidate for horizontal scaling and autoscaling policies.
- 🛡️ Critical: stateful or latency-sensitive services, require staged resizing with rollback plan.
Create a scoring function for each Droplet/node pool: weighted score = 0.5cpu_util + 0.3mem_util + 0.2*iops_latency_rank. Sort ascending; low-score items are best candidates for downsizing.
Automation reduces manual work and enforces governance. The pipeline below balances discovery, staging, approval and execution.
- Discover: run collector scripts to export metrics per resource.
- Evaluate: run rules to generate resize suggestions (size slug, expected savings, risk level).
- Stage: create Terraform plans or snapshot + test Droplet in staging.
- Approve: send an approval ticket to FinOps/owner for production changes.
- Execute: apply changes during maintenance window and monitor for regressions.
Sample doctl CLI discovery script (bash) 🛠️
> requires doctl configured with DO_TOKEN
PROJECT=$1
OUT=metrics_${PROJECT}_$(date +%F).json
echo "Collecting droplets for project $PROJECT"
DOCTL_FORMAT="json"
> list droplets with tags
doctl compute droplet list --tag-name "$PROJECT" --no-header --output $DOCTL_FORMAT > droplets.json
> iterate and pull metrics (requires DigitalOcean monitoring enabled per droplet)
while read -r DROPLET; do
ID=$(echo $DROPLET | jq -r '.[0].id')
NAME=$(echo $DROPLET | jq -r '.[0].name')
echo "Fetching metrics for $NAME ($ID)"
doctl compute droplet retrieve-metrics $ID --period 14d --format cpu,mem,net,block > metrics_$ID.json
done < <(jq -c '.[]' droplets.json)
> summarize
jq -s '{project: "$PROJECT", date: "'"$(date +%F)"'", droplets: .}' metrics_*.json > $OUT
echo "Saved to $OUT"
This script demonstrates collecting DigitalOcean metrics via doctl. For production use, handle pagination, rate limits and authentication securely.
Use Terraform to represent Droplets and DOKS node pools. Implement rightsizing as follows:
- Create a module that defines the current size as a variable.
- Generate suggested size in a separate script and update variable file (tfvars) but only commit to a staging branch.
- Run
terraform plan to show exact changes and surface billing deltas.
Example pseudo-process:
- dev-rightsize.sh generates suggestions and commits to
rightsizing/staging branch.
- CI runs
terraform plan -var-file=rightsizing.tfvars and posts plan to PR for approval.
- After manual approval,
terraform apply executes during maintenance window.
This enforces review and ties resizing to version control.
Cost comparison: droplets and plates, quick reference table 📊
| Resource type |
Typical use case |
Rightsizing action |
Expected monthly change |
| Basic Droplet (s-1vcpu) |
Small services, dev |
Downsize or schedule off-hours shutdown |
-30% to -60% |
| General purpose Droplet |
Web apps |
Resize to smaller general or move to vertical scale |
-10% to -40% |
| CPU-optimized Droplet |
Compute-heavy |
Increase horizontal replicas or use spot for batch |
depends |
| DOKS node pool (standard) |
Kubernetes workloads |
Rightsize node pool and use cluster autoscaler |
-20% to -50% |
| Block storage |
Databases |
Reduce IOPS tiers or reclaim unused volumes |
-5% to -40% |
Numbers are indicative; run pilots for exact savings per workload.
Example practical: how it works in reality ⚙️
📊 Case data:
- Service A: 3 Droplets, g-4vcpu-8gb each, 30 days metrics
- Average CPU: 12%, p95 CPU: 38%
- Average memory used: 2.8 GB
🧮 Calculation/process:
- Suggestion: resize to g-2vcpu-4gb (expected CPU headroom 120%, memory fits)
- Monthly price before: $24 x 3 = $72
- Monthly price after: $12 x 3 = $36
- Snapshot retention + test cost (one-time): $5
✅ Result: estimated recurring monthly savings $36 (50%) after 14 days validation
This block simulates a single service rightsizing pilot using real cost slugs and metrics.
Automation examples: schedule-based and usage-triggered resizing 🔁
- 🕒 Schedule-based: shut down dev Droplets at 22:00 UTC and start at 07:00 UTC using doctl or cloud-init scripts in CI pipelines to reduce runtime hours.
- 📈 Usage-triggered: use Prometheus alertmanager + a small serverless function that calls the DigitalOcean API to scale up a node pool when p95 CPU > 70% for 5 minutes, and scale down when p95 < 30% for 20 minutes.
Sample curl to resize via API (vertical resize requires power off in many cases):
curl -X POST "https://api.digitalocean.com/v2/droplets/123456/actions" /
-H "Content-Type: application/json" /
-H "Authorization: Bearer $DO_TOKEN" /
-d '{"type":"resize","disk":false,"size":"s-2vcpu-4gb"}'
Always snapshot before resizing if disk change or risk of data loss exists.
Doks-specific rightsizing: pods, node pools and autoscaler 🧩
For DigitalOcean Kubernetes (DOKS):
- Use resource requests and limits for pods to let cluster autoscaler make informed decisions.
- Create node pools by workload type (batch, frontend, stateful) and rightsizing them separately.
- Use the Kubernetes Cluster Autoscaler and Horizontal Pod Autoscaler (HPA) together.
Checklist:
- 🛠️ Ensure pods set CPU/memory requests and limits.
- 💡 Use vertical pod autoscaler (VPA) only for non-critical services.
- ✅ Test node pool resizing with a canary deployment and drain nodes safely.
Example HPA spec (short):
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
CI/CD patterns to reduce cost during test runs 🧪
- 💾 Use ephemeral environments: create and destroy droplets or DOKS namespaces per PR using Terraform or doctl in CI.
- ⚡ Use small instance types for testing and parallelize tests to reduce wall-clock time.
- 🔁 Cache builder images but avoid long-lived build servers billed 24/7.
Example GitHub Actions step to spin up a small droplet:
- name: create test droplet
run: |
doctl compute droplet create test-$GITHUB_RUN_ID --size s-1vcpu-1gb --image ubuntu-22-04 --wait --region nyc3 --tag-names ci-test
Ensure a cleanup job runs on workflow completion or after a timeout.
Snapshots, backups and retention strategies 💾
- ✅ Keep daily backups for critical databases and rotate retention (e.g., 7 daily, 4 weekly, 12 monthly).
- ⚠️ Avoid indefinite snapshots of inactive Droplets; delete orphan volumes and snapshots monthly.
- 💰 Use lifecycle rules: snapshot, store cheap copy, prune older than X days automatically.
Example retention policy pseudocode:
- Snapshot at 02:00 UTC daily for prod volumes.
- Tag snapshots with retention: daily7, weekly4, monthly12.
- Automated job removes snapshots older than retention tag rules.
Tagging and governance: map costs to teams and projects 🏷️
Consistent tagging is essential. Enforce tags via CI or admission controllers:
- Required tags: project, environment, owner, cost-center
- Enforce on Terraform modules and doctl creation scripts
- Generate weekly reports by tag using the billing API and cost allocation rules
Link to DigitalOcean tagging guidance: DigitalOcean tags
Alerts and thresholds to catch regressions ⚠️
Set alerts for these events:
- 🚨 sudden increase in CPU (delta > 50% over 5 minutes)
- 🚨 memory saturation (95th percentile > 90%)
- 🚨 unexpected node churn in DOKS
- 🚨 snapshot failures or backup errors
Recommended thresholds depend on workload criticality; start conservative and tune.
Case study: pilot rightsizing for an ecommerce app (quantified) 📈
- Baseline: 5 Droplets g-4vcpu-8gb, 1 database droplet, 2 load balancers. Monthly cost: $600.
- Action: 14-day metrics collected; web tier average CPU 18%, memory 45%.
- Pilot changes: resize web tier to g-2vcpu-4gb, reduce load balancer idle node count, reclaim one unused block volume.
- Result after 30 days: monthly cost $390, 35% savings. No latency regressions; minor memory tuning needed.
This illustrates measurable ROI using the documented pipeline.
Practical checklist: step-by-step rightsizing playbook ✅
- 1️⃣ Gather 14–30 days of metrics (CPU, memory, I/O, network).
- 2️⃣ Classify workloads and prioritize low-risk candidates.
- 3️⃣ Create snapshots and staging environments.
- 4️⃣ Run suggested resize in staging using Terraform or doctl.
- 5️⃣ Run a 7–14 day production pilot with monitoring and alerting.
- 6️⃣ Approve and roll out with maintenance windows and rollback plan.
Visual workflow: rightsizing process map
🟦 Discover → 🟧 Evaluate → 🟩 Stage → ✅ Approve & apply → 🔍 Monitor
Rightsizing workflow
🔎
Discover
Collect 14–30 days of metrics via doctl/Prometheus
⚖️
Evaluate
Score candidates and propose size changes
🧪
Stage
Apply in staging with Terraform plan and run smoke tests
✅
Approve & apply
Manual approval and scheduled maintenance window
🔍
Monitor
Observe for regressions; rollback if needed
Quick comparison: droplet sizes and use cases
Small
- ✓Dev/test, CI runners
- ✓Cheap, ephemeral
- ⚠Not for DBs
Medium/General
- ✓Web apps, mid-tier services
- ✓Balanced CPU/memory
- ✓Good for rightsizing
Advantages, risks and common mistakes ⚠️
Benefits / when to apply ✅
- ✅ Rapid cost reduction for predictable workloads.
- ✅ Simpler capacity planning when teams adopt rightsizing as standard practice.
- ✅ Improved visibility into resource ownership and chargebacks.
Errors to avoid / risks ⚠️
- ⚠️ Resizing without snapshots or tests can lead to downtime.
- ⚠️ Ignoring memory headroom causes OOMs and incidents.
- ⚠️ Over-automating without approvals can break SLAs.
FAQ: common developer questions ℹ️
How long of metrics are needed to rightsizing?
14–30 days is recommended to capture weekly and weekend patterns; extend to 90 days for highly seasonal workloads.
doctl can trigger actions via the DigitalOcean API; automation requires handling power-off, snapshots and monitoring for safety.
Should databases be downsized the same way?
Databases require extra caution: prefer vertical resizing with snapshots and off-peak windows; test performance on staging first.
What is a safe memory utilization target?
Aim for 60–75% average memory utilization with headroom for spikes; adjust by workload tolerance.
How to estimate monthly savings before applying changes?
Calculate current monthly cost per resource, map to suggested size slug pricing, and subtract. Include snapshot and testing cost as one-time expenses.
Does DOKS autoscaler handle rightsizing automatically?
Cluster Autoscaler adjusts node counts, but rightsizing node types still requires human or automated governance to change node size.
How to handle snapshots and retention without extra cost spikes?
Implement lifecycle policies and compress or move long-term snapshots off-platform if cost-efficient.
- Run a 14-day metrics collection for one non-critical service and produce a rightsizing suggestion using the Prometheus queries above.
- Create a Terraform plan that represents the suggested resize and open a PR for review so the change is auditable.
- Implement a scheduled cleanup job for orphan volumes and snapshots and tag resources consistently to enable cost reporting.