Menu Sidebar
Menu

Next-generation managed WordPress hosting

What if there was a managed WordPress company that got rid of its servers altogether, and focused on helping you achieve the best possible results from any infrastructure on the market?

Here’s how it might work:

  1. When you sign up for an account, you connect your Google Analytics account, so the service has intelligence about your current traffic patterns.
  2. Based on expected resource utilization, the service suggests a server configuration on AWS, Digital Ocean, or Google Cloud Platform. Once you select your preference, the service provisions a WordPress-optimized hosting stack on the provider.
  3. As a part of the offering, the service provides a best-in-class object-cache drop-in, CDN-based full-page cache, Elasticsearch integration, etc.
  4. Over time, as the service passively monitors the performance of your WordPress instance, it offers suggestions for additional application-level optimizations (think New Relic but with a higher-level understanding of WordPress).
  5. Over time, the service also passively monitors your resource spend. If it detects there’s a more price-performant option on the market, the service makes it possible to migrate your site to new infrastructure seamlessly. As an example, a client of mine was spending $1k+ per month on Amazon’s CloudFront CDN. Now they’re spending $20/month on CloudFlare.

The target market is every customer subject to “Contact us for a quote” pricing (typically $2k/month and up). The service would enable a non-technical company to run their website in the price-performant public cloud without needing to internalize the DevOps cost.

Some existing options include ServerPilot and Laravel Forge, but neither focus deeply on WordPress.

Crazy?

One simple trick to clean up your WordPress database

Most WordPress sites likely run Akismet, which comes bundled with every new copy. What they probably don’t know is that, over time, Akismet will cause your wp_commentmeta table to balloon in size.

Use wp db size --tables to see the size of all tables:

$ wp db size --tables
+-----------------------+--------+
| Name                  | Size   |
+-----------------------+--------+
| wp_users              | 9 KB   |
| wp_usermeta           | 66 KB  |
| wp_posts              | 274 MB |
| wp_comments           | 48 MB  |
| wp_links              | 3 KB   |
| wp_options            | 41 MB  |
| wp_postmeta           | 25 MB  |
| wp_terms              | 796 KB |
| wp_term_taxonomy      | 621 KB |
| wp_term_relationships | 905 KB |
| wp_termmeta           | 48 KB  |
| wp_commentmeta        | 687 MB |
+-----------------------+--------+

Whoa! wp_commentmeta is way larger than I’d expect it to be. What’s going on there?

Let’s take a look at what keys are used:

$ wp db query "SELECT DISTINCT meta_key FROM wp_commentmeta"
+-----------------------+
| meta_key              |
+-----------------------+
| akismet_result        |
| akismet_history       |
| ERRating              |
| akismet_user_result   |
| akismet_user          |
| akismet_rechecking    |
| akismet_as_submitted  |
| akismet_pro_tip       |
| _wp_trash_meta_status |
| is_customer_note      |
| rating                |
+-----------------------+

Hm. Can’t quite tell what might be a large one from that set. Let’s look at a random comment:

$ wp comment meta list 659968
+------------+----------------------+-----------------------------------------------------------------------------------------+
| comment_id | meta_key             | meta_value                                                                              |
+------------+----------------------+-----------------------------------------------------------------------------------------+
| 659968     | akismet_result       | true                                                                                    |
| 659968     | akismet_history      | {"time":1503414726.1497,"event":"check-spam"}                                           |
| 659968     | akismet_as_submitted | {"comment_author":"coach handbag tassels embroidery","comment_author_email":"[email protected] |
|            |                      | il.com","comment_author_url":"http:\/\/www.bestcoachbag.store\/accordion-zip-wallet-in- |
|            |                      | signature-embossed-leather-p-37.html","comment_content":"Hi, i think that i saw you vis |
|            |                      | ited my site thus i came to return the favor?I'm attempting to find things to enhance m |
|            |                      | y website!I suppose its ok to use some of your ideas!!","comment_type":"","user_ip":"58 |
|            |                      | .19.83.5","user_agent":"Mozilla\/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Mozill |
|            |                      | a\/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 1.0.3705)","blog":"http:\ |
|            |                      | /\/example.com","blog_lang":"en_US","blog_charset":"UTF-8","permalink":"http:\/\/exa |
|            |                      | ple.com\/one-two-three"}                                           |
+------------+----------------------+-----------------------------------------------------------------------------------------+

What on Lord’s earth? Why is Akismet storing a copy of every comment in comment meta? I wonder how large that is in total:

$ wp db query "SELECT sum(char_length(meta_value)) FROM wp_commentmeta WHERE meta_key='akismet_as_submitted'"
+------------------------------+
| sum(char_length(meta_value)) |
+------------------------------+
|                    567045828 |
+------------------------------+

Ah, I see. Akismet’s akismet_as_submitted entry is 567 MB of the 1 GB total database size. That makes sense.

PS I tried to list the total comments but then I ran into a WP-CLI bug. Que será, será.

Meal plan for the next two weeks

100 free development hours

I love solving problems. Right now, I’m in search of a good problem to solve.

Here’s my pitch: send me a problem your business is struggling with. If I pick it, I’ll put at least 100 development hours (including documentation, support, etc.), free to you, into producing a WordPress plugin, open source library, or SaaS that solves the problem. You get early access, plus a lifetime usage license.

“What’s the catch?”

Of course, there are some qualifiers:

  • The problem needs to relate to your existing business. Building the next Snapchat is unlikely to be picked.
  • Because I’m doing the actual work, I own the end product. You get a lifetime usage license.
  • The better the problem, the more likely it will be picked.

The sky’s the limit, though. Five problems? Send them all.

“Why should I give you my valuable ideas?”

Unless you’re already working on the problem, you’d probably be better off with a robust solution than trying to build it yourself. Ideas are cheap; execution is everything.

Case in point: even I had the idea for Uber back in 2008.

“How will I know if my problem is picked?”

If I pick your submission, you’ll definitely hear from me.

Even if I don’t pick your submission, I’ll send a follow-up email in a few weeks time.

Here’s the submission form again.

“You’re crazy”

Yes, sometimes I have crazy ideas on my runs.

10 advanced WP-CLI tricks

These examples are adapted from my “WP-CLI: Advanced Usage” VIP Workshop presentation last week. I will now only ever use GIFs in slides.

wp-cli update --nightly

Live life on the bleeding edge by running latest and greatest version of WP-CLI.

The master branch is typically stable enough to use in local and staging environments. Or production too, yolo.

wp scaffold theme-tests

You probably knew you could scaffold plugin tests, but you probably didn’t know that you could also scaffold theme tests.

wp scaffold theme-tests gives you everything you need to write PHPUnit tests that leverage the WordPress test suite. Specifically:

  • bin/install-wp-tests.sh is a setup script to download the WordPress test suite and create the test database.
  • .travis.yml is a configuration file to automatically run your tests every time you push to GitHub (Travis account required).
  • tests/ contains the PHPUnit-specific files. You can modify test-sample.php to your liking.

Functionally, theme tests are pretty much the same as plugin tests. Check out the generated tests/bootstrap.php file for the secret of how your theme gets loaded into the test suite.

wp role reset

If you’ve been monkeying about with core’s default roles, wp role reset will set them back to the basics.

Reset a single role, or reset them all with --all.

wp rewrite list --match=<uri>

Rewrite rules are WordPress’ API for routing URI patterns to WP_Query instances.

For historical reasons, rewrite rules are stored in an option, which means you need to “flush” (regenerate) rewrite rules any time you register a new one.

The --match=<uri> argument makes it possible to see which rewrite rules match the URI you’ve provided, making it simple to debug why your rewrite rule doesn’t seem to be working. Because rewrite rules never work the first time.

wp shell

Ever wish you could literally write and run PHP code against WordPress?

Well, now you can. Actually, you’ve been able to for years.

wp site empty

If you want to delete all content in your WordPress install, but keep users, options, etc., wp site empty is your new best friend.

wp cron event run

After the Rewrite API, WP Cron is the WordPress developer’s second most bane of their existence. It’s opaque, buggy, and unreliable.

But, we have to use it, so we may as well make it easier to work with.

--prompt

There are some commands I still can never remember the arguments for.

--prompt works with any WP-CLI command, even those you write yourself, and interactively walks you through all of the arguments you need to complete.

wp-cli.yml

WP-CLI supports global- and project-based configuration files to accelerate your workflow.

For instance, if you use the same command with the same arguments over and over again, you can define those arguments as the default arguments for the command.

“Ugh, I always have to enter the same username and password when installing WordPress”… no you don’t!

Bonus!

You must be a WP-CLI master.

Here are four challenges for you to complete (with WP-CLI) in two minutes or less. For the solution, click on the link to see the GIF:

Three new experimental life hacks

Three new experimental life hacks I’m instituting today:

  • Waiting until 6 am to begin working. For a while now (year or more), I’ve been waking up anywhere between 3:30 and 4:30, and diving right into work. Needless to say, this is a recipe for sleep deprivation during the week. By forcing myself to wait until 6 am to work, I’m (hopefully) forcing myself to sleep another 45 to 60 minutes.
  • Only using Slack through the web browser. Rather than follow every community all the time, I’m only going to open each Slack organization as it’s relevant to what I’m working on. As far as distractions go, Slack is the new Twitter.
  • Using Focus to limit access to distracting websites and apps. I probably should’ve done this a while back. I’d much rather have 7.5 really productive hours in the day, than 10 moderately productive ones.
Newer Posts
Older Posts

Daniel Bachhuber

Proud father and husband. Principal, Hand Built. Maintainer, WP-CLI. Sales, rtCamp.