“There’s such a thing as loyalty,” said Jane. MacPhee, who had been carefully shutting up the snuffbox, suddenly looked up with a hundred covenanters in his eyes. “There is, Ma’am,” he said. “As you get older you will learn that it is a virtue too important to be lavished on individual personalities.”
C.S. Lewis in That Hideous Strength, page 190
Posts
A Year in the Wilderness: Bearing Witness in the Boundary Waters
by Amy and Dave Freeman
Description
Since its establishment as a federally protected wilderness in 1964, the Boundary Waters has become one of our nation’s most valuable—and most frequently visited—natural treasures. When Amy and Dave Freeman learned of toxic mining proposed within this area’s watershed, they decided to take action—by spending a year in the wilderness, and sharing their experience through video, photos, and blogs with an audience of hundreds of thousands of concerned citizens. This book tells the deeper story of their adventure in northern Minnesota: of loons whistling under a moonrise, of ice booming as it forms and cracks, of a moose and her calf swimming across a misty lake.
With the magic—and urgent message—that has rallied an international audience to the campaign to save the Boundary Waters, A Year in the Wilderness is a rousing cry of witness activism, and a stunning tribute to this singularly beautiful region.
My Thoughts
We purchased this book at Lake Superior Trading Post during a camping trip earlier this year.
The authors spent a year in the Boundary Waters Canoe Area Wilderness documenting their experiences with hundreds of photographs, some video, and a few podcast episodes. The book contains dozens of the beautiful full-color photographs.
They camped at approximately 120 different sites, explored 500 lakes, rivers and streams, and traveled more than 2,000 miles by canoe, foot, ski, snowshoe and dog team.
They had a fairly large volunteer support team who brought in food and supplies, and they had a satellite phone to post updates, but otherwise they were cut off from civilization for a year.
They muse on the importance of solitude and retreat from the noise of daily life, and come to appreciate the beauties of the area more than ever.
We’ve been to the edge of the Boundary Waters but it’ll likely be a few years before we can really visit, and thanks to this book, I cannot wait.
This was my favorite book of the entire year.
Resources
Visit https://www.savetheboundarywaters.org/wildernessyear for more information.
Here’s a short video produced by some friends of the Freemans:
Note: this is an affiliate link, so I may get a small commission if you purchase using the link. This commission does not affect the content of this post.
Visual Studio Code Workspaces and PHP Intelephense
When developing WordPress plugins for general use, I like to open the plugin directory itself in VS Code.
This allows me to use the git integration and terminal without wading through the wp-content/plugins/{plugin name}
directory structure.
However, this results in the WordPress functions appearing as “undefined function” and the inability to jump to their definition or hover to see parameters and other details.
Here’s how I fix that annoyance:
- Save the open project as a workspace (File > Save As Workspace…)
- Add a fresh WordPress installation to the workspace, making it a multi-root workspace
- Note: this step is not strictly necessary as noted below.
- Go to Settings (Code > Preferences > Settings), click on the “Workspace” tab, and search for
intelephense.environment.includePaths
- In the “Include Paths” section, add an entry for the fresh WordPress installation so Intelephense will index it
Alfred Workflows
I’ve been using Alfred on macOS for years now and it’s a wonderful productivity enhancement (on average, I use it more than 100 times a day).
Here are some of my favorite workflows:
Alfred SSH
Alfred SSH by Dean Jackson gives you quick access to SSH connections you have defined in your config, as well as quick one-off connections.
Colors
Colors by Tyler Eich is a quick way to preview color codes and convert between formats.
Datetime Format Converter
Datetime Format Converter by Michael Waterfall is the fastest way I’ve found to convert Unix timestamps to human-readable dates, and vice versa.
Dev Doctor
Dev Doctor by Syd Lawrence provides quick-reference lookups for code documentation.
DevDocs
DevDocs by Yannick Galatol is another workflow that provides quick reference for documentation using devdocs.io.
HTTP Status
HTTP Status by Marc Görtz is my preferred reference for quickly finding an HTTP status code either by number or name.
Laravel Docs
Laravel Docs by Till Krüss is amazing…it seems to have indexed most of Laravel documentation, so searching by any key word tends to bring up the best page of the documentation.
Laravel Livewire Docs
Livewire Docs searches the Laravel Livewire documentation.
Open in VS Code
I use Visual Studio Code as my primary development tool; I created this workflow to quickly and easily open a file or directory in VS Code.
TailwindCSS Docs
TailwindCSS Docs searches the TailwindCSS documentation.
VPN Manager
VPN Manager by Dean Jackson is a great way to enable/disable VPN connections on the fly.
WordPress Developer
WordPress Developer by keesiemeijer is the fastest way to search and find functions, filters, classes, and more in the WordPress documentation.
Installing New Relic on RunCloud
Now that New Relic is offering a free tier, I’ve started using it to monitor some personal websites.
This particular server was configured using RunCloud, and the New Relic installation script didn’t automatically install New Relic monitoring for RunCloud’s PHP. Here are the steps I followed to get that working:
- Install New Relic APM for PHP following this documentation.
- Find the RunCloud PHP directories:
/RunCloud/Packages/php7*rc/bin
- Set the
NR_INSTALL_PATH
variable to all the versions I had installed, as described here. - Run
newrelic-install
and selectall
to install for all versions. - Reload PHP:
systemctl reload php7*rc-fpm
Bonus
I found this plugin that adds WordPress-specific knowledge to New Relic reporting.
Bonus 2
New Relic allows you to specify multiple app names to group together all the sites on a server, all of one client’s sites, etc. See their documentation for more details.
The WordPress plugin provides the wp_nr_app_name
filter to modify the app name.
Setting Up YouTube Live
WP YouTube Live is a free WordPress plugin to display live videos on a WordPress site.
To get started, follow these instructions:
Enable Streaming on YouTube
- Decide if you will stream from a personal account or a brand account. Read more about the differences in this article.
- Decide how you will stream video.
- See this article for more information about what YouTube supports.
- For general principles about live-streaming hardware and software, see this tutorial I wrote in 2013.
- Some options for computer programs: YouTube website, Wirecast, vMix
- Enable streaming for your account; see this article for details.
- Verify your channel here: youtube.com/verify
- See this article for more information about verifying your account.
Set up the YouTube Data API
- If you don’t have a Google account already, sign up here.
- Log in to the Google Developers Console: console.developers.google.com
- Create a new project if you don’t have one already.
- Go to the Credentials page: console.developers.google.com/apis/credentials
- Click the “Create Credentials” button at the top and choose “API key” and copy the new key
- Go to the Enabled APIs page: console.developers.google.com/apis/enabled
- Search for Youtube Data API v3 and enable it.
Reference: developers.google.com/youtube/v3/getting-started
Install the WordPress Plugin
- Go to the plugins page on the backend of your website.
- Press the “Add New” button and search for “WP YouTube Live.”
- Install and then activate the plugin.
- Go to Settings > YouTube, enter your channel ID and API key, and choose what to display when no video is live.
- Add the
[youtube_live]
shortcode to the page where you want the video player to appear.
Support
For other support questions, please use the WordPress support forum.
Secondhand: Travels in the New Global Garage Sale
Secondhand: Travels in the New Global Garage Sale by Adam Minter is a fascinating look at what happens to people’s stuff when they no longer want or need it.
The first couple of chapters discuss people decluttering on their own or disposing of a deceased family member’s belongings, often by bringing in a service to go through the stuff and determine what can be sold or donated and what should simply be thrown away.
The second part of the book goes into the global economy of second-hand stuff. For example, all the Goodwill stores in one county take unsold clothing to a Goodwill “warehouse” where clothing is sold for a dollar or two per bag; people purchase truckloads of clothing, drive over the border, and resell it at enough of a profit to make a living.
Highlights
Between 1967 and 2017, the money that Americans spent annually on stuff—from sofas to cell phones—increased almost twentyfold.
Location 51
Garage sales aren’t where it’s at anymore. Half the stuff doesn’t sell because the prices are too high. Everyone thinks they’re on Antiques Roadshow.
Location 836
In the United States (and in Europe), most secondhand goods are donated rather than sold. As a result, most people lack a financial incentive to take care of their things. So instead of seeing the end of an object’s life as an opportunity to extract some last value from it (as people do with their cars), Americans view that object in philanthropic terms. It’ll help the poor; it’ll benefit the environment. For better or worse, both those reasons have proved to be little incentive to take care of stuff.
Location 1076
None of the cut-up fragments of sweatshirt through which Wilson is rummaging were used in India. Rather, they were likely made in South Asia, exported to the United States, and worn until they were donated to Goodwill, the Salvation Army, or some other thrift-based exporter. When they didn’t sell there, they were exported again, to Kandla most likely (or perhaps Mississauga, en route to Kandla), cut up, and exported again—this time to Star Wipers in Newark, Ohio. Each step of that journey makes perfect economic sense, even if the totality of it sounds ridiculous.
Location 2755
American Kingpin: The Epic Hunt for the Criminal Mastermind Behind the Silk Road
American Kingpin: The Epic Hunt for the Criminal Mastermind Behind the Silk Road is an account of how Ross Ulbricht built the Silk Road, a marketplace for illegal drugs (the book several times compares it to “Amazon for drugs”).
It traces the history of how he built the site, and how individuals from several branches of law enforcement collaborated (or competed…) to stop him.
I thought the technical explanations were very good: accurate so a geek like me didn’t get annoyed or frustrated about incorrect descriptions, and short enough to be relevant and informative to others.
Overall I highly recommend it.
The Secret Life of Pronouns: What Our Words Say About Us by James W. Pennebaker
Description
We spend our lives communicating. In the last fifty years, we’ve zoomed through radically different forms of communication, from typewriters to tablet computers, text messages to tweets. We generate more and more words with each passing day. Hiding in that deluge of language are amazing insights into who we are, how we think, and what we feel.
In The Secret Life of Pronouns, social psychologist and language expert James W. Pennebaker uses his groundbreaking research in computational linguistics-in essence, counting the frequency of words we use-to show that our language carries secrets about our feelings, our self-concept, and our social intelligence. Our most forgettable words, such as pronouns and prepositions, can be the most revealing: their patterns are as distinctive as fingerprints.
Using innovative analytic techniques, Pennebaker X-rays everything from Craigslist advertisements to the Federalist Papers-or your own writing, in quizzes you can take yourself-to yield unexpected insights. Who would have predicted that the high school student who uses too many verbs in her college admissions essay is likely to make lower grades in college? Or that a world leader’s use of pronouns could reliably presage whether he led his country into war? You’ll learn why it’s bad when politicians use “we” instead of “I,” what Lady Gaga and William Butler Yeats have in common, and how Ebenezer Scrooge’s syntax hints at his self-deception and repressed emotion. Barack Obama, Sylvia Plath, and King Lear are among the figures who make cameo appearances in this sprightly, surprising tour of what our words are saying-whether we mean them to or not.
My Thoughts
I thought this was a mildly interesting book explaining how people’s use of language reveals a lot about their personality and mental condition.
For instance, when speaking to a superior, people tend to use more personal pronouns, but when speaking to a person under their authority, they tend to use far fewer pronouns. This is an unconscious behavior that happens even within minutes of meeting a stranger.
However, the book didn’t seem especially practical. Many times the author reiterated that we don’t pick up on differences in pronoun usage and must rely on word-counting software to analyze text and find patterns. Because word usage is a symptom, not the cause of our behavior, changing our speech patterns won’t have much effect. Rather, it opens a window into what’s going on internally in a person’s thoughts and emotions.
WordPress and WooCommerce at Scale with 500,000 Users
WordPress generally works fairly well on small-to-medium sites; on larger sites, it can run into performance issues because of the size of the database.
A current project I’m working on for LuminFire has a WooCommerce store with potentially 270,000+ customers, and that’s causing some issues with site performance. For sake of development, our dev store has 500,000+ users.
Contents:
- Generating Dummy Users
- WordPress User Dashboard
- WooCommmerce User Queries
- WooCommerce User Reports
- WordPress Posts Dashboard
Generating Dummy Users
First, I generated a CSV file with 50,000 fake users using mockaroo.com and imported them using this plugin (I had to bump up my PHP memory limit to 4096MB and execution time to 240 and it still timed out a couple of times, but I deleted the users who had already been imported and then ran the import again).
Update: I have since learned about WC Smooth Generator, and it may have worked just as well or better.
I figured 50K unique users were plenty and duplicating them via MySQL queries was more efficient, so wrote these queries to do the job.
The users
queries ran in seconds each, copying a batch of 50K rows at a time. The usermeta
queries, not so much…they took about 11 minutes each since there were about 1.71 million rows to clone each time.
In case it’s helpful to you, here are files with the dummy users:
- CSV with 50K users
- MySQL dump of
wp_users
table (30.4MB)- It does include the ID field since it needs to match the
usermeta
table. - The first user ID is 510024; if you try to import and have user IDs above 510024, you’ll have errors.
- 500,000 rows
- It does include the ID field since it needs to match the
- MySQL dump of
wp_usermeta
table (148.5MB)- It does not include the
meta_id
field (so no errors trying to overwrite existing IDs). - 17,000,000+ rows
- It does not include the
WordPress User Dashboard
At the top of the user dashboard, WordPress typically displays a list of the user roles on your site, as well as the number of users in each role.
The number of each users is generated by the count_users
function, which uses a resource-intensive SQL query. In our dev site, it takes 15+ seconds just to run the query.
This is a known issue and should be resolved in WordPress 5.0 (currently scheduled for release in late 2018), but we need this working much sooner.
WordPress Multisite drops the number of users per role and instead shows just a list of roles; that’s how WordPress.com and other large multisite networks avoid this performance hit.
The proposed patch on the ticket modifies the count_users
function to behave similarly to WP Multisite: if there are more than 10,000 users (modifiable with the new wp_is_large_user_count
filter), it doesn’t show the number of users per role.
Since the patch is for the development version of the WP code, it doesn’t apply cleanly to a production site, so I manually patched WP core. Here are several patch files for different versions of WordPress; make sure to use the appropriate patch for your version:
You can apply this patch file by downloading it, opening your WordPress installation in a terminal, and running git apply <path-to-downloaded-patch-file>
.
WooCommerce User Queries
The biggest performance hit I found was searching for customers when editing an order; it took 10–15 seconds for search results to be returned.
- If searching by customer ID, the backend would respond pretty quickly.
- Otherwise, it runs a full text search for the search term in the first and last name, which takes a while; see the code for full details.
Since orders aren’t manually assigned/reassigned too often, we decided this behavior was acceptable for now.
WooCommerce Customer Reports
The WooCommerce customer reports were the other major performance hit. For now, we simply disabled the customers reports since this particular customer already has a third-party system where they manage the customer data, so they’re not likely to use the WooCommerce reports.
Customers vs. Guests
Timing details:
- Around 20–40 sec to load the page
- Around 7 sec to get administrator users
- Around 7 sec to get shop_manager users
- Around 6 sec to get all other users
Here are the actual actual MySQL queries. In my staging environment, PHP ran out of memory; in my local environment, it took 305MB(!) to load the report for 1 week (the default view).
As noted above, we gave up on optimizing this report since the customer doesn’t really need it.
Customers List
This was completely unusable; it took 300 seconds to load the page.
Here are the actual MySQL queries. Two JOIN
s times in each query with full-text search on two columns × three queries was just too much on such a large table.
As noted above, we gave up on optimizing this report since the customer doesn’t really need it.
WordPress Posts Dashboard
Update: found another place where there’s a 15+ second wait. When bulk-editing posts (or any other post type that supports authors), an author dropdown causes a full search of the wp_usermeta
table. I’ve updated the patch file in the gist above to include a fix for this.
Summary
In summary, having 500,000 users on a WordPress and WooCommerce site doesn’t hurt overall performance too much, as long as you include an upcoming change in WP core and can get by without the WooCommerce customer reports.
We may explore further options to improve performance particularly when getting user roles from wp_usermeta
, and I will update this post or add a new post if we find other enhancements.