The post “The Theory of Constraints in PHP” is the editorial for the PHP Channel’s newsletter on July 11th. To stay on top of PHP news, posts, and relevant links, make sure to keep up to date here.
I had been reading The Phoenix Project, a great novel about IT (you read that right), which presents day to day IT and devops problems at a large Amazon-like company in a way which makes mortals understand the complexities and chaos of 21st century technology.
Without giving away any spoilers, at one point in the book the Theory of Constraints is mentioned. As per Wikipedia:
The Theory of Constraints (TOC) is a management paradigm that views any manageable system as being limited in achieving more of its goals by a very small number of constraints. There is always at least one constraint, and TOC uses a focusing process to identify the constraint and restructure the rest of the organization around it.
The Theory of Constraints can be distilled to the idea that the chain is only as strong as its weakest link.
In the book it was phrased thusly:
Any improvements made anywhere besides the bottleneck are an illusion.
For some reason, this resonated with me much more than the chain idiom. There’s just something about building something that’s ineffective that’s more relatable to me than breaking something that’s weakly built.
Factories and Browsers
As (initially) presented in the book and slightly dumbed down here, a factory floor was seeing a pile-up of work orders at one desk, with other areas of the factory working somewhat satisfactorily. Without working on optimizing this one desk’s throughput and by (either coincidentally or intentionally) upgrading the process that precedes or supersedes it, the factory became clogged with work because the former lead to a stack of products before the desk that had no destination, and the latter lead to idle workers at the other end of the facility, waiting for the products to reach them for shipping, but all stuck in slow processing at the central desk.
To go off on a slight tangent here – if you follow me on Twitter, you know I like to rant about browsers. I especially lose it when they put in updates like native OSX notifications but fail to address the decade old RAM use problem. Some people are quick to address this as an appeal to worse problems fallacy, but I disagree. While, yes, this is an appeal to a worse problem, I don’t see it as fallacy – rather, I see it as a lack of identified constraints on Google’s part. As a company, they seem completely clueless of what’s in need of optimization, or are devoid of resources to dedicate to the fixing of this problem (not sure which is worse). So we have all these “improvements” made outside the bottleneck, driving power users mad and resulting in attempts at revamping the browser by slapping another skin on it (Vivaldi, Brave, Opera, Ghost…), but unable to make progress because, again, the bottleneck remains. If you move the desk and the whole factory setup from one building to the next, the desk is still the problem. Fix the desk.
Theory of Constraints in PHP
So how does this apply to web apps? Or, better yet, PHP apps in particular?
These days, it’s really easy to follow this principle and identify the constraint(s). We have so many amazing tools at our disposal that identifying the bottleneck within a few hours is generally a given:
Blackfire will provide you with fantastic in-depth graphs of your application’s execution stack, indicating code bottlenecks with ease. These will include database bottlenecks as well, if executed in the code stack you’re analyzing, making the whole thing infinitely easier to optimize.
Not many people know this, but Xdebug has that same execution stack diagram with time analysis, letting you do that same thing locally!
There’s a bunch of valuable QA tools which can help you test your app to bits – super long test times are often indicative of bottlenecks, and pinpointing them there while they’re running on mock data and test examples can be incredibly rewarding.
A bit of an oldie but goldie, this set of posts helps you optimize your MySQL once you’ve identified it as a bottleneck..
But remember that optimizing it just for the sake of optimization isn’t a good idea!
It helps if you nuke your app with requests, and compare before/after results – it’ll be a clear indicator on much your optimizations boosted the app as a whole. A tool like Siege can help with that, and we have an in-depth guide for just that.
The tools above are a good start, but far from exhaustive, and far from applicable to every problem you might run into. Additional articles from this Premium PHP Anthology about Better PHP Development might be useful, but I’m honestly hoping for more diverse examples and links from you! Shoot!
The ToC is a valid concern in software development, and just as applicable as anywhere else. We’ve all encountered bottlenecks, and we’ve all stupidly tried to improve upon anything other than the bottleneck – or if you haven’t fallen into this trap yet, I promise that you will.
Luckily, the PHP ecosystem is ripe with tools that help with identifying bottlenecks and turning them into system constraints. If your application is having performance or throughput issues, find the bottleneck, tag it, then drop all other work until the bottleneck has been resolved. Pull critical people off of other tasks, even if it means ignoring incoming unrelated high priority tasks, and have everyone who’s qualified focus on that one problem until it’s resolved. The entire system will thank you for it because, more often than not, that one bottleneck is the reason for those other high priority tickets in the first place. Don’t Brent yourself into a corner! (To understand that reference, you’ll need to read the book)
If you’re flying solo, the same principles apply – as you’re looking at your columns of tasks in Trello, Zenkit, Freedcamp, or another project management tool, identify the bottleneck one, paint it red, and move all others into a column off-screen or one that can be collapsed until the constraint has been resolved and the system remodeled around it. Doing anything less will incur mountains of tech debt that’ll bury you later.
How do you find your bottlenecks? Do you remodel the system around the identified constraint, or do you remodel the constraint instead and try to hack your way through it? Which tools/tutorials have I missed in the above list? Let me know in the comments – let’s build a comprehensive list together – and remember: “Improving daily work is even more important than doing daily work“! (Another great quote from the book)