Upgrading an Ubuntu server on UpCloud to add more CPU, Memory and Disk Space
If you have not read my previous posts I have now moved my blog from Vultr to the awesome UpCloud host (signup using this link to get $25 free credit).
Recently I compared Digital Ocean, Vultr and UpCloud Disk IO here and UpCloud came out on top by a long way (read the blog post here). Here is my blog post on moving from Vultr to UpCloud.
Spoiler: UpCloud performance is great.
Why Upgrade
I have 1 CPU, 1 GB memory and 50GB storage and it is running well? I have PHP child workers set up and have set up the preferred use of memory over swap file usage.
Before UpCloud, when I had 512MB ram on Vultr I had multiple NGINX crashed a day so I used a bash script and scheduled a cron job to clear memory cache when memory fell below 100MB (view the script here). To further increase the speed of the WordPress I have configured the OS to use memory over the disk. About once a day free memory falls below 100MB (this is not a problem as my script clears cached items automatically).
I’d like to add more memory as I am working on some things (watch this space) and I will use the extra memory. I’d prefer the server is set up now for the expected workload.
How to Upgrade
This is how I upgraded from 1xCPU/2GB Memory/50GB Storage/2TB Transferred Data to a 2 CPU/4GB Mmeory/80GB Storage/4TB Transferred Data server.
UpCloud Pricing: https://www.upcloud.com/pricing/
Upgrade an UpCloud VM
I shut down my existing VM. Read this guide to setup a VM.
Login to the UpCloud dashboard, select your server (confirm the server has shut down) and click General Settings, choose the upgrade and click Update.
I confirmed the upgrade options (2x CPU, 4096 MB Memory).
Click Update
After 10 seconds you can start your server from the UpCloud server.
I confirmed the CPU upgrade was visible in the VM
Software Tweaks Post Upgrade.
I added these settings to the top of /etc/nginx/nginx.conf to ensure the extra CPU was used.
I increased PHP FPM ( /etc/php/7.2/fpm/php.ini ) to increase memory usage and child workers. I doubled child workers and max memory limit.
I restarted NGINX and PHP
I tweaked WordPress max memory limits
MySQL Tweaks: I logged into MySQL
I ran “SHOW GLOBAL STATUS” to view stats
mysql> SHOW GLOBAL STATUS; +-----------------------------------------------+--------------------------------------------------+ | Variable_name | Value | +-----------------------------------------------+--------------------------------------------------+ | Aborted_clients | 0 | | Aborted_connects | 0 | | Binlog_cache_disk_use | 0 | | Binlog_cache_use | 0 | | Binlog_stmt_cache_disk_use | 0 | | Binlog_stmt_cache_use | 0 | | Bytes_received | 3179986 | | Bytes_sent | 223872114 | | Com_admin_commands | 0 | | Com_assign_to_keycache | 0 | | Com_alter_db | 0 | | Com_alter_db_upgrade | 0 | | Com_alter_event | 0 | | Com_alter_function | 0 | | Com_alter_instance | 0 | | Com_alter_procedure | 0 | | Com_alter_server | 0 | | Com_alter_table | 0 | | Com_alter_tablespace | 0 | | Com_alter_user | 0 | | Com_analyze | 0 | | Com_begin | 0 | | Com_binlog | 0 | | Com_call_procedure | 0 | | Com_change_db | 284 | | Com_change_master | 0 | | Com_change_repl_filter | 0 | | Com_check | 0 | | Com_checksum | 0 | | Com_commit | 0 | | Com_create_db | 0 | | Com_create_event | 0 | | Com_create_function | 0 | | Com_create_index | 0 | | Com_create_procedure | 0 | | Com_create_server | 0 | | Com_create_table | 0 | | Com_create_trigger | 0 | | Com_create_udf | 0 | | Com_create_user | 0 | | Com_create_view | 0 | | Com_dealloc_sql | 0 | | Com_delete | 18 | | Com_delete_multi | 0 | | Com_do | 0 | | Com_drop_db | 0 | | Com_drop_event | 0 | | Com_drop_function | 0 | | Com_drop_index | 0 | | Com_drop_procedure | 0 | | Com_drop_server | 0 | | Com_drop_table | 0 | | Com_drop_trigger | 0 | | Com_drop_user | 0 | | Com_drop_view | 0 | | Com_empty_query | 0 | | Com_execute_sql | 0 | | Com_explain_other | 0 | | Com_flush | 0 | | Com_get_diagnostics | 0 | | Com_grant | 0 | | Com_ha_close | 0 | | Com_ha_open | 0 | | Com_ha_read | 0 | | Com_help | 0 | | Com_insert | 342 | | Com_insert_select | 0 | | Com_install_plugin | 0 | | Com_kill | 0 | | Com_load | 0 | | Com_lock_tables | 0 | | Com_optimize | 0 | | Com_preload_keys | 0 | | Com_prepare_sql | 0 | | Com_purge | 0 | | Com_purge_before_date | 0 | | Com_release_savepoint | 0 | | Com_rename_table | 0 | | Com_rename_user | 0 | | Com_repair | 0 | | Com_replace | 0 | | Com_replace_select | 0 | | Com_reset | 0 | | Com_resignal | 0 | | Com_revoke | 0 | | Com_revoke_all | 0 | | Com_rollback | 0 | | Com_rollback_to_savepoint | 0 | | Com_savepoint | 0 | | Com_select | 16358 | | Com_set_option | 849 | | Com_signal | 0 | | Com_show_binlog_events | 0 | | Com_show_binlogs | 0 | | Com_show_charsets | 0 | | Com_show_collations | 0 | | Com_show_create_db | 0 | | Com_show_create_event | 0 | | Com_show_create_func | 0 | | Com_show_create_proc | 0 | | Com_show_create_table | 0 | | Com_show_create_trigger | 0 | | Com_show_databases | 3 | | Com_show_engine_logs | 0 | | Com_show_engine_mutex | 0 | | Com_show_engine_status | 0 | | Com_show_events | 0 | | Com_show_errors | 0 | | Com_show_fields | 921 | | Com_show_function_code | 0 | | Com_show_function_status | 0 | | Com_show_grants | 0 | | Com_show_keys | 1 | | Com_show_master_status | 0 | | Com_show_open_tables | 0 | | Com_show_plugins | 0 | | Com_show_privileges | 0 | | Com_show_procedure_code | 0 | | Com_show_procedure_status | 0 | | Com_show_processlist | 0 | | Com_show_profile | 0 | | Com_show_profiles | 0 | | Com_show_relaylog_events | 0 | | Com_show_slave_hosts | 0 | | Com_show_slave_status | 0 | | Com_show_status | 6 | | Com_show_storage_engines | 0 | | Com_show_table_status | 0 | | Com_show_tables | 2 | | Com_show_triggers | 0 | | Com_show_variables | 6 | | Com_show_warnings | 1 | | Com_show_create_user | 0 | | Com_shutdown | 0 | | Com_slave_start | 0 | | Com_slave_stop | 0 | | Com_group_replication_start | 0 | | Com_group_replication_stop | 0 | | Com_stmt_execute | 4 | | Com_stmt_close | 4 | | Com_stmt_fetch | 0 | | Com_stmt_prepare | 4 | | Com_stmt_reset | 0 | | Com_stmt_send_long_data | 4 | | Com_truncate | 2 | | Com_uninstall_plugin | 0 | | Com_unlock_tables | 0 | | Com_update | 70 | | Com_update_multi | 0 | | Com_xa_commit | 0 | | Com_xa_end | 0 | | Com_xa_prepare | 0 | | Com_xa_recover | 0 | | Com_xa_rollback | 0 | | Com_xa_start | 0 | | Com_stmt_reprepare | 0 | | Connection_errors_accept | 0 | | Connection_errors_internal | 0 | | Connection_errors_max_connections | 0 | | Connection_errors_peer_address | 0 | | Connection_errors_select | 0 | | Connection_errors_tcpwrap | 0 | | Connections | 292 | | Created_tmp_disk_tables | 1124 | | Created_tmp_files | 30 | | Created_tmp_tables | 1369 | | Delayed_errors | 0 | | Delayed_insert_threads | 0 | | Delayed_writes | 0 | | Flush_commands | 1 | | Handler_commit | 6094 | | Handler_delete | 33 | | Handler_discover | 0 | | Handler_external_lock | 38571 | | Handler_mrr_init | 0 | | Handler_prepare | 0 | | Handler_read_first | 2299 | | Handler_read_key | 134761 | | Handler_read_last | 237 | | Handler_read_next | 310119 | | Handler_read_prev | 2733 | | Handler_read_rnd | 222350 | | Handler_read_rnd_next | 472820 | | Handler_rollback | 0 | | Handler_savepoint | 0 | | Handler_savepoint_rollback | 0 | | Handler_update | 15605 | | Handler_write | 17310 | | Innodb_buffer_pool_dump_status | Dumping of buffer pool not started | | Innodb_buffer_pool_load_status | Buffer pool(s) load completed at 180624 23:38:01 | | Innodb_buffer_pool_resize_status | | | Innodb_buffer_pool_pages_data | 1035 | | Innodb_buffer_pool_bytes_data | 16957440 | | Innodb_buffer_pool_pages_dirty | 0 | | Innodb_buffer_pool_bytes_dirty | 0 | | Innodb_buffer_pool_pages_flushed | 1936 | | Innodb_buffer_pool_pages_free | 7144 | | Innodb_buffer_pool_pages_misc | 13 | | Innodb_buffer_pool_pages_total | 8192 | | Innodb_buffer_pool_read_ahead_rnd | 0 | | Innodb_buffer_pool_read_ahead | 0 | | Innodb_buffer_pool_read_ahead_evicted | 0 | | Innodb_buffer_pool_read_requests | 306665 | | Innodb_buffer_pool_reads | 950 | | Innodb_buffer_pool_wait_free | 0 | | Innodb_buffer_pool_write_requests | 26509 | | Innodb_data_fsyncs | 1229 | | Innodb_data_pending_fsyncs | 0 | | Innodb_data_pending_reads | 0 | | Innodb_data_pending_writes | 0 | | Innodb_data_read | 16273920 | | Innodb_data_reads | 1078 | | Innodb_data_writes | 2857 | | Innodb_data_written | 53379584 | | Innodb_dblwr_pages_written | 1275 | | Innodb_dblwr_writes | 109 | | Innodb_log_waits | 0 | | Innodb_log_write_requests | 450 | | Innodb_log_writes | 585 | | Innodb_os_log_fsyncs | 793 | | Innodb_os_log_pending_fsyncs | 0 | | Innodb_os_log_pending_writes | 0 | | Innodb_os_log_written | 664064 | | Innodb_page_size | 16384 | | Innodb_pages_created | 56 | | Innodb_pages_read | 988 | | Innodb_pages_written | 1936 | | Innodb_row_lock_current_waits | 0 | | Innodb_row_lock_time | 0 | | Innodb_row_lock_time_avg | 0 | | Innodb_row_lock_time_max | 0 | | Innodb_row_lock_waits | 0 | | Innodb_rows_deleted | 2 | | Innodb_rows_inserted | 19219 | | Innodb_rows_read | 249102 | | Innodb_rows_updated | 77 | | Innodb_num_open_files | 81 | | Innodb_truncated_status_writes | 0 | | Innodb_available_undo_logs | 128 | | Key_blocks_not_flushed | 0 | | Key_blocks_unused | 12751 | | Key_blocks_used | 645 | | Key_read_requests | 321877 | | Key_reads | 648 | | Key_write_requests | 196 | | Key_writes | 150 | | Locked_connects | 0 | | Max_execution_time_exceeded | 0 | | Max_execution_time_set | 0 | | Max_execution_time_set_failed | 0 | | Max_used_connections | 3 | | Max_used_connections_time | 2018-06-24 23:43:48 | | Not_flushed_delayed_rows | 0 | | Ongoing_anonymous_transaction_count | 0 | | Open_files | 229 | | Open_streams | 0 | | Open_table_definitions | 206 | | Open_tables | 786 | | Opened_files | 502 | | Opened_table_definitions | 208 | | Opened_tables | 817 | | Performance_schema_accounts_lost | 0 | | Performance_schema_cond_classes_lost | 0 | | Performance_schema_cond_instances_lost | 0 | | Performance_schema_digest_lost | 0 | | Performance_schema_file_classes_lost | 0 | | Performance_schema_file_handles_lost | 0 | | Performance_schema_file_instances_lost | 0 | | Performance_schema_hosts_lost | 0 | | Performance_schema_index_stat_lost | 0 | | Performance_schema_locker_lost | 0 | | Performance_schema_memory_classes_lost | 0 | | Performance_schema_metadata_lock_lost | 0 | | Performance_schema_mutex_classes_lost | 0 | | Performance_schema_mutex_instances_lost | 0 | | Performance_schema_nested_statement_lost | 0 | | Performance_schema_prepared_statements_lost | 0 | | Performance_schema_program_lost | 0 | | Performance_schema_rwlock_classes_lost | 0 | | Performance_schema_rwlock_instances_lost | 0 | | Performance_schema_session_connect_attrs_lost | 0 | | Performance_schema_socket_classes_lost | 0 | | Performance_schema_socket_instances_lost | 0 | | Performance_schema_stage_classes_lost | 0 | | Performance_schema_statement_classes_lost | 0 | | Performance_schema_table_handles_lost | 0 | | Performance_schema_table_instances_lost | 0 | | Performance_schema_table_lock_stat_lost | 0 | | Performance_schema_thread_classes_lost | 0 | | Performance_schema_thread_instances_lost | 0 | | Performance_schema_users_lost | 0 | | Prepared_stmt_count | 0 | | Qcache_free_blocks | 1 | | Qcache_free_memory | 16760152 | | Qcache_hits | 0 | | Qcache_inserts | 0 | | Qcache_lowmem_prunes | 0 | | Qcache_not_cached | 16355 | | Qcache_queries_in_cache | 0 | | Qcache_total_blocks | 1 | | Queries | 19164 | | Questions | 19155 | | Select_full_join | 0 | | Select_full_range_join | 0 | | Select_range | 2677 | | Select_range_check | 0 | | Select_scan | 2098 | | Slave_open_temp_tables | 0 | | Slow_launch_threads | 0 | | Slow_queries | 0 | | Sort_merge_passes | 12 | | Sort_range | 4859 | | Sort_rows | 244452 | | Sort_scan | 854 | | Ssl_accept_renegotiates | 0 | | Ssl_accepts | 0 | | Ssl_callback_cache_hits | 0 | | Ssl_cipher | | | Ssl_cipher_list | | | Ssl_client_connects | 0 | | Ssl_connect_renegotiates | 0 | | Ssl_ctx_verify_depth | 0 | | Ssl_ctx_verify_mode | 0 | | Ssl_default_timeout | 0 | | Ssl_finished_accepts | 0 | | Ssl_finished_connects | 0 | | Ssl_server_not_after | | | Ssl_server_not_before | | | Ssl_session_cache_hits | 0 | | Ssl_session_cache_misses | 0 | | Ssl_session_cache_mode | NONE | | Ssl_session_cache_overflows | 0 | | Ssl_session_cache_size | 0 | | Ssl_session_cache_timeouts | 0 | | Ssl_sessions_reused | 0 | | Ssl_used_session_cache_entries | 0 | | Ssl_verify_depth | 0 | | Ssl_verify_mode | 0 | | Ssl_version | | | Table_locks_immediate | 11962 | | Table_locks_waited | 0 | | Table_open_cache_hits | 19395 | | Table_open_cache_misses | 817 | | Table_open_cache_overflows | 12 | | Tc_log_max_pages_used | 0 | | Tc_log_page_size | 0 | | Tc_log_page_waits | 0 | | Threads_cached | 2 | | Threads_connected | 1 | | Threads_created | 3 | | Threads_running | 1 | | Uptime | 2944 | | Uptime_since_flush_status | 2944 | +-----------------------------------------------+--------------------------------------------------+ 353 rows in set (0.00 sec)
Read more on SHOW GLOBAL STATUS here. Read more on the values here.
I can see NO major errors here (possibly due to UpClouds awesome disk IO) so I won’t be making memory tweaks in MySQL. Sign Up using this link and get $25 credit free on UpCloud and see for yourself how fast they are.
Configure Ubuntu System Memory Usage
Edit /etc/sysctl.conf
Add the following to allow things to sit in ram longer
Snip from: https://www.kernel.org/doc/Documentation/sysctl/vm.txt
This percentage value controls the tendency of the kernel to reclaim the memory which is used for caching of directory and inode objects. At the default value of vfs_cache_pressure=100 the kernel will attempt to reclaim dentries and inodes at a "fair" rate with respect to pagecache and swapcache reclaim. Decreasing vfs_cache_pressure causes the kernel to prefer to retain dentry and inode caches. When vfs_cache_pressure=0, the kernel will never reclaim dentries and inodes due to memory pressure and this can easily lead to out-of-memory conditions. Increasing vfs_cache_pressure beyond 100 causes the kernel to prefer to reclaim dentries and inodes. Increasing vfs_cache_pressure significantly beyond 100 may have negative performance impact. Reclaim code needs to take various locks to find freeable directory and inode objects. With vfs_cache_pressure=1000, it will look for ten times more freeable objects than there are."
Read these pages here and here regarding setting MySQL memory.
Reboot
Resize the disk
The 2x CPU, 4GB memory plan comes with 80GB storage allowance. My disk at present is 50GB and I will update the size soon following this guide soon.
Quick Benchmark
I used loader.io to load 500 users to access my site in 1 minute.
The benchmark worked with no errors.
This benchmark was performed with no Cloudflare caching. I should get Cloudflare caching working again to lower the average response time. I loaded my website manually in Google Chrome while loader.io threw 500 users at my site and it loaded very fast.
Conclusion
After a few days, I checked my memory logs and there were no low memory triggers (just normal internal memory management triggers). Ubuntu was happier.
This graph was taken before I set “vm.vfs_cache_pressure” so I will update this graph in a few days.
I hope this guide helps someone.
Please consider using my referral code and get $25 credit for free.
https://www.upcloud.com/register/?promo=D84793
Ask a question or recommend an article
[contact-form-7 id=”30″ title=”Ask a Question”]
Revision History
1.0 Initial Post