Operations 19 min read

How to Simulate CPU, Memory, Disk, and I/O Load on Linux with stress and dd

This guide explains how to use the Linux stress utility and the dd command, together with a custom shell script, to deliberately consume CPU, memory, disk space, and I/O resources for realistic load‑testing and performance analysis in production‑like environments.

Liangxu Linux
Liangxu Linux
Liangxu Linux
How to Simulate CPU, Memory, Disk, and I/O Load on Linux with stress and dd

Introduction

In production environments it is essential to simulate high resource usage on servers so that performance bottlenecks and stability issues become apparent early. This article provides practical methods for generating CPU, memory, disk‑space, and I/O load on a Linux host using stress and dd, and shows a ready‑to‑run shell script that orchestrates the whole process.

Approach

Use stress to create CPU and memory pressure.

Use dd to fill a secondary disk with large files, thereby consuming disk space and generating I/O.

Run a monitoring loop that stops the test when memory usage exceeds 80% or after a fixed duration (20 minutes).

Tool: stress

The stress command can spawn multiple processes that perform CPU calculations, memory allocations, disk writes, and file operations. The demo environment is Ubuntu 18.04.

Key Options

-c N

: start N CPU workers that repeatedly compute square roots of random numbers. -i N: start N I/O workers that repeatedly call sync(). -m N: start N memory workers that allocate and free memory. --vm-bytes B: size of each memory allocation. --vm-keep: keep the allocated memory instead of releasing it. --vm-hang N: after allocation, each worker sleeps N seconds before releasing memory. --vm-stride B: write a pattern every B bytes to trigger Copy‑On‑Write. -d N and --hdd-bytes B: create files of size B and repeatedly write/delete them. -t N or --timeout N: terminate the test after N seconds.

Examples: stress -c 4 Creates four CPU workers that continuously compute square roots. stress --vm 2 --vm-bytes 300M --vm-keep Spawns two processes each allocating 300 MiB of memory and keeping it allocated. stress -i 4 Generates four I/O workers that repeatedly call sync(), causing high iowait. stress -d 1 --hdd-bytes 10M Creates a process that continuously writes 10 MiB files, stressing the disk.

Tool: dd

The dd utility copies data between files or devices and can be used to create large files, test I/O speed, or generate random data.

Syntax

dd [options]

Common Options

if=FILE

: input file (e.g., /dev/zero). of=FILE: output file. bs=SIZE: block size. count=N: number of blocks to copy. conv=KEYWORD: conversion flags.

Examples

dd if=/dev/zero of=sun.txt bs=1M count=1

Creates a 1 MiB file named sun.txt. dd if=/dev/urandom bs=1 count=15 | base64 -w 0 Generates a 15‑byte random string and encodes it in base64.

Shell Script for Automated Simulation

The following Bash script runs the described tests, logs actions, and stops when memory usage exceeds 80% or after 20 minutes.

#!/bin/bash
# Simulate CPU, I/O, and memory usage
# ver 1.0
# Run daily at 01:00, duration 20 minutes
script_log="script_log.log"
mem_info=$(free -m | grep Mem)
used_mem=$(echo $mem_info | awk '{print $3}')
total_mem=$(echo $mem_info | awk '{print $2}')
mem_util=$(echo "scale=2; $used_mem / $total_mem * 100" | bc)
mem_utilization=$(printf "%.0f" "$mem_util")

if [ ! -f "$script_log" ]; then touch "$script_log"; fi

function simulate_memory() {
  INSTALLED=$(rpm -qa | grep stress)
  if [ $? -eq 0 ]; then
    echo "$(date +%Y-%m-%d-%H:%M) stress already installed" >> $script_log
  else
    yum install stress -y
    sleep 5
  fi
  if [ $mem_utilization -lt 80 ]; then
    stress --io 1 --vm 1 --vm-bytes "$(awk '/MemFree/{printf "%d
", 0.7*$2}' /proc/meminfo)k" --vm-keep &
    echo "$(date +%Y-%m-%d-%H:%M) started memory stress" >> $script_log
  fi
}

function simulate_file() {
  second_disk=$(lsblk | grep -w "vd[b-z]")
  if [ $? -eq 0 ]; then
    echo "$(date +%Y-%m-%d-%H:%M) second disk exists" >> $script_log
    if [ -d "/data" ]; then
      if [ -d "/data/second_disk_data_tmp" ]; then
        echo "$(date +%Y-%m-%d-%H:%M) temp dir exists" >> $script_log
      else
        mkdir -p /data/second_disk_data_tmp
        echo "$(date +%Y-%m-%d-%H:%M) created temp dir" >> $script_log
      fi
    fi
  else
    echo "$(date +%Y-%m-%d-%H:%M) second disk missing" >> $script_log
  fi

  if [ -f "/data/second_disk_data_tmp/data_tmp.txt" ]; then
    rm -f /data/second_disk_data_tmp/data_tmp.txt
    echo "$(date +%Y-%m-%d-%H:%M) removed existing temp file" >> $script_log
  else
    touch /data/second_disk_data_tmp/data_tmp.txt
  fi

  second_disk_usage=$(df -h | egrep "vd[b-z]" | awk '{print $5}' | tr -d "%")
  file_size=$(df -h | egrep "vd[b-z]" | awk '{print $4*0.8}' | tr -d "G" | bc)
  size_file=$(printf "%.0f" "$file_size")
  if [ $second_disk_usage -lt 80 ]; then
    time1=$(date +%s)
    echo "$(date +%Y-%m-%d-%H:%M) start creating temp file" >> $script_log
    dd if=/dev/zero of=/data/second_disk_data_tmp/data_tmp.txt bs=1G count=$size_file
    time2=$(date +%s)
    echo "$(date +%Y-%m-%d-%H:%M) created temp file in $((time2-time1)) seconds" >> $script_log
    if [ $second_disk_usage -ge 80 ]; then
      rm -rf /data/second_disk_data_tmp/data_tmp.txt
      echo "$(date +%Y-%m-%d-%H:%M) disk >80%, removed temp file" >> $script_log
    fi
  fi
}

start_time=$(date +%s)
simulate_memory
simulate_file
while true; do
  mem_info_now=$(free -m | grep Mem)
  used_mem_now=$(echo $mem_info_now | awk '{print $3}')
  total_mem_now=$(echo $mem_info_now | awk '{print $2}')
  mem_util_now=$(echo "scale=2; $used_mem_now / $total_mem_now * 100" | bc)
  mem_utilization_now=$(printf "%.0f" "$mem_util_now")
  current_time=$(date +%s)
  elapsed_time=$((current_time - start_time))
  if [ $mem_utilization_now -ge 80 ]; then
    for i in $(ps aux | grep "stress --io" | awk '{print $2}'); do kill -9 $i; done
    echo "$(date +%Y-%m-%d-%H:%M) memory >80%, stopped stress" >> $script_log
    sleep 10
    simulate_memory
    sleep 10
  fi
  if [ $elapsed_time -ge 1200 ]; then break; fi
  sleep 10
done
for i in $(ps aux | grep "stress --io" | awk '{print $2}'); do kill -9 $i; done
echo "$(date +%Y-%m-%d-%H:%M) finished stress test" >> $script_log
end_time=$(date +%s)
cost_time=$((end_time - start_time))
echo "$(date +%Y-%m-%d-%H:%M) script ran for $cost_time seconds and exited" >> $script_log
exit 0

Execution Results

Sample screenshots of CPU, memory, and I/O usage during the test:

CPU usage
CPU usage
Memory usage
Memory usage
I/O usage
I/O usage

Related Issues

When dd runs for a long time, the operation may take several minutes.

During dd execution, disk I/O can become saturated, leading to high iowait values.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Performance TestingLinuxstress testingdd commandresource simulation
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.