I just spent the entire morning debugging a customer whose WordPress installation had suffered from a collection of issues, seemingly all at once. Their business requires ongoing subscriptions for access to their product, and those subscriptions are running via a series of plugins that are integrated together, utilizing the WooCommerce subscription system to process transactions. By my count, there are about 7 plugins required to accomplish this task. At the end of each month, the system must process hundreds of transactions that renew member access to the product. Sounds simple enough, right?
In the custom development world, this is a very simple use-case. You first set up a user record in a user database. You set up a “product”, in this case, a recurring subscription. And then, you run a process each month on a timed basis to run through each subscription and process a new transaction. It’s actually a fairly easy thing to custom build, and the only integration you will need is a payment gateway such as Stripe, Braintree, etc. As we all know, those are not major development tasks as each provider has a sophisticated series of API solutions we can utilize to handle the heavy lifting. In fact, the even more elegant solution would be to use features available within those platforms to handle the recurring billings. That saves a lot of development time and makes the timed process much easier to develop in addition to securely storing the credit card details.
But, ultimately, this client is based on WordPress, where the appeal of off-the-shelf solutions was appealing to their initial development budgets and timeframes. So, the solution was built utilizing a mixture of event management plugins, WooCommerce, and the subscription platform. As I have mentioned, this required more than a couple of plugins to work properly.
Today we got the call that on the first of the month subscriptions failed to go through. Thus began the process of troubleshooting. First, there were flaws in how WordPress handles automated processes. “Crons” are usually something that is set up at a server level, running on a timed basis so essential scripts can run in the background. WordPress doesn’t set up their timed processes that way, instead, they have to utilize the permissions available to them, which means that the only way they can determine to see if a process should run is to run a check on each page load of the site. This isn’t horribly effective and can lead to wonky behavior. In this case, the timed scripts weren’t behaving nicely, and the timed transactions weren’t being run.
That was just the beginning of our issue. After we established that the scripts were running properly, we discovered that once the jobs ran, the transactions failed. One of the 7 plugins was spawning a PHP parse error. This was easy to diagnose as the Wordpress system shows us the error in the “scheduled actions” tab. So, we started to initiate the update on that plugin. This proved a bit challenging as the client’s license failed – it had expired sometime in the past. We had to pay for a new license and then verify that the changes installed correctly. Easy enough… so far!
Upon downloading of the plugin, which was a required manual and not an automatic update, the upgrade created a dependency error – another plugin needed an update as well (are you starting to see a theme here?). This is when things got really interesting… The plugin immediately upon update created a 500 error whenever a page loaded. For those who don’t know, a 500 error is a pretty generic server error. To get more verbose insight, you have to turn debug mode on within Wordpress. So we did that and saw that this update was causing yet another PHP parse error. This one was a bit harder to diagnose. The plugin is central to the site’s performance, so literally, every page on the site created a 500 error and didn’t load. This included the entire admin interface. Not a single page loaded…
Now, let me just break a bit off topic here because I have to address this… How can any CMS allow a plugin’s individual parse error break the entire admin portal? How can there be such a dependency in a plugin? At the very least, the CMS portion should always load. To have an update of add-on software cause a sitewide 500 error is something that shouldn’t ever happen. It would make more sense that if and when a plugin breaks that the resulting error is relegated to one particular section of the site, which obviously isn’t what WordPress allows. But to break the admin? I’ve never seen a decoupled or headless CMS that breaks down in such a manner. But, I digress…
The only option left was to revert every plugin back to its original state prior to the changeover, which we did. This ultimately did lead to a restoration of the issue, but, only after some tinkering to bring the site back to life. Upon testing, we found an interesting thing had happened – restoration of the old plugins resulted in the original problem being corrected – transactions had begun flowing freely and working. Confused yet? We are!
I wish this was a one-time story, and that I’ve never seen such a thing before… But unfortunately, we run into this story on a pretty regular basis. The fact of the matter and the point of this entire post is that the “plugin culture” which has inundated the web development world has some pretty nasty realities:
- Site owners and operators are told that plugins “seamlessly” integrate to third-party services and other plugins. Well, yes and no.
- Updates are regularly updated for security and are as easy to update as hitting a button. Not always!
- Plugins can handle almost any use case you throw at them. Not quite.
The fact is, each of those claims sometimes holds a bit of truth but oftentimes are mostly misleading. How is one to know any better? How do you know when you are building out a comprehensive and stable solution or just bandaging things together? Unfortunately, for the layman, it’s hard to recognize the difference. You have to count on your developer and trust their counsel. My advice: always ask for 3 or 4 ways to do something. Most problems have many solutions, and a developer who can spotlight multiple pathways will be able to tell you the pros and cons of each approach.
How would this have played out if the solution was custom developed? Well, first, the timed mechanism would’ve been installed at the server level. It would run on time, every day, as scheduled, not relying on some other hack to be initiated. Secondly, there wouldn’t be any “plugins” from third-party developers. The software would be custom assembled to achieve the task at hand. The idea of an update to custom software is somewhat laughable – you amend software, you iterate software, but you don’t just update it because someone told you to or because some button appeared asking you to - it doesn’t work that way.
The fact is – custom software has far fewer points of failure:
- Requires frequent, unpredictable updates.
- Dependency on other plugins can cause breakdowns. It's difficult to determine dependencies.
- Plugins affect far more than anyone knows – a plugin can take down an entire site.
- Plugins never achieve 100% of the desired functionality.
- Plugins are third party and hard to diagnose at a deep level. Good luck getting support for mission-critical applications.
- While more economical at the outset, ongoing maintenance costs add up.
- Updates only when necessary due to third-party integrations, or when improvements warranted.
- Only dependencies are with third-party integrations or at the server layer (same as off-the-shelf solutions). Changes to API’s or other integration methods are announced many months in advance.
- Highly unlikely a fix could be allowed to happen as development happens in a sandbox and problems are discovered earlier.
- Custom development allows developers to achieve near-total use case requirements resulting in fewer breakdowns.
- Custom code is owned by you, and your developers can dig to any level to improve.
- Ongoing maintenance is minimal other than core software updates at the server level: you’d do that with Wordpress too.
Today was frustrating, but since we do work with off-the-shelf solutions, we see these problems on a fairly regular basis. As I’ve said many times before – Wordpress isn’t a horrible piece of software. It’s just too often extended to beyond its comfort zone for the sake of saving budget or realizing unrealistic timeframes. It’s important that people consider the long-term implications of piecing together software versus just implementing it properly in the first place. Houses made out of cards are going to tumble down – often at the worst times