Script 08 · System Limits
8. Apply u-limit 65535
Raises open file limits to 65535 for users and selected systemd services such as PostgreSQL, PgBouncer, and Nginx.
Category: System Limits
Risk: Medium
Lines: calculating
Language: Bash / Linux
What this script does
- Support many concurrent sockets/files.
- Prevent service crashes from low nofile limits.
- Persist service overrides through reboot.
Prerequisites
- Root access
- PAM-based login sessions
- Systemd services installed if overrides are desired
Execution flow
- Backs up limits.conf
- Appends nofile limits
- Ensures pam_limits
- Creates systemd overrides
- Restarts detected services
Validation checklist
- ulimit -n
- cat /proc/<pid>/limits
- systemctl cat postgresql
Operational cautions
- Service restarts can interrupt traffic.
- Duplicated limits.conf entries should be cleaned during future maintenance.
Original script notes
ℹ️ Script Info: Increases the system's "open files" limit (ulimit) to 65535. This is essential for game servers and databases to handle thousands of simultaneous player connections without crashing.
cat << 'EOF' > setup_ulimit.sh && chmod +x setup_ulimit.sh && ./setup_ulimit.sh
#!/bin/bash
# Output Colors
GREEN='\033[0;32m'; RED='\033[0;31m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
echo -e "${BLUE}=====================================================${NC}"
echo -e "${BLUE} SYSTEM OPTIMIZATION: ULIMIT SETUP (65535) ${NC}"
echo -e "${BLUE}=====================================================${NC}"
# Ensure run as root/sudo
if [ "$EUID" -ne 0 ]; then
echo -e "${RED}[!] Please run this script with sudo or as root.${NC}"
exit 1
fi
# 1. Configure /etc/security/limits.conf
echo -e "${YELLOW}[*] Configuring /etc/security/limits.conf...${NC}"
# Backup original file
cp /etc/security/limits.conf /etc/security/limits.conf.bak
# Add configuration (Append)
cat <<LIMITS | tee -a /etc/security/limits.conf > /dev/null
# --- Custom ULIMIT Configuration $(date) ---
# Wildcard for regular users
* soft nofile 65535
* hard nofile 65535
# Explicit limit for root
root soft nofile 65535
root hard nofile 65535
LIMITS
# Check Postgres user
if id "postgres" >/dev/null 2>&1; then
echo -e "${GREEN}[+] User 'postgres' found. Adding specific limits.${NC}"
cat <<PGLIMITS | tee -a /etc/security/limits.conf > /dev/null
# Limit for Postgres user
postgres soft nofile 65535
postgres hard nofile 65535
PGLIMITS
else
echo -e "${YELLOW}[i] User 'postgres' not found. Skipping database user limits.${NC}"
fi
# 2. Check and activate pam_limits.so
echo -e "${YELLOW}[*] Checking PAM Module (common-session)...${NC}"
if grep -q "session required pam_limits.so" /etc/pam.d/common-session; then
echo -e "${GREEN}[OK] pam_limits.so is already active.${NC}"
else
echo "session required pam_limits.so" | tee -a /etc/pam.d/common-session > /dev/null
echo -e "${GREEN}[+] pam_limits.so added to common-session.${NC}"
fi
# 3. Reload Systemd & Apply Temporary Limit
echo -e "${YELLOW}[*] Reloading Systemd & Applying Limit...${NC}"
systemctl daemon-reload
ulimit -n 65535
# Check result
CURRENT_LIMIT=$(ulimit -n)
if [ "$CURRENT_LIMIT" == "65535" ]; then
echo -e "${GREEN}[OK] Current Session Limit: $CURRENT_LIMIT${NC}"
else
echo -e "${RED}[!] Failed to set current session limit (Current: $CURRENT_LIMIT).${NC}"
fi
# 4. Detect and Configure Service (PostgreSQL, PgBouncer, Nginx)
echo -e "\n${BLUE}--- Service Configuration (Database & Proxy) ---${NC}"
configure_service_limit() {
SERVICE_NAME=$1
DIR_NAME=$2
# Check if service is listed in systemd (active or inactive)
if systemctl list-unit-files | grep -q "^$SERVICE_NAME"; then
echo -e "${YELLOW}[*] Service '$SERVICE_NAME' detected.${NC}"
# Create override folder
mkdir -p "/etc/systemd/system/$DIR_NAME.service.d"
# Create override.conf file
echo -e "[Service]\nLimitNOFILE=65535" | tee "/etc/systemd/system/$DIR_NAME.service.d/override.conf" > /dev/null
echo -e "${GREEN}[+] LimitNOFILE added to $SERVICE_NAME.${NC}"
# Reload and Restart
echo -e "${YELLOW}[*] Restarting $SERVICE_NAME...${NC}"
systemctl daemon-reload
systemctl restart "$SERVICE_NAME"
# Verify via /proc (only if service is running)
PID=$(pgrep -f "$SERVICE_NAME" | head -n 1)
if [ -n "$PID" ]; then
LIMIT_CHECK=$(cat /proc/$PID/limits | grep "Max open files")
echo -e "${GREEN}[Verify] $SERVICE_NAME (PID $PID):${NC}"
echo -e "$LIMIT_CHECK"
else
echo -e "${YELLOW}[i] $SERVICE_NAME configured, but service is not running.${NC}"
fi
else
echo -e "${YELLOW}[i] Service '$SERVICE_NAME' not installed. Skipping.${NC}"
fi
}
# Run function for PostgreSQL
configure_service_limit "postgresql" "postgresql"
# Run function for PgBouncer
configure_service_limit "pgbouncer" "pgbouncer"
# Run function for Nginx
configure_service_limit "nginx" "nginx"
# 5. Reboot Confirmation
echo -e "\n${BLUE}=====================================================${NC}"
echo -e "${BLUE} CONFIGURATION COMPLETE ${NC}"
echo -e "${BLUE}=====================================================${NC}"
echo -e "${YELLOW}Note: limits.conf changes for login users (SSH) usually require logout/login or reboot.${NC}"
echo -e "Do you want to reboot the system now?"
echo "y) Yes, Reboot now"
echo "n) No, later"
read -p "Your Choice (y/n): " REBOOT_OPT
if [[ "$REBOOT_OPT" =~ ^[Yy]$ ]]; then
echo -e "${RED}[*] System will reboot in 3 seconds...${NC}"
sleep 3
reboot
else
echo -e "${GREEN}[OK] Please reboot manually later if needed.${NC}"
fi
EOF