SW engineering, engineering management and the business of software
One of my more recently popular twitter threads: Miscellaneous ways to Be Awesome at your job & Decision Making
I’ve had lots of chats on how to be awesome at your job recently. Much of the advice boils down to “Learn how to Learn”, and “Learn faster than everyone around you”.
Some other tactical bits around the importance of taking notes; getting/soliciting immediate feedback; finding and having good mentors; creating or seeking out safe environments; thinking critically when things go wrong (5 whys style) and decision making.
On Decision Making in particular:
You need to Understand the urgency and importance, Understand the undo cost (Type I vs Type II) and Understand the blast radius. Type I is a one-way door, high cost to undo. Type II is a two-way door. decisions that are relatively easy to reverse.
You will never have perfect information. Opportunity cost is real.
It’s not important that everyone agrees
It is important that:
Commiting to decisions you disagree with is particular important. I’ve heard this verbalized or adopted as culture with phrases such as “I can get on the bus” or “Disagree but commit”
For decisions with large undo costs and/or large blast radius, you have a repeatable, understood-by-all-parties process and the process includes documenation.
For decisions with easy undo and/or smaller blast radius, decisions are made quickly and you iterate on the early outcomes, results, new data.
Originally tweeted out here: What is Engineering Management?:
I spent a chunk of time today talking about Engineering Management. Sillicon Valley does people a disservice with the very common occurrence of battlefield promotions for eng managers.
Most of them never get trained on how to be a good manager much less have someone clearly explain the role and the expectations for the role clearly.
I roughly categorize the work/expectations into five buckets:
Bucket 1: Making people Excel. This the largest bucket comprised of 1:1s, coaching, mentoring, training, feedback, tough convos, performance evals, creating safe environments, empathetic environments, Umbrella work (shielding your people from BS), career development, etc.
Bucket 2: Prioritize, Align, Motivate. This is mostly making sure your people are pointing the the right direction. This also includes stuff that may not immediately move the bottom line, such as making sure tasks such as process, docs, automation, actually happen amid the constant pressure to ship. Lastly making sure that you have good thoughts and behaviors around decision management (see my tweets from yesterday)
Bucket 3: Business Value: This understanding the business and the metrics that drive it. both technical and biz metrics are important to track and surface. Also understanding of the product, the market and the economics of your space.
Bucket 4: Hiring/Recruiting: most engineers don’t realize that an eng manager should be spending 25-50% of their time doing this. Process, assessment, questions design, speed, candidate experience, closing, etc. The industry does this poorly in general in my opinion.
Bucket 5: Skill: You have to know what you are talking about. You have to have both the tech skill and an appropriate amount of relevant domain knowledge. It’s much much harder to be an awesome manager if you don’t know what your reports are doing, and can’t assess their ability to do their work because you lack the relevant skill set or experience.
Editors note: I originally wrote about Empathy as a Core Engineering Requirement back in 2017. This is adapted from a recent series of tweets:
People ask me why I stress Empathy as an important technical skill (esp. when it comes to recruiting). Aside from the fact that I prefer working with empathetic people and I believe to be a morally sound way to live your life, I make the argument that empathy is an important aspect of business success.
Often, the key to being successful is just getting better than everyone else around you at a faster rate. The way to do this is with the innovation loop: experiment/action → feedback → analyze → iterate → repeat (or EFAI loop for short).
You see aspects of this in obvious areas like AB testing or NPS surveys. Importantly anything you can do to increase the cycle time of that loop is critical.
The way businesses most commonly mess this up is A: skipping a step such as ignoring or not collecting feedback or gathering data but not doing any iteration (which seems silly but I see it all the time!) or B: dramatically slowing the cycle by not allowing for both outcomes of the experiment/action step.
Diving into B, almost by definition an experiment/action can succeed or fail. When you have an environment where failure is frowned upon, punished or has negative ramifications for your career, you are preventing rapid cycles by dramatically increasing friction.
This brings up the concept of psychological safety. One common way of thinking about PS is that you are creating an environment that allows failure is a safe manner. In other words, fast EFAI loops essentially require a workplace where people can fail safely. I do want to point out that this is not an excuse for recklessness or gross negligence. You can have a psychologically safe environment that also has reasonable safeguards against ridiculous extreme behavior.
So if the goal is success and rapid innovation loops drive success and rapid innovations loops require environments where you can fail safely, how to we achieve that?
Having empathy for your users, co-workers, managers, manager’s manager, your reports is an essential foundation of creating a safe environment. Empathy allows you to evaluate outcomes, especially failure, while maintaining a very healthy respect for individuals, the circumstances and context around the original experiment or action. Being able to say: “I understand that you made the best decision at the time with available information at the time” and work to resolve, mitigate and achieve better outcomes is a tremendously powerful tool
Empathy is an important technical skill as it helps create environments where ppl can fail safely which begets fast innovation loops which begets a rate of improvement that outpaces your neighbors & competitors which is strong part of repeated, outsized, successful outcomes.
One of the things I’m constantly harping on as a manager is Capturing Small Improvements. It’s a handy slogan for making compound math work for you over time.
The magic of compound interest is real. If you’ve ever been to a 401k presentation, you’ve likely heard how small growth can lead to outsized returns over time.
As a numerical example the difference between capturing a 1% improvement a day and remaining static is significant. Mathematically speaking, 1.01365 is about 37.7.
If a 40x rate of improvement isn’t enough for you, then contrast a small improvement with a small regression. The difference is stunning: 0.99365 is 0.0188. That’s a tremendously impactful three orders of magnitude.
A daily 1% improvement over the course of a year ends up two thousand times higher than a daily 1% regression.
If you are talking about spending and saving, you can measure this directly via your bank account. In terms of improving people or knowledge or process efficiency in some way, you want to make sure you build feedback loops and improvement capture mechanisms in those loops in order to achieve atypically large, positive outcomes. (Improving feeback loop cycle time by reducing friction is also critically important!)
When you are talking about certain processes, like hiring & recruiting, daily 1% isn’t practical or achievable. Yet if you could improve just 2% a week you find that you are hiring three times more efficiently. (1.0252 = 2.8)
Another example is Capturing Small Improvements in developer (or whoever) productivity via automation. Saving 10 mins a day for your developers adds up to a roughly a work week over the span of a year. If you have 50 or so developers, that 10 minutes is potentially entire year of productivity. Then imagine that there is four two six other low-hanging-fruit-type opportunities to invest in a tool, automate away or cancel a meeting or streamline some processs. Maybe there are a handful or so not-so-low-hanging or not-so-obvious opportunities as well.
This is how you drive towards and eventually achieve exponential increases in velocity. The broad lesson here is applicable for yourself as an indiviual, your team, or your company.
So yeah, Capture Small Improvements.
This post is adapted from one of my twitter threads. You should follow me there to hear stuff about Engineering, Engineering Managagement and Hiring & Recruiting Engineers.
I do want to properly credit to Paul Buchheit, who’s mathematical allegory (1.01365 vs 0.99365) I’ve reused here. I don’t know if he came up with it, but I originally heard it third-hand from him.
People ask me all the time about them and let me tell you straight away: weaponizing exploding offers as a mechanism to close candidates is a terrible practice. Don’t do this!
It’s a terrible Candidate Experience. No-one wants the hiring process to feel like being sold a used car. You are adding unnecessary pressure to a potentially life-altering choice for a candidate.
You are potentially increasing employee turnover rates. In the worst case, they may leave in less than a year and you’ve just invested a ton of talent team and departmental time & resources onboarding an employee without any of the big payout that happens in months 6-24. That represents a tremendous opportunity cost lost. Like most opportunity costs, this one doesn’t blatantly show up on balance sheets or metrics or reports or dashboards.
Furthermore, it’s irrational. Nothing about a candidate materially changes after day 7. It’s not like you hate them after a week passes. Candidates are not loaves of bread.
Let me be clear, you have to have an expiration date on the offer. It’s important from a legally-protecting-your-company point of view. I am specifically calling out the bad practice around the “you have to cancel all your current interviews and sign by Friday” high pressure nonsense.
The expiration date is largely symbolic in a market where you can’t hire people fast enough. During the offer process, I go out of the way to explain to candidates that the expiration date doesn’t mean anything and that even if it does expire, I’m happy to spin up a new offer with a new date.
There are exceptions. If there is only one open position and two or more candidates have open offers, you have to be very open and transparent about that! In some cases, you may have multiple open roles, but an equity or comp policy that means you can’t guarantee the exact numbers past the specific date. This is often the case with equity, especially if you are in process of doing/closing a fundraising round.
The thing is, the best, most capable people do intelligent things like explore their options. And you really want your employees to be good at exploring options to get to the best result rather than being easily manipulated into rushed or poor outcomes.
No manager ever thinks: “Oh I should have a team full of people that can be scammed into making rushed and possibly lousy decisions!”
If a company tries the high-pressure-cancel-your-interviews tactics it reflects quite poorly on the company and its culture. In your zeal to close the candidate you are presenting your company as the lesser option. This means that your hiring process is unintentionally biasing towards people who are susceptible to manipulation and pressure tactics.
Don’t weaponize exploding offers. It’s a lousy crutch and if you rely on it, I have serious concerns about how you treat your candidates and by proxy your employees.
You can do better!
Work with your candidates, be transparent about real, artificial or procedural deadlines. Understand your candidates needs and the risks they surface. The offer process should result in win/win; it’s not hunting. Invest in your candidate experience and invest in promoting your opportunities at all stages instead. Remember, the goal is not to put butts in seats but to find the best fits who can materially help your company succeed over the next 1-3 years or beyond.
Adapted from one of my recent twitter threads: Don’t Weaponize Exploding Offers
An earlier revision can also be found on LinkedIn:Don’t Weaponize Exploding Offers
I got a great question from @0xa38:
Do you think submitting apps online is a deadend and job applicants should always aim for referrals/reach out to recruiters first or is it company-dependent?
I love this question! The simple answer is that it is both company-dependent and role-dependent. Talent teams will always prioritize referrals and outbound candidates. It makes too much statistical sense to do otherwise. On top of this, hiring managers and recruiters aren’t good at picking resumes in general and many excellent candidates have poor resumes. Different companies have talent teams that are more or less diligent with inbound volume.
Some companies get so much inbound (candidates who apply directly to job posts via a company’s website) that there is tremendous backlog and the applications just time out. If a particular role is of particular importance, (for example, a senior security engineer), then inbound resumes get a ton of scrutiny. Entry level positions often have far more inbound than the recruiters or hiring managers can reasonably go thru.
That being said, submitting apps online is not a total waste of time. Inbound candidates have a few tricks they can pull off. First, think like a recruiter. For a high volume inbound role, they may have some hundreds of applications and resumes to screen and dozens more pouring in weekly or even daily. How do you get your resume to stand out?
Start off by assuming you are bad at making resumes. Most people are.
Be very upfront about your skills and your relative skill level. Think of this like a fantasy RPG: “Python 9⁄10, Ruby 6⁄10, MySQL 7⁄10, Postgres 5⁄10, JS 2⁄10, Java was 8⁄10 but currently rusty and would need to brush up.”
The number one thing I need to know as a technical hiring manager is your relative skill set. With the above, I have a sense of how you’d fit on a Go-project (some learning curve), or a data engineering project (prob ok), or Rails project (expect you to hit the ground running). There is so much more value to the scored skills above than a simple list: “Python, Ruby, Java, JS, MySQL, Postgres.“
If you worked on specific projects say so and say which technology you used and your specific role: “Photo sharing Mobile app, team of 3, Swift, Core Data, GraphQL. I primarily worked on image processing algorithms.“
Use design and color (this sounds cheesy but it works). Tremendously good resumes or unique ones or terrible ones are fodder for recruiter gossip: “Look at this piece of work!” Get feedback from other engineers and ideally other recruiters. If you get a call with a company, ask them what about your profile or resume stood out. Emphasize whatever that is in a future iteration of your profile/resume.
Sometimes being persistent works. As in apply to the same job in the same company every other month.
If your actual resume is weak, and companies are looking for different skill sets or more experience, then develop more skills. Launch a mobile app or play around with Django on your local machine. Products you’ve developed, and developed a market for look amazing on a resume.
Apply to jobs you may be overqualified or underqualified for (but are still in your preferred industry).
Lastly, you can use cold submission as an opportunity to refine your resume, AB testing style. Have a flashy resume? Submit it to a few places and submit your plain version to a few places. See which gets more responses. Iterate.
Job hunting can be difficult. I wish you and everyone doing so the very best.
Something I’ve had unclear thoughts about for years but only recently been put into succinct words is the programming and system design concept of “isolating complexity to one side of the seam”. In other words, keep simple at least one side of the boundary between two things (codebases, components, systems, API producers & consumers, etc.)
If you have an API or any kind of interface, You don’t want to make it difficult for developers on both sides. You want the majority of the complexity to rest on one side or the other.
The Seam Law: Isolate complexity to one side of the seam between two components
Typically this is because you have asymmetric relationship of some kind. Such as a single producer, but many consumers. By putting the burden of work on the producer side, this allows new consumers to be easily spun up and to work reliably with out a ton of learning curve.
Similarly, if there are many producers, you would typically put the burden of complexity on the consumer side. Handing all the ordering, fault tolerance, etc. on the consumer side means, you can trivially add new producers. An example here is logs or metrics aggregators.
If you have complexity on both sides, the system becomes hard to debug (defect rate and time to resolution go up). You also have extended learning curves on both sides. Here you can imaging an API server protocol that is hard to implement and requires a tremendous amount of developer skill to make use of the API payloads on the consumer side.
A typical REST API is an example of making one side easy. Relative to other technologies at the time of it’s invention, JSON-based REST APIs were originally designed to simplify client-side consumption. Contrast with SOAP, which has ridiculously complexity on both sides and didn’t last in the market.
Something like protobufs is an attempt to add a bit of tooling complexity in exchange for type safety across the seams.
If you want a particular technology to reach wide adoption, I think is is even more important. Think of how early wiki’s made publishing on the web relatively simple. USB was initially tough on manufacturers, but the consumer benefit of a single port won out. Stripe’s relatively simple-to-use API beat out not just old Wall Street behemoths, but even incumbent digital payment giants like PayPal.
Lastly, you want the complexity on the side with the fewest developers or users. Just about every successful example above (log aggregators, REST APIs, USB, etc.) follows this pattern. Make it hard for a few of your core developers so the majority of users benefit.
Regardless if you want good architectural design or need broad market adoption, you should strongly consider isolating complexity to one side of the seam.