I have a laravel application which I've installed on a 1GB standard droplet running ubuntu 20.4, nginx, MySQL 8 and php 7.4
The application isn't even live yet and I notice it's already using over 60% memory - 68%
Below is a snap shot of the current high memory running processes. Is this level of memory usage normal for a laravel application which is not even live i.e. limited load?
top - 15:47:51 up 1 day, 23:53, 1 user, load average: 0.00, 0.01, 0.00
Tasks: 100 total, 3 running, 97 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.3 us, 0.3 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 981.3 total, 89.5 free, 612.3 used, 279.5 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 200.7 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
815 mysql 20 0 1306168 408208 2892 S 0.3 40.6 18:20.97 mysqld
2259 www-data 20 0 244024 38424 25504 S 0.0 3.8 0:05.27 php-fpm7.4
388 root 19 -1 106512 38196 37008 S 0.0 3.8 0:06.24 systemd-journal
2265 www-data 20 0 244032 37988 25108 S 0.0 3.8 0:05.14 php-fpm7.4
2257 www-data 20 0 244004 37780 24856 S 0.0 3.8 0:05.22 php-fpm7.4
988 root 20 0 125160 30236 4640 S 0.3 3.0 2:03.41 php
741 root 20 0 649232 22700 6672 S 0.0 2.3 0:17.61 snapd
544 root rt 0 280180 17976 8184 S 0.0 1.8 0:11.26 multipathd
743 root 20 0 31348 16972 2468 S 0.0 1.7 0:31.63 supervisord
738 root 20 0 238392 13208 7244 S 0.0 1.3 0:09.45 php-fpm7.4
726 do-agent 20 0 559692 11852 5560 S 0.0 1.2 0:20.79 do-agent
825 root 20 0 108036 11804 4160 S 0.0 1.2 0:00.10 unattended-upgr
736 root 20 0 29220 11364 3708 S 0.0 1.1 0:00.11 networkd-dispat
1 root 20 0 168752 10208 5772 S 0.0 1.0 0:12.03 systemd
15532 sammy 20 0 18556 8488 6948 S 0.0 0.8 0:00.08 systemd
778 www-data 20 0 71004 8276 3552 S 0.0 0.8 0:02.71 nginx
15522 root 20 0 13760 8256 6816 S 0.0 0.8 0:00.01 sshd
623 systemd+ 20 0 23912 6756 2752 S 0.0 0.7 0:00.60 systemd-resolve
15634 osama 20 0 13892 5912 4452 S 0.0 0.6 0:00.06 sshd
747 root 20 0 16860 5564 4552 S 0.0 0.6 0:02.54 systemd-logind
15635 sammy 20 0 10032 5104 3412 S 0.0 0.5 0:00.04 bash
15537 sammy 20 0 169820 4572 0 S 0.0 0.5 0:00.00 (sd-pam)
763 root 20 0 12160 4504 3572 S 0.0 0.4 0:01.33 sshd
621 systemd+ 20 0 18544 4292 3276 S 0.0 0.4 0:01.11 systemd-network
659 root 20 0 18880 3808 2528 S 0.0 0.4 0:01.92 systemd-udevd
My concern is once the application goes live and the load increases, more database connection it going to run out of memory. I know I can resize the droplet and increase the memory or set up some swap space but is this amount of memory usage normal for an unused laravel application?
How can I optimize the high memory usage processes such as mysql, niginx, php. Looks like mysql8 is the main culprit hogging all the memory. Below are the mysql8 settings:
#
# The MySQL database server configuration file.
#
# One can use all long options that the program supports.
# Run program with --help to get a list of available options and with
# --print-defaults to see which it would actually understand and use.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html
# Here is entries for some specific programs
# The following values assume you have at least 32M ram
[mysqld]
#
# * Basic Settings
#
user = mysql
# pid-file = /var/run/mysqld/mysqld.pid
# socket = /var/run/mysqld/mysqld.sock
# port = 3306
# datadir = /var/lib/mysql
# If MySQL is running as a replication slave, this should be
# changed. Ref https://dev.mysql.com/doc/refman/8.0/en/server-system- variables.html#sysvar_tmpdir
# tmpdir = /tmp
#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address = 127.0.0.1
#
# * Fine Tuning
#
key_buffer_size = 16M
# max_allowed_packet = 64M
# thread_stack = 256K
# thread_cache_size = -1
# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
myisam-recover-options = BACKUP
# max_connections = 151
# table_open_cache = 4000
#
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
#
# Log all queries
# Be aware that this log type is a performance killer.
# general_log_file = /var/log/mysql/query.log
# general_log = 1
#
# Error log - should be very few entries.
#
log_error = /var/log/mysql/error.log
#
# Here you can see queries with especially long duration
# slow_query_log = 1
# slow_query_log_file = /var/log/mysql/mysql-slow.log
# long_query_time = 2
# log-queries-not-using-indexes
#
# The following can be used as easy to replay backup logs or for replication.
# note: if you are setting up a replication slave, see README.Debian about
# other settings you may need to change.
# server-id = 1
# log_bin = /var/log/mysql/mysql-bin.log
# binlog_expire_logs_seconds = 2592000
max_binlog_size = 100M
# binlog_do_db = include_database_name
# binlog_ignore_db = include_database_name
Any tips and advice much appreciate as this is the first time I'm using a vps.
*** UPDATE ***
Further to advice from tim, switching off mysql performance schema has made a huge difference I now get the following:
top - 10:33:26 up 5 days, 18:39, 1 user, load average: 0.01, 0.03, 0.00
Tasks: 114 total, 1 running, 107 sleeping, 6 stopped, 0 zombie
%Cpu(s): 0.7 us, 0.3 sy, 0.0 ni, 98.7 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 981.3 total, 253.8 free, 360.9 used, 366.7 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 449.2 avail Mem
An operating system will use all the RAM for cache - cache can be freed almost instantly and helps performance. So RAM available generally isn't important, it's freeable memory that's important.
From the info above:
You actually have 297 + 89 = 386MB available for use.
I have MySQL, PHP, Nginx, and a few utilities running on an AWS server with 512MB RAM and 512MB of swap, so it's possible. I made a six part tutorial which is probably a bit out of date now but could have some useful tips.
From memory the key things to do are:
You may start with
https://www.techolac.com/linux/how-to-optimize-apache-mysql-performance-for-1gb-ram-vps-centos-rhel/
Good advice for a low memory instance..and tuning mysql down.
Be advised, that you will loose performance, so understand where your bottle necks are.
If you have massively complex queries, the optimise your database.
You might even very simple queries, and you can use an entirely different database server instead , such as a NOSQL database.
So not only think about tuning your server, but look at code running on it, and perhaps optimise your code too.