Declaring your love of simplicity has long been a prerequisite pledge for anyone working on products. It’s the perfect placeholder word for everyone to load up with their own personal aspirations, all the while nodding in agreement with someone holding diametrically opposed ideas. Even the most obtusely designed products will have a parent ready to explain “it’s actually quite simple if you just…”
Beyond the trouble of pinning down exactly what simple means is certifying its value. “Simple” is just one of the many qualities we can use to evaluate products, and it is by no means the most important. To use a trite phrase to describe another: Simple is overrated!
Here are but a few qualities I’d take over simple:
I wouldn’t just rank “simple” low on my list of priorities for a finished product, but also for the tools we use to take us there. My favorite tool is the programming language Ruby. It is anything but simple. Thousands of methods across the standard library, so many keywords I can’t even tell you the number. Full of subtlety that directly relates to its wonder and delight.
Basecamp is in the same boat. It’s clear, it’s just enough, but it is not “simple”. We literally have hundreds of individual screens spread across 6 major features that could each be individual products (and are!).
The value is derived from solving many of the problems most people face when trying to make progress together. It tries to do so in a clear and playful manner. “Simple” is not high on the list of priorities, and the product is much better for it.
It’s time to knock “simple” down a peg. It’s just not that important.
Disappointment occurs when expectations don’t match reality. And our expectations for software quality are profoundly unrealistic. Thus, lots of people are continuously disappointed — even enraged — by software bugs. They shouldn’t be.
The only reliable, widely used way to ensure impeccable software quality is to write less software that does less stuff, and then spend eons honing that tiny lot. Such an approach, however, is very rarely compatible with commercial success or even programmer motivations (despite what many may claim).
How do you think the market would receive the iPhone 7, if its headline improvement was cutting 1/3 of the features to shrink the code base so it’d have fewer bugs? Yeah, I thought so. While people may get excited in concept by “stop the train, we need to fix the tracks” directives for software development, it’s not what they would buy.
Well, but then there’s the argument: Apple is so rich, can’t they just hire more developers and testers to fix all the bugs? To paraphrase Frederick Brooks: No. Software development doesn’t work like that. Throwing ever bigger teams at problems usually just makes the problems bigger still.
Bugs are an inevitable byproduct of writing software. Sure, there are all sorts of techniques and potions that promise to decrease how many of the damn critters run about, but only the comically hyperbole pretends that complete eradication is possible.
Once we accept that simple fact that software = bugs, we can progress to understand why fixing them may not even be that important a lot of the time. The absence of bugs is simply one parameter of success in software, but not even close to the most important one (with some exception for life critical systems).
Useless software can be entirely bug free, yet remain entirely useless. Useful software can be ridden with bugs, yet remain highly valuable. Or, the value of software depends far more upon the problem it solves than the quality by which it does so.
Sometimes the dichotomy isn’t that black and white, of course. You could have two pieces of software that solve the same problem, and it’s reasonable to think that the one with fewer bugs would do better. Though even that simple statement is often laughably disproven by the market. Factors such as existing adoption, integrations, brand, and fun often trump quality as well.
Given that there are so many factors more important to the future prospects of a software package and its makers, is it really that surprising not every bug gets “drop everything, we gotta fix this” priority? Of course not. But we, as users who hit a bug, still constantly pretend that it is.
It’s really the pinnacle of myopia when we as users demand and demean software makers to fix our pet bug, just because we hit it, and just because it may have caused anything from a slight annoyance to loss of some time.
The value of a any given bug can be rated by the number of users affected times the criticality of the issue. Lots of users are losing all their data due to this bug? Okay, then, Very Damn Important! Fix it NOW! Lots of users are a little annoyed or confused by this? Probably should fix it some time soon. A few users have to spend another 30 seconds on a work around? Unlikely to get fixed any time soon!
Software organizations that stay in business triage their backlog of bugs like that. They do not drop everything to deal with any damn bug. As the economies of scale kick in, so does the magnitude of consequences from such triaging. Large software packages and organizations will have hundreds if not thousands if not TENS OF THOUSANDS of open bugs of various criticality. THIS IS NORMAL. THIS IS EXPECTED.
This is not a call to give up on software quality, quite the contrary. This is a call to remove the highly charged emotional responses of encountering the world as it should be expected to spin. Demeaning developers, questioning their professionalism (whatever that means!), or feigning outrage at that which ails all software makes everyone, including users, worse off.
So next time you hit an annoying bug, give it five minutes before you fire off that indignant tweet. Marvel at the miracle it is that anything as complex as a modern piece of software works at all! Consider the billions of instructions our work-horse CPUs have to get just right for you to enjoy the splendors of computing. Have some sympathy for man and machine.
I’d like to say that Basecamp 3 doesn’t have any bugs. But it does. I’m sorry! Hopefully it provides more value than annoyance. Give it a try.
Some patterns are just about the code. If your code looks like this, and you need it to do that, here’s what to do. You’d do well to studysuchpatterns, as they give you a deep repertoire of solutions ready to apply and make your code better every time you hit their context.
Then there are other patterns that are less about the code and more about how the code is being written, by whom, and within which organization. The Majestic Monolith is one of those patterns. But before we dive into all its glory, let’s first examine its opposite pattern: Micro/services oriented architecture.
M/SOA is a prescription to break down an application into many smaller parts, run each of these parts as their own application, and then let the constellation solve the grand problem you really care about.
This is a great pattern. No, really. Not being sarcastic here. If you’re Amazon or Google or any other software organization with thousands of developers, it’s a wonderful way to parallelize opportunities for improvement. Each service can be its own team with its own timeline, staff, and objectives. It can evolve independently, at least somewhat, of whatever else the rest of the constellation is doing.
When you reach a certain scale, there simply is no other reasonable way to make coordination of effort happen. Otherwise everyone will step on each other’s feet, and you’ll have to deal with endless merge conflicts. (Well, at least in theory, I hear Facebook is having a great time with a monolith, whether it’s majestic or not is a different discussion).
In other words, M/SOA fits the organizational shape of very large corporations. So far so good!
Where things go astray is when people look at, say, Amazon or Google or whoever else might be commanding a fleet of services, and think, hey it works for The Most Successful, I’m sure it’ll work for me too. Bzzzzzzzzt!! Wrong!
The patterns that make sense for organizations orders of magnitude larger than yours, are often the exact opposite ones that’ll make sense for you. It’s the essence of cargo culting. If I dance like these behemoths, surely I too will grow into one. I’m sorry, but that’s just not how the tango goes.
This is true of not just technical patterns, but general organizational approaches too. But that you shouldn’t run HR like a 50,000-person company when you have 50 seems obvious to most though (with some exceptions).
The problem with prematurely turning your application into a range of services is chiefly that it violates the #1 rule of distribute computing: Don’t distribute your computing! At least if you can in any way avoid it.
Every time you extract a collaboration between objects to a collaboration between systems, you’re accepting a world of hurt with a myriad of liabilities and failure states. What to do when services are down, how to migrate in concert, and all the pain of running many services in the first place.
As I said, all that pain is worth it when you have no choice. But most people do have a choice, and they do have an alternative. So allow me to present just one such choice: The Majestic Monolith!
Having your system described as “monolithic” is usually a point of derision. Them be fighting words amongst many programmers! I say don’t just turn the other cheek, but embrace the monolith with pride and a salute! Don’t just accidentally waltz your system into a monolithic design, do so with intent and with your head held high. Any monolith worth erecting is worth making majestic!
So what is a majestic monolith exactly? It’s an integrated system that collapses as many unnecessary conceptual models as possible. Eliminates as much needless abstraction as you can swing a hammer at. It’s a big fat no to distributing your system lest it truly prevents you from doing what really needs to be done.
Enter the case study: Basecamp
I’ve been writing Basecamp as a majestic monolith since 2003. The latest iteration, version 3, takes this pattern to new heights and renders under its domain not just the web, but all of our native platforms as well.
Basecamp 3 is available via the web, as native mobile apps on iOS and Android, as native desktop apps on Windows and Mac, and through email as well. That’s a lot of platforms to juggle concurrently! And I believe the only possible way to do so with a small team of ~12 programmers is do explicitly choose and commit to The Majestic Monolith, in all its controversial glory.
In summary, the pressures that drove us to embrace this pattern are as follows:
Basecamp is a large application. There are literally hundreds of screens of various kinds under its domain. We have 200 controllers with a total of 900 methods! This combined with a model of 190 classes with some 1473 methods. And that’s just what’s directly inside app/*, not to talk about our front-end, like the Trix text editor.
Basecamp is a small team. As I mentioned, we have just 12 programmers, and many of those are busy keeping the systems we’ve been creating over the last decade operational. In addition, we have just 7 designers (counting Jason, my partner and our CEO).
Basecamp is available on 6 platforms: Web + iOS + Android + Mac + Windows + Email.
Basecamp has millions of users and a back catalogue of many apps we’ve committed to maintaining until The End of the Internet.
So a very broad scope, deep commitments, and a very small budget, all comparably speaking. The necessity of this situation simply isn’t compatible with a highly labour intensive pattern like M/SOA. It’s not compatible with writing 100% native apps, but it fits the hybrid application model like a glove.
In addition to these formal constraints is the mission to write beautiful, understandable, and succinct code. Code that not only makes us smile while we write it, but also when we later have to extend or patch it. Such a mission is simply not compatible with an accidental monolith. It just gotta be majestic.
One of the benefits to the majestic monolith is that it basically presumes that the people who work on it also understand it. It’s much easier to silo knowledge and responsibilities with a proliferation of smaller systems. We’ve had that happen for the few external, shared services we do have, like Basecamp ID (shared authentication for all generations of the Basecamp app). “Oh, you gotta talk to Jeff about that”.
This in turn puts immense pressure on making the application understandable and changeable by individuals, not teams. Which in turn again forces you to take the time to turn a long letter into a short one. If your standards are slipping, you’re not just pissing in your own corner, you’re pissing all over that majestic monolith we all have to polish every day. Don’t do that!
In many ways, this goes right to the essence of Ruby and Rails’ perception of programmers. That given the right incentives and nudges, most will rise to the occasion and write beautiful code. That our systems should be a red carpet invitation to become a better, more productive programmer. Who cares if those who aren’t invested in walking that path use the tools and patterns to screw themselves over? Maybe everyone needs to do that once or twice before appreciating the ropes that guides you into the gala premiere.
The Majestic Monolith doesn’t pretend to provide a failsafe architectural road to glory. That’s a fool’s errand. Many programmers suffering under many oppressive influences will turn any architecture made with any tool into a big pile of mud. So worrying too much about how to save those who’s likely out of reach anyway isn’t a productive use of energy. And it takes all the ones who do care down the wrong path.
TL;DR: Run a small team, not a tech behemoth? Embrace the monolith and make it majestic. You Deserve It!
People do crazy things when they can’t afford to lose. Being dealt a bad hand, which invariably happens at some point, becomes an existential threat, the brain shuts off rational analysis, the primal mode of survival kicks in. It’s when morals and spines are broken.
Let’s say your business is reliant on just a few big customers. Now any one of them has the power to make you sweat, or worse, by threatening to pull the plug. If you absolutely need their business, you will absolutely do what they say — even when it’s the wrong answer or direction to the overall mission. When your business has been over-tuned for these few edge cases, your dependency deepens, leaving you less open to new customers (and profits).
This is why acting on customers’ requests, rather than on their behalf, is generally a bad idea. Customers know what’s right for them, in singular. It’s your job to listen but then act on the aggregate sense of what most customers would want most of the time. That’s very hard to do if you can’t afford to say no to a single customer.
The same is true with vendors. If you’re relying on a service so much that they can dictate your existence, well, then they can dictate your existence! That’s the recurrent threat and theme of building on other people’s platforms. Or relying on a particular algorithm for search results in, say, Google. Companies make choices based on what’s right for them, not what’s right for you.
Finally, the hardest part is when this is true of employees. If your magic wizard of server mountain is a complete asshole, but only they hold the knowledge of how to keep your business in the air, whatcha gonna do? You’re going to eat their bullshit, that’s what. And that bullshit is going to seep through the whole organization until it has stained it completely.
The easiest way to get yourself out of a bad situation is to avoid it in the first place. Harder said than done, but not impossible if you maintain a healthy dose of skepticism when Golden Opportunities present themselves.
Like when that big prospective client is dangling a huge check that could grow your business by 20%, but the alarm bells are already ringing red on their list of “requests” to make that happen. Is growing by 20% in one jump worth it if it’s off the ledge?
When the vendor offers you a too-good-to-be-true deal if you’d just climb inside their fortress with towering barriers of exit, well, then maybe the power of that social graph should get another thought.
Or when that impressive candidate who’s willing to take a below-market salary radiates contempt for anyone beneath their ninja chops. Is having one superhero on the team worth a toxic environment for everyone else?
Don’t make any of your dependencies too big to fail. Whatever advantage you gain in the short term by saying yes is dread and misery later when you can’t say no.
We designed Basecamp from the beginning to capable of taking individual losses. Most customers only pay us around $50/month. We built an audience and technology base that wasn’t beholden to any existing corporate platform or vendor. Those choices are part of the reason we’re still around after 12 years.
“Just be yourself!” is commonly served as encouragement for people facing challenges in life. Whether that be in personal relationships or job hunts or speaking at a conference. If you’re already the perfect person, that’s sound advice. If not, it’s worth closer examination.
Whoever you happen to be right now, at this very moment, is highly unlikely to be the person you ultimately want to be. Maybe you occasionally have a short temper. Maybe you don’t know as much about programming or speaking at conferences as you’d like to. Maybe you procrastinate too much.
Whatever it is, you could probably stand to be more like other people in a bunch of areas. Being content merely being “you”, and whatever incremental iteration on that concept you can scrape together, is a sigh of resignation.
This is where the power of envy comes in. As emotions go, envy doesn’t exactly have much popular support. I mean, when you make it onto the list of the seven deadly sins, it’s probably best something to steer clear of, right? I say wrong.
Envy is a useful jolt of motivation to be more like someone else. Better, smarter, wiser, hell, even prettier and richer (oh, the horror 💀!). All attributes that can be refined through your own actions. You can learn new skills, you can read more, you can work out, you can save money.
I’m not the same person I was 20 years ago. Thankfully! I decided early that there was nothing so special about this happenstance of personality traits, skills, and knowledge I had acquired by age 16. Not only that, I reveled in the fact that there were lots of people that were downright better than me at all sorts of things. Things I wanted to be better at. They provided a clear template to first emulate, then adopt from. In other words, I was envious.
I remember attending JAOO 2003, a programming conference in Denmark, and seeing Kent Beck talk about Extreme Programming. Not only was the subject matter interesting, but even more so the manner Kent delivered it. I felt deeply envious at his excellent delivery and vowed to be more like Kent. To study and emulate him until I had become more Kent than me (at that time) at delivering a convincing argument on stage.
“How do you juggle it all?” is a question I’m asked regularly. Usually with an undertone that I must have some secret. A trick. Is it sleeping just 5 hours per night? Is it working 12 hour days for months on end? What is it!?!
The common lore of Highly Productive People is that they just work harder. Often superhumanly so. They have a singular focus that turns their drive to 11. The media loves to recount these feats of marvelous stamina and determination.
I don’t fit that mold. I usually sleep a good 8.5 to 9 hours every night. I take pride in making work fit the traditional 40 hour/week constraint. I have no drive for more, more, more.
If I have a trick, it’s a focus on the quality of each individual hour. That doesn’t mean Time Management, in the 1990s sense of the term, slicing each hour to the last minute, and squeezing it for every last second of peak productivity. But it does cover a realization that all hours are not created or spent equal.
An hour haunted by stress, interruption, sleep deprivation, or frazzle is not worth the sixty minutes its allotted. It’s a low quality hour. You’d be foolish to expect that you can turn such dirty input into clear accomplishments. Garbage in, garbage out.
40 hours of work every week is a king’s keep. I contend that almost anything can be accomplished with such a glorious budget. But not if you squander it on meetings, multitasking, or poorly defined problems. There’s no limit to the amount of time that can be wasted like that.
Well, there’s a physical limit. And I suppose that’s where many people find refuge. I gave it everything! You can’t blame me, and I can’t blame myself, for failing to accomplish when every second was spent. I left nothing for myself, so have mercy, they rationalize.
Covering your ass to yourself or others might give you some temporary comfort, but it won’t cover the deficit of ambition in the long run. Resignation is a coping mechanism for the beaten.
What you need is a set of refinement techniques. You need to actively work on increasing the purity and quality of your hours. Here are a few that I use:
Do I really need to be involved in this?
Gluttonous curiosity is the siren song that seeks to loop you into all manners of discussions, decisions, and events that you’re likely not a necessary or even important component.
It’s hard to accept that while your insight or experience might be useful to other people, it equally might not be nearly useful enough to offset the cost of yet another head at the table.
The value of just skimming that email, turning down that meeting invitation, not depositing your two cents in that chat seems abstract in the moment. But diligently refraining from chiming in and collaborating is what gives room for making more important progress on fewer things.
Could this wait?
Some problems need to be dealt with today, lest they compound tomorrow. Best deal with those right away. But they’re in the minority. Most problems and opportunities are just as valuably addressed a day or a week or a month from now.
Putting something on the back burner means it might well have dissipated by the time you give it a second look. Wonderful! That was work that then didn’t need to get done. Or just appeared more important than it really was when you first thought about it.
The longer you delay solving a problem, the more you’ll know about it. Lots of pains just go away by adding idle time.
Can I bail on this?
The road to a day wasted is paved with heroic attempts of throwing good hours after bad. Mistaking the depth of a problem is a reliable error of working life.
The crime comes when you continue digging after realizing the hole needed is thrice as deep as you anticipated, without confirming that the solution is also worth thrice the effort originally budgeted.
Learning to give up is a critical skill for making your remaining hours count. Sunk cost is a sucker’s bet.
Am I ready for this?
Sometimes it’s the problem that needs more time to ripen, and sometimes it’s you. We are not equally capable or fit to tackle all problems at all times.
If my head is in tune for writing this week, it’s a good time to complete the copy for the new website, but it’s probably a bad time to organize the work for the next quarter. If my fingers are itching to code, then let’s solve that bug that’s irked me for a month, not try to redirect the passion to doing 1–1 interviews that week.
Our motivations ebb and flow. Swimming with the tide instead of against it is just so much easier. And as detailed above, most things can wait until the water that needs to carry them comes back up.
Even with a strong repertoire of techniques for making each hour count for more, you will still fail regularly. Maybe all the work that needs doing this week just doesn’t include anything you can muster the motivation for. So it slides and you feel shit.
But there’s great comfort in knowing that this happens to everyone. With far more often than most are willing to admit. Despite a finely-honed perception for high quality hours, I still churn through junk frequently. Leaving me with much less than what I had hoped. So it goes!
What matters is increasing the aggregate quality of your hours over the long term. Not to stress when you fail to turn out a perfect batch.
Once you’ve built an awareness and appreciation of quality time, I doubt you’ll feel the same pull to keep chasing more, more, more. The difference between an uninterrupted string of four quality hours versus a few days of crap hours is a revelation.
Even if you squeeze and squeeze to get more hours, maybe you’ll get another 20–50%? Refine the ones you already have and you might get 200–500% more value. That’s the true 10x.
The trick to juggling it all is to stop juggling.
I spend most of my quality work hours building Basecamp. We just released a brand-new version 3, which has a special Work Can Wait feature designed specifically to increase the quality of your working hours by avoiding interruptions. Give it a try!
When Jason Fried a few months ago suggested that we should start posting articles on Medium, I was skeptical. What possible gain could we have from sharing our stories on someone else’s platform rather than our 15 year-old blog? Turns out, quite a lot!
First of all, the writing and formatting experience on Medium is just excellent. I’ve yet to find another web editor that makes it as easy to produce great looking articles. It’s just the right mix of flexibility and constraint. Writing on Medium is just beautiful.
Second, Medium has a wonderful community and readership that reaches far beyond our natural sphere of influence. Between just RECONSIDER and The day I became a millionaire, I’ve had more than 500,000 people see those articles. We just weren’t getting those numbers hosting Signal v Noise on our own island.
Third, running our own blog system is a classic case of the cobbler’s shoe syndrome. Yes, we’re well capable of technically making a great blog system, keeping it updated, and keeping the design fresh, but it falls to the bottom of the list of priorities against making Basecamp better. So we don’t, and it languishes. Why not just use something off-the-shelve that others have as their sole mission to make the best?
Fourth, Medium has listened to the concerns of publishers. By offering custom domains, we’re ensured that no permalink ever has to break, even if we leave the platform. By committing to never showing advertisement, unless the publisher consents, we can remain with Basecamp as the sole commercial sponsor of Signal v. Noise. Between these two facts, we feel confident about owning our content and our legacy, regardless of where Medium-The-$82M-VC-Funded-Company goes.
So here we are. Signal v. Noise has been around since 1999. That’s more than 15 years! We’re going for at least another 15. Please follow our publication if you care to be notified when new stories are posted (or subscribe via RSS). And if you want to follow along on Twitter, where we’ll move the shorter-form quotes, insights, and video pointers, then follow @37svn.
When our son Colt was born three years ago, I found the true purpose to why I had spent the past decade studying and practicing photography: Capturing the arc of a whole new life that I co-created.
Family photography is often relegated to the lowest rung of Serious Photography. And I get that looking at pictures of other people’s kids really isn’t all that interesting most of the time. But if it’s your kid, suddenly it’s the most important and profound subject in the whole world.
Colt just turned three, and already I have a hard time remembering the specifics of his early expressions just by digging in grey matter. But pull up a few pictures, and all of the sudden the memory is jogged, alive in the mind’s eye.
It’s the magic of photography that it can serve as key to unlock those treasures you’d otherwise struggle to access. So thank you to Canon, Fuji, and, since Colt was about 1, primarily, Leica. ❤️📷