Infrastructure

How to optimize costs without adding servers: a cloud cost optimization guide

Binadit Tech Team · Jun 10, 2026 · 6 min czytaj
How to optimize costs without adding servers: a cloud cost optimization guide

What you'll achieve and why it matters

This guide shows you how to diagnose performance issues systematically and optimize your existing infrastructure instead of throwing more servers at the problem. You'll learn to identify real bottlenecks, implement targeted fixes, and reduce costs while improving performance.

Most infrastructure problems stem from inefficient resource usage, not resource shortage. Proper optimization can cut costs by 30-60% while delivering better user experience.

Prerequisites and assumptions

You'll need:

  • SSH access to your servers
  • Basic command line familiarity
  • Monitoring tools installed (we'll use standard Linux tools plus application metrics)
  • A staging environment that mirrors production load patterns

This guide assumes you're running a typical web application stack with database, application servers, and load balancer. The principles apply whether you're on dedicated servers, VPS, or cloud instances.

Step-by-step implementation with concrete commands, configs and code

Step 1: Establish baseline metrics

Before optimizing anything, measure current performance. Install and configure monitoring tools to capture baseline data.

Install system monitoring tools:

sudo apt update
sudo apt install htop iotop nethogs sysstat

Enable system statistics collection:

sudo systemctl enable sysstat
sudo systemctl start sysstat

Create a monitoring script to capture key metrics:

#!/bin/bash
# save as monitor.sh
echo "$(date): $(uptime)" >> /var/log/performance.log
echo "Memory: $(free -h | grep Mem)" >> /var/log/performance.log
echo "Disk I/O: $(iostat -x 1 1 | tail -n +4)" >> /var/log/performance.log
echo "---" >> /var/log/performance.log

Run this script every minute via cron to establish patterns:

* * * * * /path/to/monitor.sh

Step 2: Identify resource bottlenecks

Most performance issues fall into four categories: CPU, memory, disk I/O, or network. Use these commands to identify which resources are actually constrained.

Check CPU usage patterns over time:

sar -u 1 60

If CPU usage consistently exceeds 80%, investigate which processes consume most cycles:

top -o %CPU

Check memory usage and identify memory leaks:

free -h
ps aux --sort=-%mem | head -20

Monitor disk I/O to spot database or filesystem bottlenecks:

iostat -x 1 10

Look for high %util values (>90%) or long await times (>10ms for SSD, >20ms for HDD).

Check network utilization:

nethogs -d 5

Step 3: Optimize database performance

Database queries cause most web application bottlenecks. Optimize these before adding database servers.

Enable MySQL slow query log to identify problematic queries:

sudo mysql -e "SET GLOBAL slow_query_log = 'ON';"
sudo mysql -e "SET GLOBAL long_query_time = 2;"

Analyze slow queries after running for 24 hours:

sudo mysqldumpslow /var/lib/mysql/slow.log | head -10

Add indexes for frequently queried columns. For an ecommerce platform, typical optimization looks like:

ALTER TABLE orders ADD INDEX idx_created_status (created_at, status);
ALTER TABLE products ADD INDEX idx_category_price (category_id, price);

Configure MySQL memory settings based on available RAM. For a server with 8GB RAM dedicated to MySQL:

# Add to /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
innodb_buffer_pool_size = 5G
query_cache_size = 512M
tmp_table_size = 256M
max_heap_table_size = 256M

Step 4: Implement application-level caching

Caching reduces database load more effectively than adding database servers.

Install Redis for application caching:

sudo apt install redis-server
sudo systemctl enable redis-server

Configure Redis for optimal memory usage:

# /etc/redis/redis.conf
maxmemory 2gb
maxmemory-policy allkeys-lru
save 900 1
save 300 10

Implement caching in your application. Here's a PHP example for caching database queries:

function getCachedProducts($categoryId) {
    $redis = new Redis();
    $redis->connect('127.0.0.1', 6379);
    
    $cacheKey = "products_category_" . $categoryId;
    $cached = $redis->get($cacheKey);
    
    if ($cached) {
        return json_decode($cached, true);
    }
    
    $products = $this->database->query(
        "SELECT * FROM products WHERE category_id = ?", 
        [$categoryId]
    );
    
    $redis->setex($cacheKey, 3600, json_encode($products));
    return $products;
}

Step 5: Optimize web server configuration

Web server misconfiguration wastes resources. Optimize settings based on your actual traffic patterns.

For Nginx, configure worker processes and connections based on CPU cores:

# /etc/nginx/nginx.conf
worker_processes auto;
worker_connections 1024;

http {
    keepalive_timeout 65;
    gzip on;
    gzip_comp_level 6;
    gzip_types text/plain text/css application/javascript;
}

Enable HTTP/2 for better connection efficiency:

# In your server block
listen 443 ssl http2;
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;

Configure connection pooling for PHP-FPM to reduce overhead:

# /etc/php/8.1/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35

Step 6: Implement CDN and static asset optimization

Serving static content from optimized locations reduces server load significantly.

Configure Nginx to serve static files with proper caching headers:

# Add to your server block
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
    access_log off;
}

Compress images and minify CSS/JavaScript. Create a build process:

#!/bin/bash
# optimize-assets.sh
for img in assets/images/*.jpg; do
    jpegoptim --max=85 "$img"
done

for css in assets/css/*.css; do
    uglifycss "$css" > "${css%.css}.min.css"
done

Verification: how to confirm it works

Measure improvements using the same metrics you established in your baseline. Performance optimization success shows in specific numbers.

Compare before and after CPU utilization:

sar -u -f /var/log/sysstat/saXX | grep Average

Check memory usage improvement:

free -h

Measure database performance improvement:

sudo mysqladmin extended-status | grep -E "(Queries|Uptime)"
# Calculate queries per second: Queries / Uptime

Test application response times using a simple load test:

ab -n 1000 -c 10 http://yoursite.com/

Monitor key application metrics:

  • Average response time should decrease by 20-50%
  • Database queries per page should reduce
  • Memory usage should stabilize
  • CPU peaks should be lower and less frequent

Check your infrastructure costs after running optimizations for a full billing cycle. Most businesses see 30-60% cost reduction without adding servers.

Common pitfalls to avoid

Don't optimize everything at once. Implement changes incrementally and measure impact before proceeding. This prevents introducing issues and helps identify which optimizations deliver the most value.

Avoid premature optimization of code that isn't actually causing bottlenecks. Profile first, optimize second.

Don't ignore monitoring during optimization. Some changes may improve one metric while degrading another.

Next steps and related reading

Once you've optimized your existing infrastructure, focus on preventing future performance degradation. Implement automated monitoring to catch issues before they impact users.

Consider implementing immutable infrastructure patterns to maintain optimization consistency across deployments.

Set up alerts for key performance metrics so you catch problems before they require emergency server additions.

Plan regular optimization reviews. Infrastructure needs change as your application grows, and optimization requirements evolve with usage patterns.

Long-term infrastructure strategy

Effective cloud cost optimization services require ongoing attention to infrastructure efficiency. The goal isn't just reducing immediate costs, but building systems that scale efficiently.

Most performance problems that seem to require more servers actually indicate inefficient resource usage. Database queries without proper indexes, unoptimized caching strategies, or misconfigured web servers waste more resources than insufficient capacity.

Building optimization into your development and deployment processes prevents the costly cycle of adding servers to compensate for inefficiency. This approach delivers better performance at lower cost than constantly scaling hardware.

Need this running in production without building it yourself? See our managed infrastructure services or schedule a call.