WordPress VM on $0.99 per month

I’ve been a big fan of Digital Ocean and their $5 Droplets (aka Virtual Machines). They are 100% SSD backed and speedy, and for $5 a month, you can afford to experiment. But when I borked my Droplet by screwing up a kernel update, I started thinking…. can I do this any cheaper than $5 per month?

This is when I discovered atlantic.net and their “GO” VPS package for $0.99 per month. $0.99! I had to try this out. Admittedly, the 10 GB of disk space and 256 MB of RAM is pretty tight, but I am strangely drawn to challenges of efficiency and really enjoy doing a lot with a little. So right now, this WordPress multisite install is running on a $0.99 per month server.

So far it has been very stable, but I have had to make some adjustments to keep from overrunning the limits of this box. First thing I reigned in was MySQL. Since this blog has very few posts, I could decrease the buffers to a very low value and still get good performance for my dataset. This would be much more challenging with more content and a larger database. Here’s what I have set in my.cnf – many of these variable could probably even go lower:

max_connections         = 50
connect_timeout         = 5
wait_timeout            = 600
max_allowed_packet      = 16M
thread_cache_size       = 86
sort_buffer_size        = 64k
bulk_insert_buffer_size = 64k
tmp_table_size          = 12M
max_heap_table_size     = 12M

myisam_recover          = BACKUP
key_buffer_size         = 32k
table_open_cache        = 400
myisam_sort_buffer_size = 32k
concurrent_insert       = 2
read_buffer_size        = 32k
read_rnd_buffer_size    = 32k

query_cache_limit               = 256K
query_cache_size                = 2M

default_storage_engine  = InnoDB

innodb_buffer_pool_size = 12M
innodb_log_buffer_size  = 2M
innodb_file_per_table   = 1
innodb_open_files       = 400
innodb_io_capacity      = 400
innodb_flush_method     = O_DIRECT

All of my tables are InnoDB, so I cut way back on any MyISAM buffers. Running mysqltuner.pl shows the maximum possible RAM usage to be 62.6 MB, about 25% of our RAM. Not too shabby.

 >>  MySQLTuner 1.3.0 - Major Hayden 
 >>  Bug reports, feature requests, and downloads at http://mysqltuner.com/
 >>  Run with '--help' for additional options and output filtering
[OK] Logged in using credentials from debian maintenance account.
[!!] Currently running unsupported MySQL version 10.1.1-MariaDB-1~trusty-wsrep-log
[OK] Operating on 32-bit architecture with less than 2GB RAM

-------- Storage Engine Statistics -------------------------------------------
[--] Status: +Aria +CSV +InnoDB +MRG_MyISAM
[--] Data in InnoDB tables: 11M (Tables: 69)
[!!] Total fragmented tables: 1

-------- Security Recommendations  -------------------------------------------
[OK] All database users have passwords assigned

-------- Performance Metrics -------------------------------------------------
[--] Up for: 3m 56s (639 q [2.708 qps], 63 conn, TX: 282K, RX: 71K)
[--] Reads / Writes: 87% / 13%
[--] Total buffers: 36.0M global + 544.0K per thread (50 max threads)
[OK] Maximum possible memory usage: 62.6M (25% of installed RAM)
[OK] Slow queries: 0% (0/639)
[OK] Highest usage of available connections: 4% (2/50)
[!!] Key buffer size / total MyISAM indexes: 32.0K/121.0K
[OK] Query cache efficiency: 27.0% (127 cached / 470 selects)
[OK] Query cache prunes per day: 0
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 22 sorts)
[OK] Temporary tables created on disk: 20% (54 on disk / 266 total)
[OK] Thread cache hit rate: 96% (2 created / 63 connections)
[OK] Table cache hit rate: 52% (99 open / 187 opened)
[OK] Open file limit used: 5% (60/1K)
[OK] Table locks acquired immediately: 100% (236 immediate / 236 locks)
[OK] InnoDB buffer pool / data size: 12.0M/11.0M
[OK] InnoDB log waits: 0

I then checked /etc/memcached.conf (since I switched from CentOS to Ubuntu) and made sure Memcached was set to only use 64 MB of RAM (-m 64). In the future, I plan to run some tests to see how much RAM WordPress actually uses in Memcached from a clean install (my suspicion is it isn’t much).

Besides that, the tweaks are minor. The memory_limit in php.ini is 128M and pm.max_children = 8 for php-fpm. I have swap enabled on this VPS to allow the disk to be used for overflow.

With hardly anything installed, I’m already using 2.5 GB of the 10 GB disk. Thankfully I don’t upload much on here, so this should last me for a while.

The low RAM limits what you can realistically run, but it fits my needs nicely and I’ve so far been happy with it. Now don’t expect the modern design or fancy tools like you get from Digital Ocean, but if you don’t expect too much from Atlantic.net, you might not be let down.

Update: It was pointed out to me that the feature set in the Atlantic.net dashboard and the Digital Ocean dashboard are very similar and, after checking out the Atlantic.net dashboard, I can say that it does have a pretty similar list of features. The main tools I use (snapshots, console access, and password resets) are all there.


  1. Geoff says:

    Sounds kinda pricey – maybe they will have a Cyber Monday sale? Haha. Wow, who knew the prices could go this low. Kudos for the configuration. I’d like to test this out with my 26 plug-in site. Ha.

  2. Gagan says:

    Are you using Apache ?? or Nginx ?

    Can you shed some light on the over configuration like OS (I see ubuntu) /Mysql falvor (mariadb/Percona) and Version and other small compositions that made you achive such low memory usage ?

    Thanks Alot

    • zach says:

      I’m using Nginx and PHP-FPM. You can see some details about my Nginx config in my microcaching post – I have my entire config file linked from there https://thelastcicada.com/microcaching-with-nginx-for-wordpress

      For the database, I’m using MariaDB 10.1.1. I don’t think the memory usage is significantly different than what MySQL would be – you just have to turn the buffers and caching down way low and just rely on the performance you can get with everything running from the disk.

      For PHP-FPM, I have the workers limited to a very small amount to run concurrently:

      pm.max_children = 8
      pm.start_servers = 2
      pm.min_spare_servers = 1
      pm.max_spare_servers = 3

      I’m using memcached for page and object caching in WordPress and have it set to use on 64 MB maximum. I also have opcache.memory_consumption=64 in php.ini, decreased from the default of 128 MB.

      One of the reasons this all works is that my site has 2 blog posts, a simple theme, and very few plugins. This is a multisite with another site on it with about a dozen posts and a few more plugins, but all of it gets maybe 15 visitors a day on a good day. If I were asking more from this server by having a complex site with lots of content and quite a few visitors, I’d probably run into my limits very quickly. That being said, any site that is mainly serving static content to readers should be able to effectively cache those pages and run all of the PHP on very minimal hardware such as this.

Leave a Reply