Tag: Customer Obsession

If You Can’t Beat ‘Em

If You Can’t Beat ‘Em

I don’t have a ton of tech writers that I read regularly, but one that I do is Gergely Orosz. His newsletter, The Pragmatic Engineer, is incredible, full of insights and advice for folks at any point in their technical career journey.

A recent two-part installment discussed in detail the plusses and pitfalls of trying to measure developer productivity, a notoriously difficult problem in software engineering. It’s one I’ve been thinking quite a bit about recently, in an attempt to balance the business need to understand how much value we can deliver per dollar spent, without devolving into a joyless culture of mediocrity that treats its team like coding robots (which, it must be said, they’re not).

If you’re in the same position as me, I’d encourage you to subscribe to the newsletter and give the articles a read-through, but if you’re short on time, I absolutely love this simply-summarized single objective measure:

Weekly delivery of customer-appreciated value is the best accountability, the most aligned, the least distorting.

Yup, that sums it up. Other measures matter, but nothing beats screamingly happy stakeholders.

Withertos And Whyfors

Withertos And Whyfors

If I’ve said it once, I’ve said it a thousand times: there’s more to being a software engineer than coding. In fact, coding isn’t even the hardest part.

The point of that latter article is that AI won’t replace programmers any time soon, but not because it can’t code. Rather because it needs to know what it’s coding for, and specifying that well is what matters, whether it be a carefully constructed prompt to GPT or a detailed requirements document.

One of my favorite sayings is “It’s only software!” And I mean it, in that with enough time and money, computers can do just about anything (which is itself pretty darn cool). But no amount of software can determine what ought to be built. To do that we must apply a broader set of tools.

Just Do It

Just Do It

Don’t mean for this blog to turn into an endless stream of “gripe about all things AWS” posts, but once again today I ran into an issue that I feel the system ought to be able to figure out on my behalf.

I’m trying to deploy a CloudFormation template (which, not my favorite) in us-west-2. There’s a small bit of configuration (the WAF rules) that are globally applicable, and when not deployed in us-east-1, this causes the whole template deployment to fail (with an utter non-sequitur of an error message):

I mean, obviously that means I’m trying to deploy in an unsupported region, am I right? (eye roll)

Oh CloudFormation, why aren’t you smart enough to just apply the parts that must be global in any region? Right now you’re forcing me to either 1) deploy the whole thing in us-east-1, which I don’t want to do for locality reasons, or 2) split the template into two pieces, which adds complexity. Boo!

Amongst The Silos

Amongst The Silos

Steps I expected to take when creating an Amazon QuickSight instance and connecting it a PostgreSQL database in Amazon RDS:

  1. Write terraform to create the QuickSight instance
  2. Write terraform to create the RDS dataset
  3. Open the QuickSight console and create a dashboard using that dataset

Steps I actually had to take:

  1. Write terraform to create the QuickSight instance only to discover that creation via API is not supported in my region of choice, so had to throw it away
  2. Create the QuickSight instance manually in the console, during which I had to explicitly select that I wanted to give permissions to talk to RDS
  3. Manually edit the resultant IAM policies to include permissions to use the customer-managed keys that encrypt all our resources
  4. Apply a security group to the RDS instance that allows TCP access on port 5432 to the QuickSight public IP addresses in my chosen region
  5. Add a user to PostgreSQL specifically for QuickSight to use, one with a password hashed using an older algorithm, since the QuickSight driver uses a version that lacks support for modern (read: most secure) algorithms
  6. Grant permissions for this user to be able to read the schemas and tables that hold the data I want to visualize
  7. Create the RDS dataset in QuickSight, manually entering the connection details
  8. Create a dashboard using the above dataset

Figuring out a number of the above steps required decoding unhelpful errors, searching through pages of documentation, and other non-trivial efforts. For shame, Amazon, for shame. Y’all should talk to each other more.

It Figures

It Figures

Since becoming a CTO, I’ve had a major uptick in spam, everything from thinly veiled LinkedIn connection requests to blatant direct emails. This one was particularly funny:

Oh Brian, you have a delightful sense of irony. Your products probably won’t solve my unwanted solicitation problem, but your marketing attempt did bring a smile to my face, and for that I thank you. Now go away.

Eye Of The Beholder

Eye Of The Beholder

In My 20 Year Career Is Technical Debt, the author outlines how most everything he’s worked on is eventually deprecated and replaced. It’s a hazard of technical work, where new approaches, frameworks, and solutions are being invented regularly. We’re not building cathedrals that will still be standing five-hundred years from now. At least not in the sense that the stuff of our creation, the ones and zeros, are still going be on a storage medium and flowing through a CPU long into the future (with some rare exceptions).

But that’s not the point. What you build doesn’t matter, it’s all going to end up technical debt (if you’re lucky) or deleted (if you’re not). What matters is the outcomes enabled by what you’ve created, and the relationships you’ve developed along the way. If your code plays a part in improving people’s lives for some period of time, then it’s done its job. And if those around you are better for having collaborated on it, you’ve done yours.

That’s all we can ask for. And it’s enough.

Little Light Of Mine

Little Light Of Mine

Klaus Teuber died this week. His career began in dental hygiene, but by its end he’d designed one of the world’s most influential board games, The Settlers of Catan. I learned it about 20 years ago from a college buddy, and right away fell in love with its balance of strategy and luck. Enough of the former to make it interesting, enough of the latter to appeal to a broad audience. It also requires deft handling of social dynamics through alliances, trades, and the occasional threat.

It’s hard to overstate the influence this game has had on my life. Quick games of Catan formed early bonds between myself and my wife during the stress of having young kids. When we moved to San Diego it was a vehicle to make new friends in an unfamiliar area. And it’s been a staple of family game night since my children were in middle school (I still remember exactly where we were when we taught them to play for the first time). The above photo is from a game played just last night (I’m green, and I won with 4 cities and longest road).

I once read that a typical person will have a direct influence on 10,000 others over the course of a lifetime. No idea if that’s true (or what “typical person” could even mean), but the point remains that whatever influence we each have, it’s likely larger than we think. Certainly Klaus Teuber had no idea that his game would affect me and my family so positively. But I’m thankful nonetheless.

When I die, it won’t really matter what systems or organizations I’ve built, but it will matter how those systems and organizations have influenced the people involved, and promoted human flourishing more broadly. My tools are technology, but they’re not the goal.

Spirit And Truth

Spirit And Truth

As I was reading Things they didn’t teach you about Software Engineering, I found myself frequently nodding along. There’s a fountain of wisdom here. Seriously, go read it, or at least go read the headers, which are helpfully summarized along the side of the page.

One worth a deeper dive is this: domain knowledge is more important than your coding skills. I cannot agree more. If you don’t know your customer, it’s unlikely anything you build will add value, no matter how perfectly it’s constructed. And given that the typical end-user is rarely going to be a developer themselves, this knowledge won’t come automatically. It needs to be pursued intentionally.

I’ll go even further, though: knowledge isn’t enough. When the going gets tough (and it will, because programming is hard), a team needs more than information about their customers to keep them moving forward. They need an emotion powerful enough to overcome diverse roadblocks. They need empathy.

The best engineers don’t just seek to know about the problems they’re solving. They internalize those problems, engaging their emotions alongside their intellect. When a customer has a challenge, they feel it in their bones (it’s not by accident that we use the metaphor of a “pain point” when describing problems). When a customer is angry at a missed deadline or poor quality outcome, they lean in, acknowledging failure. And when a customer is overjoyed at the success of a new product launch, they get to share in that happiness.

Empathy is the key that unlocks the willpower to achieve great things. Regardless of technical prowess, show me an empathetic developer, and I’ll show you a good one.

Sean Maguire Was Right

Sean Maguire Was Right

Don Norman came to mind today, a not uncommon occurrance. I’ve mentioned him before, but not loudly enough. If you care at all about building great solutions, technical or otherwise, reading The Design of Everyday Things is a must. Here’s my favorite passage:

The idea that a person is at fault when something goes wrong is deeply entrenched in society. That’s why we blame others and even ourselves. Unfortunately, the idea that a person is at fault is imbedded in the legal system. When major accidents occur, official courts of inquiry are set up to assess the blame. More and more often the blame is attributed to “human error.” The person involved can be fined, punished, or fired. Maybe training procedures are revised. The law rests comfortably. But in my experience, human error usually is a result of poor design: it should be called system error. Humans err continually; it is an intrinsic part of our nature. System design should take this into account. Pinning the blame on the person may be a comfortable way to proceed, but why was the system ever designed so that a single act by a single person could cause calamity? Worse, blaming the person without fixing the root, underlying cause does not fix the problem: the same error is likely to be repeated by someone else.

The notion of system error is quite profound, applicable to technology, organizations, governments, even entire civilizations. Leaders of all stripes do well to consider its explanatory power.

Just discovered that Don has a new book coming next month: Design For a Better World. Pre-ordered!

That Last 20%

That Last 20%

I got an email this morning from a reader who asked if I had an email subscription feature on this blog. I didn’t then, but now I do! Want my writing to hit your inbox the moment I publish? Just add your email address into the widget at the top of the sidebar and hit subscribe. Easy!

You know what wasn’t easy? Trying to get that widget to match the rest of the site. At first it looked like this:

Gross. Luckily WordPress supports adding custom CSS. Unluckily, that means I had to fiddle with CSS, which is a special form of hell. I couldn’t get it perfect on all browsers, but it’s not bad now:

While I was at it, I made a few other visual tweaks to the site, primarily shrinking the masthead height, which has always bugged me. Here’s the final code snippet. Not the prettiest, especially with all those !important keywords (generally they’re a smell that your CSS is too complex), but it gets the job done.

.navbar {
    display: none;
}

.site-header {
    height: 300px;
    min-height: 300px;
}

.site-title::after {
    margin-top: 0.5em !important;
    margin: auto;
}

button.wp-block-button__link {
    height: 34px !important;
    margin-left: 0px !important;
    padding: 0px 5px !important;
    background: #fab526;
    font-weight: bold;
}

input#subscribe-field-1 {
    padding: 5px !important;
    border-bottom: 2px solid #ddd !important;
}

.search-field::placeholder {
    color: #B9B9B9;
}

If you happen to notice any weirdness on your device/browser of choice, do let me know, eh?