Open source culture and the valorization of public work
This view runs deep in open source culture, which valorizes public work even at the cost of stress and time. Open source culture on the one hand tacitly assumes that everyone has those available, and on the other hand assumes that if you don’t do public work (for whatever reason) that you are less virtuous or not virtuous at all. To be a virtuous person in open source is to contribute publicly at the cost of your time, energy, stress, and perhaps money, and to not do so is to not be virtuous (sometimes this is phrased as “not being dedicated enough”).
(Often the most virtuous public contribution is “code”, so people who don’t program are already intrinsically not entirely virtuous and lesser no matter what they do.)
Open source culture has some reason to praise and value “doing work that scales”, public work; if this work does not get done, nothing happens. But it also has a tendency to demand that everyone do it and to judge them harshly when they don’t. This is the meta-cultural issue behind things like the cultural expectations that people will file bug reports, often no matter what the bug reporting environment is like or if filing bug reports does any good (cf).
I feel that this view is dangerous for various reasons, including because it blinds people to other explanations for a lack of public contributions. If you can say “people are not contributing because they’re not virtuous” (or not dedicated, or not serious), then you don’t have to take a cold, hard look at what else might be getting in the way of contributions. Sometimes such a cold hard look might turn up rather uncomfortable things to think about.
The end of 0% interest rates: what it means for software engineering practices
Every organization that’s all-in on microservices must deal with challenging downsides. The benefits of microservices matter during hypergrowth, but not when the engineering organization stops doubling in size, annually. Then, it makes sense to consolidate services and use a more sensible services strategy.
In 2020, Uber announced a domain-oriented microservice architecture to reduce systems' complexity. This approach wrapped dozens of microservices into a single “domain,” to reduce the number of communication surfaces, while teams migrated small services into larger, “well-sized” services.
In 2022, Monzo shed light on the tooling pain of managing 2,500 services. The online bank is investing in more tooling to overcome these issues.
Monoliths can mean a safer bet when growth isn’t expected. The upsides and downsides of monolith services are the opposite to those of microservices. Monoliths do poorly when you onboard a large number of new engineers, because everyone is stepping on each other’s toes. But they work well when there’s a good rhythm of development and deployment, so long as the team doesn’t grow too fast.
Stripe is in the middle of breaking up its monolith into larger services, while elsewhere, Shopify modularized its Ruby on Rails monolith. These companies prove that starting out with a monolith, and then breaking it into smaller chunks as you grow, is a viable option during rapid growth.
I’m hearing more accounts of the pain of having too many microservices after deep cuts. A Fintech that employed 8,000 staff at its peak, including 2,000 engineers, did mass layoffs and brought headcount down to around 5,000, with engineering below 1,500.
Architecting to solve a current pain point could become more common. During times of fast growth, it makes a ton of sense to design systems for future expected loads, even if they fail to materialize.
For example, this approach was why Fast hired so many software engineers, who built state-of-the-art payments systems capable of processing billions in currency. A good part of the engineering team had built these types of systems before; including on Uber’s payments team.
Exists is the enemy of good
We’ve all heard the adage “perfect is the enemy of good”. I take this to mean: if you only accept perfect, you might miss a good-enough solution. I still try to strive for perfect, but have learned to accept that good might be sometimes enough.
However, I’ve been saying something to friends and colleagues — for probably a decade now — that is closely related: exists is the enemy of good.
This idea is pretty simple, in principle: sometimes we miss a good-enough solution because a not-quite-good-enough solution is already out there and in use.
When I came up with this, it was specifically about bad software that seems good enough. Usually, stakeholders are less willing to invest in a good solution when one already exists.
TBM 274: how capable leaders navigate uncertainty and ambiguity
Encourage New Interaction Patterns
The ability to encourage new interaction patterns within an environment rather than solely attempting to change (or remove) individuals. Help individuals connect and become exposed to new information and experiences.
Patient Divergence
The ability to encourage productive divergence and resist the urge to converge on a solution or path forward prematurely. Fostering an environment conducive to creative exploration and following multiple “threads”, allowing alignment to happen without forcing it.
Coherence vs. Alignment
The ability to seek coherence instead of alignment—setting boundaries and “no go” areas but encouraging people to explore broadly and in multiple directions simultaneously within those boundaries. Acknowledging that forced alignment is fragile, and that generally coherent actions are resilient.