I’ve had the opportunity to build and lead tech organizations across companies of various sizes and stages. If you have questions on scaling, management, and leadership, I can probably help.
I was interviewed by Heroku/Salesforce on engineering leadership where I talked about 4 principles I have come to rely on. Full interview and transcript here
Pragmatic engineering is when the tech you build has an oversized impact on the business. It’s about applying the right technology solution at the right time at the right cost. It’s about prioritizing practical concerns.
If you are a software engineering leader, you work within tight constraints and competition. The following principles will save you time, money, energy, and increase the probability of your organization’s success. They are in descending order of importance. Find balance among them, and apply common sense.
The Four Fs: Fast > Function > Form > Fabrication
Be fast
The #1 thing that will move the needle for most teams is a culture of speed. It spurs ownership, decisiveness, and creativity.
a. Get your work out quickly. Think fast. Be decisive and have a bias for action.
b. Get me to what I want as fast as possible. Customer’s experience should be faster than anyone else, including checkout and customer service.
c. Websites and Apps should be high-performance.
d. UX should feel fast and get out of the way.
Build impactful features
a. Build what truly matters. And nothing else.
b. Verbosity kills engagement. Balance text with imagery, when communicating with the customer, and for internal communication.
Be pleasant to use
a. Make it beautiful, but not unnecessarily. Never at the expense of the above two.
b. Less is more. Reduce cognitive load, and reduce verbiage.
Be beautiful inside.
a. The process matters. Get rid of systems that hold you back.
b. Write good, clean code. PRs should be descriptive, respecting the reviewer’s time. Smaller PRs are quicker to review, test, and push to prod.
c. Quick hacks are totally fine, but they should still have some elegance to them. Include a story in the backlog with reasoning and steps to get to a better longer-term solution.
d. Keep infra costs in mind. e. Improve tooling for everyone.
Now that you’ve got the gist, let’s go into some detail here.
Being fast is more important than adding a bunch of features. Even if your website or app doesn’t have all the features the market demands, if it’s fast at what it does have, you’re going to have happy users who keep coming back.
Make being fast a part of your team’s core values in two areas:
Any feature you decide to develop, ensure it’s performant to the level it needs to be. Study what performance level your users expect, and get specific pages as close to that as you can within a reasonable amount of effort. Check different browsers and different devices. Simulate the network bandwidth your users have. If 75% of your users are on mobile web, then that should be the team’s primary testbed, not your 28-core Mac Pro.
If the user has to wait for something that will take time, do not throw in an infinite spinner, that’s just a lazy design. Users are smart, they know latency is a fact. If you keep the user informed about what the app’s doing behind the scenes it will build engagement and create involvement.
Good enough and launched
is better than
almost perfect but still not done.
Delivery speed should be a core principle within the entire team including Engineers, PMs, UX, and DevOps. If you do this, you enable the team to develop innovative ideas that get solutions out the door faster. You enable them to explore available solutions that they could integrate with, instead of reinventing the wheel.
Teams that get in the habit of launching quickly, enjoy the satisfaction of continuously putting out things that impact the bottom line. It makes customers happy, grows the business, and develops pride.
This is the answer to the user saying, “I wish your app did this too”. Once you have a handle on performance and delivery speed, then think about which problems you want to solve for your customer base, and which you don’t.
The Right Features > Super-cool UI. If you provide the key features your users need, they will be willing to accept shortcomings in the interface. Providing the right tools and ensuring they work great (and fast) is more important than having them look pristine.
Look at
Any feature you put in is something you, and your successors, have to live with forever. It might take you only a couple of days to put something new in, but it’s now going to need love and care, forever. It’s very rare that something gets taken out. In just a couple of years, it will become a part of tech debt, legend, and legacy code, that only a select few understand. No one wants to touch it (because they don’t know what else might break). Choose carefully, what goes in, and what doesn’t.
Only when we’ve provided the right functionality, and it’s fast, do we need to look at elevating its form & feel. I appreciate a great-looking app as much as the next person, but consider these when designing:
People like products to look nice and feel nice. The most important role of design is to enhance the experience of being able to use all those amazing super-fast features the product provides. An essential aspect is to ensure your user interface is usable, which should not be sacrificed for beauty. If most people expect the “settings” icon to be on the top right, don’t put it on the top-left nav, under a sub-menu, under the user’s profile image.
Consider this feature v design trade-off:
Let’s say you have desktop users who need to select from a few options. A drop-down is a decent choice and it’s natively supported by every browser on every device. The team though cares deeply about its users and puts in a really nice-looking javascript dropdown, with icons next to the options. The new dropdown undeniably looks awesome, compared to the default <select>. It only took one additional js lib, and some custom css to put it together. Unfortunately, it has an overlooked drawback of
not working elegantly for keyboard navigation.
With the native drop-down your users would use the keyboard to rapidly select an option and move to the next step. It now takes them an extra 3 seconds because they have to take their hand off the keyboard, and navigate with the trackpad. Now the business grows and there are 100 operators in 5 warehouses who use this drop-down a 1000 times a day. Our cute drop-down has introduced a negative impact of thousands of hours on the business.
Can you calculate the dollars? We love to reuse components, imagine the same drop-down element is used 16 times across the site. Now how bad is it?
Unless there is a good reason, stick to native elements. They work everywhere, they support the differently-abled and really cost you so much less to implement. Be thoughtful when moving away from them.
Sprinkle delightful moments in the product, little animations, auto-fills, and intelligent defaults which reduce friction and demonstrate an element of empathy and fun. Make the product as design rich as you like, without sacrificing the first two principles.
Look at
BTW, if you haven’t, you really should check out Elad Gil’s
Finally, fabrication, i.e. invention and assembly. I chose this term from the terminology of semiconductor manufacturing: it’s what started the technological revolution we’re all a part of right now. Manufacturing the components on which our software runs is an incredibly intricate, carefully managed process. In the context of software engineering, it’s important to think about all the different tools and conventions it takes to put together our products.
Fabrication is about how much care and attention was put into making the bits users interact with. It’s about how Product, Design, Engineers, QA, DevOps, and Managers communicate. It’s about coding guidelines, PR quality, about how well-written a narrative doc or a README file is.
You know that if someone paid attention to the inside of the machine, it’s going to work great, for years to come. In software, this translates to thinking about how well can we make it, whether can we deliver it in time, and can others (after you) maintain it.
How we build the systems, code quality, and how we run daily tasks, matter. Craftsmanship matters*.* Think about these things and put them in a handbook for your teams.
Some things to keep in mind:
Teams that make time for being well-organized, who eliminate tech debt while balancing their regular work, who don’t panic: these people push the entire organization forward. These teams set the example for everyone else to follow. Watch out for future leaders here.
Also published here.