Step-by-Step: Diagnosing PHP-FPM memory consumption per child process on Google Cloud Servers
Understanding PHP-FPM Memory Management
PHP-FPM (FastCGI Process Manager) is a popular alternative PHP FastCGI implementation with some additional features useful for sites of any size, especially busy ones. A common challenge in production environments, particularly on resource-constrained cloud instances like those on Google Cloud Platform (GCP), is managing and diagnosing memory consumption. Uncontrolled memory usage by PHP-FPM worker processes can lead to performance degradation, OOM (Out Of Memory) killer invocation, and service instability. This guide provides a step-by-step approach to pinpointing memory usage per PHP-FPM child process.
Prerequisites and Initial Setup
Before diving into diagnostics, ensure you have the following:
- SSH access to your Google Cloud Compute Engine instance.
- Root or sudo privileges.
- PHP-FPM installed and running (typically managed by systemd on modern Linux distributions).
- Basic familiarity with Linux command-line tools.
We’ll primarily use standard Linux utilities and PHP-FPM’s built-in status page for this analysis.
Enabling PHP-FPM Status Page
The PHP-FPM status page provides real-time insights into active processes, request statistics, and memory usage. It’s crucial for dynamic monitoring.
Locating the PHP-FPM Configuration
The primary configuration file for PHP-FPM is usually located at /etc/php/[version]/fpm/php-fpm.conf. Within this file, you’ll find directives to include pool configurations, often found in /etc/php/[version]/fpm/pool.d/www.conf (or a similar name for your specific pool).
Enabling the `status` and `ping` Path
Edit your pool configuration file (e.g., /etc/php/[version]/fpm/pool.d/www.conf) and add or modify the following directives:
[global] ; ... other global settings ... [www] ; ... other pool settings ... ; Enable status page and set the allowed IP addresses pm.status_path = /fpm_status ; For security, restrict access to specific IPs or localhost ; Example: Allow access from localhost and a specific internal IP ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or localhost ; access.log = /var/log/php-fpm/www.access.log ; request_slowlog_timeout = 10 ; slowlog = /var/log/php-fpm/www-slow.log ; pm.max_requests = 500 ; pm.process_idle_timeout = 10s ; pm.max_children = 50 ; pm.start_servers = 5 ; pm.min_spare_servers = 2 ; pm.max_spare_servers = 8 ; Enable status page and set the allowed IP addresses ; For security, restrict access to specific IPs or