Skip to content

Instantly share code, notes, and snippets.

@teknoraver
Last active December 22, 2025 14:19
Show Gist options
  • Select an option

  • Save teknoraver/88641858bb12d820e835e241418bf937 to your computer and use it in GitHub Desktop.

Select an option

Save teknoraver/88641858bb12d820e835e241418bf937 to your computer and use it in GitHub Desktop.
Find the maximum I/O size for a single read/write syscall
#!/bin/sh
#
# Find the maximum I/O size for a single read/write syscall
# Uses binary search after detecting the approximate limit by doubling
#
# Works on Linux, BSD, and other POSIX systems
set -eu
# Start with 1 MB
size=$((1024 * 1024))
prev_size=0
echo 'Finding maximum syscall I/O size...'
echo 'Starting from 1 MB and doubling until limit is reached'
echo
while true; do
# Convert size to human-readable format
if [ "$size" -lt $((1024 * 1024)) ]; then
size_kb=$((size / 1024))
size_str="$size_kb KB"
elif [ "$size" -lt $((1024 * 1024 * 1024)) ]; then
size_mb=$((size / 1024 / 1024))
size_str="$size_mb MB"
else
size_gb=$((size / 1024 / 1024 / 1024))
size_str="$size_gb GB"
fi
printf "Testing size: $size_str ... "
# Read 'size' bytes in one syscall and count actual bytes read
# Check if we got fewer bytes than requested (short read)
if dd status=noxfer if=/dev/zero of=/dev/null count=1 bs="$size" 2>&1 | grep -q '^0+[0-9]'; then
echo 'LIMIT REACHED'
break
fi
echo OK
# Save current size for next iteration
prev_size=$size
# Double the size for next iteration
new_size=$((size * 2))
# Check for overflow (when doubling causes a negative number or smaller value)
if [ "$new_size" -le "$size" ]; then
echo
echo 'Reached maximum representable size without hitting limit'
echo "Maximum tested size: $size bytes ($size_str)"
exit 0
fi
size=$new_size
done
echo
echo "Starting binary search between $prev_size and $size bytes..."
echo
# Binary search for exact limit
low=$prev_size
high=$size
initial_high=$high
# Calculate human-readable format for initial_high
if [ "$initial_high" -lt $((1024 * 1024)) ]; then
initial_high_kb=$((initial_high / 1024))
initial_high_str="${initial_high_kb} KB"
elif [ "$initial_high" -lt $((1024 * 1024 * 1024)) ]; then
initial_high_mb=$((initial_high / 1024 / 1024))
initial_high_str="${initial_high_mb} MB"
else
initial_high_gb=$((initial_high / 1024 / 1024 / 1024))
initial_high_str="${initial_high_gb} GB"
fi
while [ $((high - low)) -gt 1 ]; do
mid=$(((low + high) / 2))
# Calculate how much we subtracted from initial_high
subtracted=$((initial_high - mid))
printf " Trying $initial_high_str - $subtracted bytes ... "
# Test if this size works - check if we get all bytes
if dd status=noxfer if=/dev/zero of=/dev/null count=1 bs="$mid" 2>&1 | grep -q '^0+[0-9]'; then
echo FAIL
high=$mid
else
echo OK
low=$mid
fi
done
echo
echo '======================================='
echo " MAXIMUM SYSCALL I/O SIZE: $low bytes"
echo '======================================='
echo " Decimal: $low"
printf " Hex: 0x%x\n" "$low"
echo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment