<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[The ZBook]]></title><description><![CDATA[Founder and CEO of [Warp](https://warp.dev), where we are building a modern Rust-based terminal.
Prev: Principal Eng at Google Docs, Interim CTO at TIME, Co-fou]]></description><link>https://thezbook.com</link><generator>RSS for Node</generator><lastBuildDate>Wed, 22 Apr 2026 08:56:36 GMT</lastBuildDate><atom:link href="https://thezbook.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Ask & Adjust: The Future of Productivity Interfaces]]></title><description><![CDATA[This article describes my best guess of how productivity apps will work in a future where Generative AI is everywhere. I’m writing this from the perspective of someone who is currently building a productivity app, so it’s been on my mind a lot lately...]]></description><link>https://thezbook.com/ask-adjust-the-future-of-productivity-interfaces</link><guid isPermaLink="true">https://thezbook.com/ask-adjust-the-future-of-productivity-interfaces</guid><category><![CDATA[AI]]></category><category><![CDATA[terminal]]></category><category><![CDATA[Productivity]]></category><category><![CDATA[Rust]]></category><dc:creator><![CDATA[Zach Lloyd]]></dc:creator><pubDate>Wed, 12 Apr 2023 23:07:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1683672921414/c19aeead-58f9-4362-a4c4-e856dba910c8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This article describes my best guess of how productivity apps will work in a future where Generative AI is everywhere. I’m writing this from the perspective of someone who is currently building a <a target="_blank" href="http://www.warp.dev/">productivity app</a>, so it’s been on my mind a lot lately.</p>
<p>‍By productivity apps, I mean things like Figma, Google Docs, VSCode, Notion - basically any software where knowledge workers spend their days writing, designing, coding, analyzing, etc<a target="_blank" href="https://www.warp.dev/blog/ask-adjust-the-future-of-productivity-interfaces#footnote-one"><sup>1</sup></a> I’m particularly interested in “horizontal” productivity apps - ones used to produce a wide variety of artifacts or accomplish lots of different tasks, rather than very narrow ones (e.g. an app that just creates marketing blogs). Finally, I’m discussing AI in professional tools, not consumer apps, where I think the path will be different.</p>
<p>In case you don’t have time to read the entire piece, the tl;dr is that I believe we are moving to an AI-first world in productivity, but, importantly, not an AI-only world.  I think the main paradigm in horizontal productivity apps is going to be <em>Ask &amp; Adjust</em>: AIs will iteratively generate drafts or edits, and humans will hand-tweak them until they are right. I believe the closer the application is to one where “creative-license” is allowed (e.g. image creation or marketing copy), the less important these hand-editing interfaces will be; however for activities like coding where it’s very hard to express your intent exactly to an AI, the hand-editing interfaces, along with collaborative re-use, will remain crucial.</p>
<h2 id="heading-before-generative-ai-apps-optimized-for-hand-editing"><em>Before Generative AI: apps optimized for hand-editing</em></h2>
<p>Before I get to Generative AI, it’s worth quickly describing how productivity apps have evolved over the years.  Traditionally, the paradigm for creation in productivity apps has been pretty simple: the author uses the tool to create, edit, and share their work. I mean “author” here in a broad sense – in Figma the author is a designer, in VSCode it’s a developer, in GDocs it’s a literal author, in Webflow it’s a website creator.  </p>
<p>Because the author has always been a human, these productivity tools are heavily optimized for a human-driven creation experience (obviously). I think of  them being optimized for <em>hand-editing</em> - the apps that provide the best experiences are ones that have the most powerful, intuitive and efficient knobs and dials for humans to create artifacts or accomplish tasks.  </p>
<p>In VSCode, this means a convenient UI for comprehending and editing code (e.g. multi-cursor, jump to definition, etc). In Notion it’s a great interface for dealing with structured and semi-structured data.  In Webflow it’s a fast way of editing websites, etc. A lot of work has gone into improving these hand-editing interfaces over the years and, from the perspective of app builders, it’s super-important to get them right.‍</p>
<h3 id="heading-collaborative-building-blocks-shared-templates-libraries-and-scripts"><em>Collaborative building blocks: shared templates, libraries and scripts</em></h3>
<p>In addition to optimized hand-editing, much innovation in productivity apps lately has come from collaboration and re-use features. These features allow users to use the work of others (either their teammates or the community) as a starting point, and to easily share whatever you create for others to browse and re-use. Shared templates, libraries, and scripts – along with real-time “create together” flows<a target="_blank" href="https://www.warp.dev/blog/ask-adjust-the-future-of-productivity-interfaces#footnote-two"><sup>2</sup></a> are all examples of collaborative building blocks improving productivity interfaces.</p>
<p><em>Templates,</em> for instance, are a way of bootstrapping the creative process by starting from a premade “thing” (e.g. a company’s template presentation, or something more task specific like a “todo list” template in a spreadsheet, or a marketing site template on Webflow). Templates come in many forms — GitHub Codespaces is basically a fancy template mechanism for development environments.</p>
<p><em>Libraries</em>, like Figma components for designers or open source repos for devs, allow reuse of “pieces” of prebuilt functionality, saving time and increasing consistency.  Libraries are everywhere these days and are probably the most important collaborative building block.</p>
<p><em>Scripts</em> and <em>macros</em> simulate human interaction with the interface to make accomplishing a task easier – you “record” or write what actions you want, possibly parameterized, and then have the ability to rerun them later.  The closer you get to developer tools, the more frequently you see scripting and macros (e.g. in spreadsheets and command-line tools).</p>
<p>The rise of cloud-based collaboration has made <em>sharing</em> all of these things – templates, libraries, scripts, and finished artifacts – drastically easier in the last 15 years.  Native sharing and storage has also created network effects around certain tools, which is why a few cloud native apps like Figma and Github have won in their spaces.</p>
<p>However, even with all of these shared building blocks the important thing to realize is that at some point human authors (either individually or jointly) are responsible for the bulk of the creation in today’s productivity apps.  Humans sitting behind keyboards hand-edit and stitch everything together. In a world with Generative AI, this is about to change.</p>
<p>Today’s creation loop looks something like:</p>
<p><img src="https://storage.googleapis.com/warpdotdev-content/blog-ask_and_adjust-asset_01-2023-04-12.png" alt /></p>
<h3 id="heading-from-hand-editing-and-collaborative-building-blocks-to-ask-amp-adjust"><em>From hand-editing and collaborative building blocks to “ask &amp; adjust”</em>‍</h3>
<p>Productivity apps will be much different in a world with Generative AI.  My belief is that rather than hand-editing and collaborative re-use being the primary workflows for authors, the primary workflow is going to be <em>ask and adjust</em>.</p>
<p>In an <em>ask and adjust</em> world the human asks an AI within the app for help creating or editing something, and the AI provides a draft or revision.  This asking could be explicit (e.g. through a chat interface) or implicit (e.g. through an autocompletion interface) but the net result is the same: the AI suggests something that looks like fully formed content. I believe the “asking” will still happen within vertical productivity apps rather than being part of some “uber” AI creation interface because (as I’ll discuss below) I don’t see the hand-editing part of these interfaces going away anytime soon.</p>
<p>For example, in Webflow, rather than starting from scratch, users will ask for a “marketing website that features X images and shows the brand in a whimsical tone” and Webflow will generate a custom starting point – a bespoke template.  For product designs, users will ask Figma to adjust their component library to have “a more futuristic style” and the app will oblige.  And so on - anyone who has spent time in ChatGPT or Dall-E or similar will get the idea.  This technology is about to be in every productivity app.</p>
<p>However, it’s important to point out that the <em>ask</em> phase will usually not generate finished products. Instead, the AI will take a stab and give users a draft. The draft might be 80% of the way there. It might be 50%. In some cases this draft could actually be perfect; e.g when I use GitHub Copilot, the suggestion captures my intent perfectly something like 30% of the time. But I think perfection is the exception not the rule.  Users will usually have to tweak the draft by iteratively changing the AI prompt. </p>
<p>The reason these drafts will usually not be perfect is that for a lot of creative pursuits the human author doesn’t know what perfect actually looks like when they ask for help. There are two issues: one, humans are not able to perfectly express their intents; so even if the AI was a perfect translator of stated intent into form it would still be wrong a lot of the time.  Secondly, creation is an inherently iterative process where intent is often discovered as you draft and edit.</p>
<p>That said, even when the AI doesn’t perfectly nail it, there’s still a tremendous amount of value in how much time it saves and how far it can get you, which is why AI will be a core part of every productivity interface. For people who can’t illustrate or design websites or compose music it may even be that the draft makes the impossible possible - taking you from something you could never do to something that’s pretty good. </p>
<p>The interfaces for the <em>ask</em> phase are still being worked out, but the ones folks have started with are autosuggestions and chat. This will evolve towards deeper integrations and the apps that can most seamlessly integrate the AI into the creation experience will have an advantage. E.g. Imagine an AI “collaborator” in this GDoc I’m in right now suggesting improvements as I go, or an AI “co-designer” who cleans up your Figma designs as you make them.</p>
<h3 id="heading-the-adjust-phase-what-will-the-interface-look-like"><em>The adjust phase - what will the interface look like?</em></h3>
<p>However, for most productivity apps, my prediction is that the <em>ask</em> phase will not be the end of the story.  Instead the <em>ask</em> phase is going to need to be followed by an <em>adjust</em> phase where the human author hand-tweaks the output to match their intent.  </p>
<p>For <em>ask &amp; adjust</em>, the creation loop will look something like:</p>
<p><img src="https://storage.googleapis.com/warpdotdev-content/blog-ask_and_adjust-asset_02-2023-04-12.png" alt /></p>
<p>‍Before diving into the details of the <em>adjust</em> phase, some readers may question whether a hand-adjustment phase is going to be necessary at all.  For example, using a tool like Midjourney, you can generate and iterate on images in Discord using just text based prompts and simple buttons to get variations.  There is no complex interface to learn and no hand-tweaking UI.  Why can’t all productivity interfaces work this way?</p>
<p>‍Let’s briefly imagine that they can. In such a world, you wouldn’t actually need tools like Figma or Webflow or VSCode with all of their fancy controls and dials – this would be a world where successive prompting of the AI would be enough to get you to the perfect result.  </p>
<p>‍A user would ask for a design or website or app and a draft would appear fully formed.  To the extent that thing wasn’t “right” the user would ask the AI for revisions until it was good enough, thereby removing the requirement to ever learn any of the harder parts of these tools’ interfaces (or learn how to “truly” design or code for that matter).</p>
<p>‍And beyond obviating these interfaces you can imagine a world without the need for the intermediate data models that these tools operate on.  If AI perfectly generates computer programs, is there an advantage to it generating something human readable?  Why generate javascript when web assembly is faster?  Why generate design files when you can generate the interface they describe directly?</p>
<p>‍Despite the rapid improvements in AI, I don’t think we are actually close to this world, at least not for professional apps. I say this not because I understand generative AI technology very deeply or because I don’t believe in the high rate of progress of AI (I do). Instead I say it because I believe there are inherent limitations in <em>humans</em>: often the gap in going from a person’s <em>expressed intent</em> to the final product using just natural language is too big. </p>
<p>‍Put another way, for the applications I’m talking about (VSCode, Figma, Webflow, Notion, Warp and the like) we are often unable to express our intentions to AI precisely enough for an AI to get it completely right, even through repeated prompting. </p>
<p>‍Of course it’s not just a single user’s prompt that is informing the result but the entire trained data set - but still I believe for a lot of applications that at some point users will need to refine their intents at a more fine-grained level, by actually writing code or altering vectors or writing characters using a purpose built tool<a target="_blank" href="https://www.warp.dev/blog/ask-adjust-the-future-of-productivity-interfaces#footnote-three"><sup>3</sup></a>. After some amount of AI-assisted iteration, manual tweaking will actually be a more efficient way of getting the result they want. They will also (at least for now) want to understand the result and verify the AIs suggestions are correct.</p>
<h3 id="heading-creative-license-vs-precise-requirements-how-important-is-the-adjust-phase"><em>Creative-license vs. precise requirements: how important is the adjust phase?</em></h3>
<p>‍To be clear, I don’t think this is true for every kind of app.  I think it’s very much an application- or domain-specific challenge.  In general, the closer the domain is to one where there are a broad range of acceptable creative outcomes – where there is “creative license” – the less manual adjustment will be needed.  That means for image creation, music creation, marketing pabulum AI is going to be able to get you pretty much all the way there.</p>
<p><img src="https://storage.googleapis.com/warpdotdev-content/blog-ask_and_adjust-asset_03-2023-04-12.png" alt /></p>
<p>‍These outputs don’t need to be perfect – they can be good enough.‍</p>
<p>On the flip side, for domains where there is one correct outcome that has to be precisely implemented – and I would put coding and most developer activities in this camp – you are going to need adjustment UIs. For coding in particular, I think AI will have a huge impact, but it will be in streamlining the process, not writing the entire app for you without you seeing or editing any code. </p>
<p>The reason I think this is that the hard part of coding has always been humans getting clear on how they want a thing to work and then presenting this to a machine for execution.  This is why we write code in programming language rather than natural language; programming language is an extension of formal logic and lets humans express with exactitude what they want done.  </p>
<p>For most coding applications this really matters – e.g. login flows need to be implemented in an exact way; so does most business logic in my experience.  It’s not an area where creative license really applies, and so an 80% right solution will not work.  You generally don’t have to fix bugs in images or marketing copy – you do in code, and that’s usually because humans can’t express (or often even fully understand) how their system needs to work. The “working” program is the only complete specification of the system typically – tests can verify parts of it, but not define the whole thing.   I don’t see how AI helps with this fundamental problem.</p>
<p>For instance I’ve frequently been trying to imagine AI writing the app I’m currently building – Warp.  It’s very easy to imagine an AI writing small parts of it: e.g. write me a function for storing this terminal output block on the server.  But for the more novel parts – - e.g. write me a block based terminal emulator with a modern text editor as its input – I can’t imagine an AI producing working code for them because I don’t even fully understand how they should work. </p>
<p>This leads me to believe that hand-adjustment in our productivity apps is not going away anytime soon. I think the much more likely flow in the next five years is that the AI helps generate and edit drafts, but then there is a “fallback UI” that the human uses to finish the process.  This fallback UI is what we think of today as the primary UI in most of our productivity apps, but as the AI gets better and better, we will need to use that UI less and less. </p>
<p>Likewise, I don’t see collaborative re-use going away – it’s just too valuable to be able to reuse standard components, even if you have AI helping you along the way. The value is not just in time savings but also in consistency and maintainability and knowledge-sharing. </p>
<p>My guess is that the best AIs will understand which shared templates, scripts, and components exist and suggest using them – eventually the AIs will be able to create and share and surface these components themselves<a target="_blank" href="https://www.warp.dev/blog/ask-adjust-the-future-of-productivity-interfaces#footnote-four"><sup>4</sup></a></p>
<h3 id="heading-what-does-all-this-mean-for-creators-of-productivity-apps"><em>What does all this mean for creators of productivity apps?</em></h3>
<p>First off, authors of apps should figure out where they sit on the spectrum of needing an adjustment UI - the more creative license there is, the less adjustment needed (and vice versa).</p>
<p>If your app does need an adjustment UI, you should think of AI today not as a replacement for the core interface, but as a way of more quickly, efficiently and intuitively generating drafts and edits within that interface. </p>
<p>For these apps, it means that the primary interfaces of today will likely become fallback interfaces tomorrow.  </p>
<p>It means that if you are starting a new company building a “horizontal” productivity app, it’s risky to ignore the primary interface and try to skip directly to an AI-only interface.</p>
<p>It means that we should expect primary interfaces to become simpler and more hidden, and that AI will increasingly be a universal interface present in all productivity apps.</p>
<p>It means that collaborative re-use will remain an important part of the creation process, but one that is aided by AI.</p>
<p>In summary, the apps best positioned to succeed in this world are ones that add AI seamlessly to the creation and editing process, but still have UIs for hand-tweaking and collaboration that humans can efficiently use to get to the end results they want.   </p>
<p>That’s my take at least. I’d love to know what you all think.</p>
<hr />
<p><sup>1 </sup> <sub>These changes are already happening at a high rate (e.g. the launches of “insert product name AI” that are happening every day). I’m more documenting this as a way of talking about the changes and trying to give them names rather than pointing out something totally novel.</sub></p>
<p><sup>2 </sup> <sub>These apps also greatly improve consumption and knowledge sharing by centralizing access to a team’s stuff – there are a lot of benefits to cloud native collaboration.</sub></p>
<p><sup>3 </sup> <sub>Can you imagine for instance an AI generating text without it going into a text editor? Maybe for very niche use cases, but in general the AI will participate in drafting but not obviate the need for the editing tool itself.</sub></p>
<p><sup>4 </sup> <sub>As an aside, one of the issues with Github Copilot right now is that by always generating raw code it creates more code than is necessary; it bloats the codebase and creates duplicate code fragments. I suspect this will change and going forward Copilot will be able to suggest decompositions and create reusable libraries for you.</sub></p>
]]></content:encoded></item><item><title><![CDATA[Why is it taking so long for cloud dev environments to catch on?]]></title><description><![CDATA[tl;dr
One of Warp’s investors asked for my thoughts on the cloud development environment space.  It was a fun question to think about (and is relevant to Warp as well), so I wrote up my thoughts.  I could be totally off, but thought it would be fun t...]]></description><link>https://thezbook.com/why-is-it-taking-so-long-for-cloud-dev-environments-to-catch-on</link><guid isPermaLink="true">https://thezbook.com/why-is-it-taking-so-long-for-cloud-dev-environments-to-catch-on</guid><category><![CDATA[Cloud]]></category><category><![CDATA[IDEs]]></category><category><![CDATA[Developer]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Rust]]></category><dc:creator><![CDATA[Zach Lloyd]]></dc:creator><pubDate>Tue, 20 Sep 2022 22:50:41 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1683672537509/9430011c-3ee4-44bb-bd09-dc2d220ba7de.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>tl;dr</strong></p>
<p>One of Warp’s investors asked for my thoughts on the cloud development environment space.  It was a fun question to think about (and is relevant to Warp as well), so I wrote up my thoughts.  I could be totally off, but thought it would be fun to share them for feedback.  ‍</p>
<p>The high-level summary is that I think that development environments will eventually move to the cloud, but the incentives aren’t as strong as they are in other domains.  I think top-down adoption is more likely than bottom-up in this case, but it will depend on the stack and developer segment, and take a longish time.</p>
<p><strong>–</strong></p>
<p>I remember the first time I used a Google Sheet in 2006 where there were multiple collaborators moving around its cells in real-time.  The experience was magical, and it was pretty obvious that it represented the future of how document collaboration would work.  Everything would be shared via link, with one cloud-based source of truth that multiple people could work on together.  </p>
<p>Fast-forward 16 years (eight of which I happened to spend helping build the current version of Google Sheets), and numerous other products have made the same transition from local, single-user desktop software to cloud-based collaboration.  The transition of design software from Sketch to Figma is a good example.  </p>
<p>‍However, there has been one very notable exception to the general trend – the primary tools that developers use to write and run code. The code editor and the terminal, two tools that literally every developer uses every day – have both been very slow to make the transition off of said developers’ laptops and into the cloud. Why is that?  </p>
<p>This post explores why what seems at first to be such an obvious evolution is actually much harder than it seems.  I believe we will eventually write most of our code in the cloud, but I think it will be a slow, uneven transition. Certain segments of developers and stacks will move to the cloud before others and it will take a long time for everyone to get there.</p>
<p>First though - what does it even mean for developer tools to move to the cloud?  It could mean a couple different things:</p>
<ul>
<li><p>A full IDE in the browser (e.g. GitHub Codespaces) which integrates the code editor + terminal + execution environment that is running on some cloud machine.</p>
</li>
<li><p>A “DevBox” in the cloud that is the “runtime” for the dev environment – it has the source code, build tools, and so on, but it’s up to the developer how they connect to that DevBox, edit files, run builds, etc. They could connect through a browser based IDE or terminal or they could run a native app that “remotes” into the box as though it’s a local file system.</p>
</li>
</ul>
<p>Of the two ways of doing remote dev (IDE in the browser or DevBox), there are tradeoffs amongst the two.</p>
<p>The IDE in the browser has the advantage of not requiring any setup, installation, etc.  It’s great for getting going quickly on new projects.  </p>
<p>But to the extent that it requires an entire team to use the same code editor, it’s problematic.  Even though VSCode has a big market share, a lot of devs still prefer other editors like jetbrains or terminal editors like vim.  Sometimes you need to use a different editor because of the type of work you are doing (e.g. xcode / android studio).</p>
<p>Whatever the specifics end up being, the advantages of a cloud setup are pretty clear:‍</p>
<ul>
<li><p>The environment is accessible from anywhere via the internet, not just whatever laptop you set it up on</p>
</li>
<li><p>You can have a powerful machine in the cloud (that possibly you pay for only when using it).  Consequently, devs can get cheaper laptops and speed up build times</p>
</li>
<li><p>Cloud hosting makes real time collaboration easier if you ever want to do simultaneous pair programming</p>
</li>
<li><p>Cloud hosting makes it necessary to have a (mostly) hermetic dev environment, which is a good thing</p>
</li>
<li><p>More secure in theory because source code is not on your laptop</p>
</li>
</ul>
<p>Conversely, remote development comes with some inherent challenges to overcome:</p>
<ul>
<li><p>Latency, in all possible ways: both in terms of spinning up the environment, and actually working in it (especially via approach #1 above)</p>
</li>
<li><p>Lack of offline access - devs like working on their laptops and don’t like being unable to code when there’s no internet</p>
</li>
<li><p>Complexity of different local setups that need to be emulated in the cloud - i.e. where do all of your microservies run, how are all of their endpoints configured, etc.</p>
</li>
<li><p>Complexity of using all your devtools in a remote env (everything is harder when you aren’t on your own machine and have to connect over the network)</p>
</li>
</ul>
<p>Notably, the biggest single advantage that an app like Google Sheets brings to the knowledge worker – solving version skew and creating a system of record – isn’t really an incentive for development environments to make the cloud transition.  </p>
<p>Before apps like GDocs and GSheets, knowledge workers were constantly in the situation of sending around document attachments via email that were actually multiple versions of what conceptually was one document (think back to when you would “Save As…” and give your file a new name like important_doc_zach_1.xlx and your colleague would send you important_doc_lucy_2.xlx and so on).  This caused a ton of wasted time and headache merging changes. </p>
<p>Avoiding version skew by having only one canonical version of the document is the killer collaborative feature of all of the online document editors, more so than even any of the flashier realtime features like multiple cursors.</p>
<p>Developers, however, solved the version skew problem years ago using a very different approach – distributed source control systems like git (and cvs, perforce, svn, mercurial etc). These systems obviate a lot of the benefit of multi-player cloud editing because they allow for asynchronous local change management in a way that never existed for an excel spreadsheet.  </p>
<p>Plus, because developers typically work on text files (rather than binary document formats), merging changes is doable manually, even if it’s sometimes annoying.  </p>
<p>Finally, this type of control is actually needed for source code – you need to be able to track every single change, merge, rebase, etc, whereas for spreadsheets the “always at head” model is generally good enough.</p>
<h2 id="heading-individual-developers-whats-the-pull-to-remote-dev">Individual developers – what’s the pull to remote dev?</h2>
<p>The existence of distributed version control makes the pull of remote dev environments much less strong than it otherwise would be.  Without the “system of record” advantage, I’d contend that the pull of remote development <strong><em>to an individual developer</em></strong> simply isn’t that strong.  ‍</p>
<p>As an individual dev, here are some of the other reasons I might want to work in the cloud:</p>
<ul>
<li><strong><em>Hermetic dev envs</em>:</strong> Having hermetic, shareable dev envs is probably the strongest pull, as it’s very annoying to have to deal with the class of bugs that arises from development environments being different across developers A and B, and also from local to production. That said, doing remote development simply doesn’t solve the hermetic dev env problem.</li>
</ul>
<ul>
<li>Developers today tend to have dependencies on cloud-hosted services and APIs that can’t be made hermetic no matter where your dev env is hosted (e.g. how do you make a hermetic dev env if you’re calling out to something like the Twitter API)</li>
</ul>
<ul>
<li><p>Docker != hermetic – you get something that is hermetic across one VM, but most apps have lots of external deps, microservices, data dependencies, etc</p>
</li>
<li><p><strong><em>Faster builds</em>:</strong> could be a big pull on larger projects.  However to really do fast builds, you end up needing to shard and cache them via something like bazel and that’s not really incompatible with doing your code editing locally - this is how it worked at Google when I was there.</p>
</li>
<li><p>Real-time collab / pair programming: could be a pull, but doesn’t actually require remote hosting (you can use something like ngrok or tandem), and also really isn’t that common in my experience – it’s hard for me to imagine this being the primary driver.</p>
</li>
</ul>
<p>On the flip side, as a developer, I’m worried that the move to remote</p>
<ul>
<li><p>Will introduce latency</p>
</li>
<li><p>Will make it so I can’t work unless I have fast internet</p>
</li>
<li><p>Will make it harder to use my existing toolset</p>
</li>
<li><p>Will require some big migration to make my existing project build</p>
</li>
<li><p>And sometimes it just won’t be possible at all, say if you are doing any kind of native or mobile development (using xcode, etc)</p>
</li>
</ul>
<p>‍As an aside, at Warp, there are a lot of things we talk about with respect to improving engineering productivity, but moving our env from local to the cloud never comes up (in fairness though, we are building a native Rust app).‍</p>
<h2 id="heading-top-down-company-adoption-has-a-stronger-pull">Top-down company adoption has a stronger pull</h2>
<p>The other way the migration to remote dev could conceivably happen is from a top-down company mandate, rather than from developers choosing individually that remote dev improves their experience.  I believe this is how GitHub rolled out Codespaces internally.</p>
<p>‍However, this comes with its own set of challenges.  ‍</p>
<ul>
<li><p>If the rollout is to some version of VSCode in the cloud, there is likely to be pushback because devs use different editors (e.g. vim, jetbrains, etc) and generally don’t like to be told to switch (you can take a big productivity hit).  </p>
</li>
<li><p>Some setups are going to be hard to impossible to do remote (e.g. mobile / native / embedded systems)</p>
</li>
</ul>
<p>That said, I think the top-down approach is actually most likely because the benefit is potentially stronger for a company than an individual:</p>
<ul>
<li><p>Could save companies money to cloud host vs. buying everyone an expensive machine</p>
</li>
<li><p>Could be a significant security win not to have code on personal machines</p>
</li>
<li><p>Could be much easier to onboard / offboard engineers and work with external vendors</p>
</li>
</ul>
<p>So I could imagine a CTO saying, “we are all switching to dev in the cloud – it may be a pain to start, but the long-term benefits to the company are worth it.”</p>
<p>My best-guess at how the transition will happen:</p>
<ul>
<li><p>Remote dev shift will continue to happen gradually, not all at once</p>
</li>
<li><p>Remote dev will happen in a lot of different ways</p>
<ul>
<li><p>In some places, it will be totally vertically integrated, like Codespaces</p>
</li>
<li><p>In some places, it will be a cloud devbox model</p>
</li>
</ul>
</li>
<li><p>It will be easiest for</p>
<ul>
<li><p>New projects to start remote (rather than migrating existing workflows to remote)</p>
</li>
<li><p>More limited domains like webdev / jamstack</p>
</li>
<li><p>New developers / novices / students</p>
</li>
</ul>
</li>
<li><p>It could happen if certain companies start to mandate it for financial or security reasons</p>
</li>
<li><p>Dev technology is by its nature very fragmented though, and certain trends actually make the transition hardere</p>
</li>
<li><p>Remote dev shift will continue to happen gradually, not all at once</p>
<ul>
<li><p>Proliferation of microservices</p>
</li>
<li><p>Proliferation of cloud services make it super hard to have a hermetic dev env, no matter what you do</p>
</li>
</ul>
</li>
</ul>
<p>At some point Warp may have the feature of “make my local terminal setup run on a cloud box” – I think it’s an interesting onramp to cloud dev.  </p>
<p>But it’s not our current focus – right now we are just trying to create the best possible single-user terminal and prove that the terminal can also be a Teams product – which ironically doesn’t require any particular stance on remote dev at all.</p>
]]></content:encoded></item><item><title><![CDATA[The Google Incentive Mismatch: Problems with Promotion-Oriented Cultures]]></title><description><![CDATA[If you’re an engineer at Google or Facebook, you’re likely focused on one career question: when am I going to make it to the next level?
Getting to the next level unlocks a lot – more money, more responsibility, more respect, a feeling of progress – ...]]></description><link>https://thezbook.com/the-google-incentive-mismatch-problems-with-promotion-oriented-cultures</link><guid isPermaLink="true">https://thezbook.com/the-google-incentive-mismatch-problems-with-promotion-oriented-cultures</guid><category><![CDATA[Startups]]></category><category><![CDATA[management]]></category><category><![CDATA[leadership]]></category><category><![CDATA[hiring]]></category><category><![CDATA[terminal]]></category><dc:creator><![CDATA[Zach Lloyd]]></dc:creator><pubDate>Wed, 04 May 2022 05:03:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1651726893541/jzuxN5SRh.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you’re an engineer at Google or Facebook, you’re likely focused on one career question: when am I going to make it to the next level?</p>
<p>Getting to the next level unlocks a lot – more money, more responsibility, more respect, a feeling of progress – and even if you care deeply about other things (your product, your users, etc), you can’t really avoid caring about promotion as well.  </p>
<p>‍This post talks a bit about the (well-known) issues with this type of culture, and suggests some alternatives for startups not looking to replicate it.</p>
<h1 id="heading-the-problems-with-promo-culture">‍The problems with promo-culture</h1>
<p>The main problem with promotion-oriented culture is that it’s very hard to align promotion-criteria with business objectives, and so engineers end up doing a lot of work that doesn’t necessarily most benefit the product, users, or business – or even potentially their own growth.</p>
<p>‍For instance, when I was leading Google Sheets, we had a lot of small bugs and usability issues, often in areas where we weren’t at parity with Excel.  Users wanted us to implement disjoint selections, fix our charting UI, add the ability to insert and delete ranges of cells – pretty standard spreadsheet fare, and very reasonable requests.</p>
<p>‍However it was a constant struggle to prioritize these types of issues vs. “bigger impact” projects. Our engineers cared about the product and wanted to polish it. But they also wanted to be promoted. And so we would deprioritize product polish for projects that looked better to a promotion committee.</p>
<p>‍In addition to it being hard to prioritize polish, promo-cultures tend to create other inefficiencies:</p>
<ul>
<li>A surplus of “leads” on a project (being a “lead” allows engineers to check the leadership box for getting to the next level) </li>
<li>Post-hoc design documents written specifically to explain work to a promo-committee after the feature has been built</li>
<li>Promo-time “tech-talks” and brown-bags of dubious value from engineers trying to demonstrate community contributions
‍
Finally, there is the dreaded “perf-season” where engineers and managers waste a tremendous amount of time prepping promo-packets to make their cases for moving up the ladder.</li>
</ul>
<p>‍To sum up the problems…</p>
<ul>
<li>From a business perspective, promotion-driven cultures decrease productivity and increase cost per engineer.   </li>
<li>From a product perspective, managers create new, confusing, internally competing products while existing products languish or are sunset, because one of the best ways to get promoted is to launch something new.</li>
<li>From a cultural perspective, for engineers who really care about the products they are building, promo-culture creates a demoralizing situation, sometimes forcing engineers to choose between doing what’s best for users or what’s best for their career. 
‍</li>
</ul>
<h1 id="heading-alternatives-to-promo-cultures">Alternatives to promo-cultures</h1>
<p>‍
In theory startups should be the foil to promotion driven cultures – most startup employees understand that getting promoted is a second-order concern relative to the risks of the startup not succeeding. </p>
<p>Conversely, folks understand that if they are early at a successful startup, they will be successful too – they will all do really well from a comp perspective, have seniority by default as the company grows, and  get to take pride in building something from nothing.  Incentives are naturally aligned.</p>
<p>However, anyone who has spent their careers in startups knows that this isn't always true, and that startups that are successful tend to drift towards a promo-culture.  As startups grow, early-stage risks and benefits decline, and so incentives become less aligned.</p>
<p>Some things I've been thinking about that might help avoid promotion culture:</p>
<ul>
<li>For as long as possible, make the success of the company the primary motivator, rather than promo</li>
<li>Try to hire engineers who are fatigued by the promo process at bigger companies and don’t want to replicate it</li>
<li>For any formal promo process, put real limits on the amount of time that goes into it while keeping it fair</li>
<li>Build into core values wanting to create a culture where the end-user is the priority, not individual advancement up the ladder</li>
<li>Make the ladder heavily focused on user-impact as the main criteria for advancement</li>
<li>Be constantly on the lookout for promo red-flags like post-hoc design docs, internally competing projects, and “promo-seasons”
‍</li>
</ul>
<p>If you have other ideas on how to avoid the slip into promo-culture, I’d love to hear your thoughts.</p>
]]></content:encoded></item><item><title><![CDATA[The Biggest Mistake I See Engineers Make]]></title><description><![CDATA[Throughout my career, the biggest mistake I see engineers make is doing too much work on their own before looping in others.  

I’ve experienced this mistake as both an IC and a manager. As an IC, it’s a mistake I made many, many times early in my ow...]]></description><link>https://thezbook.com/the-biggest-mistake-i-see-engineers-make</link><guid isPermaLink="true">https://thezbook.com/the-biggest-mistake-i-see-engineers-make</guid><category><![CDATA[Startups]]></category><category><![CDATA[software development]]></category><category><![CDATA[coding]]></category><category><![CDATA[product]]></category><category><![CDATA[project management]]></category><dc:creator><![CDATA[Zach Lloyd]]></dc:creator><pubDate>Wed, 26 Jan 2022 09:03:55 GMT</pubDate><content:encoded><![CDATA[<p>Throughout my career, the biggest mistake I see engineers make is doing too much work on their own before looping in others.  </p>

<p>I’ve experienced this mistake as both an IC and a manager. As an IC, it’s a mistake I made many, many times early in my own career. As a manager, I made the mistake of not recognizing and fixing it in the engineers I’ve managed.  </p>

<p>Correcting this habit is the most common feedback I now give, so I thought it might be good to write out how it happens and how it can be avoided.</p>

<p>The typical scenario goes something like this:</p>

<ol><li>An engineer takes on a relatively big / important project, usually building a feature or piece of infrastructure.  The bigger the project, the likelier the situation to follow this pattern.</li><li>The engineer goes off on their own and starts by trying to figure out how to build the thing.  Often this is verbally framed as “exploratory work”, “designing”, or something else without a concrete deliverable or timetable.</li><li>Throughout this initial period there are standup updates of the form “I’m exploring X, or working through problem Y, but should have something for others to take a look at soon”</li><li>Finally, after several weeks, the engineer shares an update, and one (or many) of the following bad things transpire: <ol><li>They have started building the thing and are about to send out a really big initial PR for it (oy!).  For reasons I talk about <a href="https://thezbook.com/coding/#small-changes">here</a>, you always want to send the smallest PRs you can, and generally for big features you should start with a design or prototype, not a PR.</li><li>They have actually been solving the wrong problem because the feature wasn’t well specified (which is normal, and speccing a feature out more completely is often part of building it).   E.g. they assumed that their feature would work way X, but the rest of the team was thinking it would be Y, so the design or code isn’t right.</li><li>They have been trying to figure out the solution to some very specific part of the problem, which actually might not be important at all because we could easily trim back the product requirements to avoid it.  (E.g. they have been devising a locking solution for something that doesn’t even require concurrency).</li><li>They have designed a very involved, complex, overall solution which if they had got feedback on earlier we might have redirected to a totally different spot.  E.g. the solution has multiple new microservices where there could have just been a library.</li></ol></li></ol>

<p>These outcomes are all bad for the same two reasons:</p>

<ol><li>There was a huge cost in time without a lot of forward progress on the project.</li><li>We end up in a position of dealing with the <a href="https://thedecisionlab.com/biases/the-sunk-cost-fallacy/">Sunk Cost Fallacy</a> where it hurts to abandon the work already done in order to get back on track – if we aren’t careful, we’ll end up shipping the wrong thing because we didn’t want to swallow the sunk cost.</li></ol>

<p><strong><em>Why does this happen?</em></strong></p>
<p>For early career engineers, it often happens because they lack practice working on teams.  They train in school environments where they do classroom projects on their own, or work on long-term intern projects in a silo.  They are used to having to figure it all out up front, submit it for review, and then get some sort of result, like a grade or return offer.</p>

<p>For more senior engineers, it can happen because they like to work on their own and may be overconfident in finding solutions.  It can also happen if the team culture is toxic and engineers fear getting criticism early in the design process.</p>

<p>Building software on a team shouldn’t work this way though.  When you work on a team, you shouldn’t be in competition with other schoolmates or interns or teammates – you are working cooperatively to ship the best possible product, as quickly as possible.  And there’s a huge advantage in leveraging the team’s collective wisdom to build better and faster.  </p>

<p>Early career engineers don’t always know this – they need to be taught it.  Senior engineers can be overconfident and need to be reminded of it.  And as a manager, you need to be on the lookout for this flawed approach in order to keep your team productive.</p>

<p><strong>To sum up, just as a product is likely to be best if it is developed iteratively with users, the work of an engineer will be best if developed iteratively with the product team.</strong></p>

<p>Concretely, if you’re an engineering manager, this means the following:</p>

<ol><li>Always encourage engineers to show their work as quickly as possible – an engineer on a project should never go more than a week without showing something, and usually it should be more like a day.  </li><li>The thing they show could be a design doc, a PRD, a prototype – anything that puts the team in a position to give meaningful feedback as early in the development process as possible. </li><li>If the engineer is unclear on a first deliverable, help them decide on what (e.g. a design doc) and by when (e.g. in two days).  And so on for the next deliverables.</li><li>Encourage engineers to get something end to end launched internally as quickly as possible.  In other words, rather than developing the feature in a waterfall fashion, where the engineer does the complete data model, followed by the complete controller logic, followed by the complete view, encourage doing just a partial data model, controller, view that works end to end for some small part of the feature.  This will give everyone a better sense of the feature from a user’s perspective and will also be the easiest way to see how the pieces of code fit together.</li><li>Development should always be done behind feature flags so that features can be checked in incrementally.</li><li>Demo, demo, demo – continue to demo the feature as it gets fleshed out.</li><li>Separately, you should encourage everyone on the team to give constructive feedback, and be on the lookout for any feedback that is overly negative or toxic, since that discourages developers from working iteratively.</li></ol>

<p>Hope this is helpful!!</p>
]]></content:encoded></item><item><title><![CDATA[Hiring]]></title><description><![CDATA[How to hire engineers at an early stage startup
One of the hardest and most important parts of starting and growing a company is hiring a great team of engineers.  It’s probably the most important thing you will need to get good at as a founder of a ...]]></description><link>https://thezbook.com/hiring</link><guid isPermaLink="true">https://thezbook.com/hiring</guid><category><![CDATA[Startups]]></category><category><![CDATA[hiring]]></category><category><![CDATA[interview]]></category><category><![CDATA[management]]></category><category><![CDATA[software development]]></category><dc:creator><![CDATA[Zach Lloyd]]></dc:creator><pubDate>Mon, 01 Mar 2021 07:41:28 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-how-to-hire-engineers-at-an-early-stage-startup">How to hire engineers at an early stage startup</h2>
<p><span>One of the hardest and most important parts of starting and growing a company is hiring a great team of engineers.  It’s probably </span><i><span>the</span></i><span> most important thing you will need to get good at as a founder of a company, and, it’s one of those things that you’ll need to figure out on your own. </span></p>

<p><span>The reason it’s so important – in case it’s not obvious – is that the caliber of people you bring aboard is the biggest determinant of success at an early stage company.  Nothing will sink you faster than hiring (and retaining) B or C level talent. It will slow down the development process, lead to crappy product, cause management overhead, make joining you less appealing for A players, and is generally the worst thing you can do.</span></p>

<p><span>It’s easy to do hiring wrong (I’ve done it wrong).  Some of the dangers include</span></p>

<ul><li><span><strong>Hiring the wrong people</strong> – which leads to having to fire them (or worse, retaining them), which is painful</span></li><li><strong>Not hiring enough people</strong> – which slows your velocity and can be deadly from a business perspective</li><li><strong>Wasting a ton of your time</strong> – you can easily spend all your time sourcing, interviewing, etc and not enough time building the actual business. But expect to spend a bunch of your own time on it at least to start</li><li><strong>Wasting a ton of your team’s time</strong> – this happens when you bring unqualified candidates too far down the funnel and other people get sucked into interviewing and grading bad fit candidates<br /></li><li><strong>Spending a lot of money</strong> – recruiting is a huge business and once you start hiring you will be inundated with offers from recruiters and recruiting platforms to give you your business</li></ul>


<h3 id="heading-startups-vs-established-companies">Startups vs. Established Companies</h3>
<p><span>As an aside, if you’re at Google or a place like it, this section won’t be as useful.  Google has unique advantages compared to a startup in terms of name-brand, amount of inbound applications, what they can pay and offer in perks.  </span></p>

<p><span>What Google or Facebook managers call “hiring” is actually a completely different thing from startup hiring.  It’s really “selection” from a highly curated applicant pool, without having to worry about compensation, applicant interest, sourcing, etc.   It has more in common with what the admissions committee at Harvard does. Most of the quality applicants come to you, and you sort, filter and select, and then, if someone meets the bar, you have to sell them on taking your (usually very competitive) offer.</span></p>

<p><span>Startup founders need to operate higher in the funnel, and typically have a much tougher pitch.  They need to go out and find quality engineers who already have other, more secure, higher paid jobs, cut through the noise to convince them to talk, sell them on a dream, convince them to do a real interview process (which might lead to their rejection), and ultimately hop ship to work on a much riskier, usually lower paid venture.  It’s hard.</span></p>

<p><span>I still have a lot to learn on how to do hiring well.  But I can share some of what I learned at my last company where I was really proud of the team we put together.</span></p>


<h3 id="heading-hiring-is-a-sales-process">Hiring is a sales process</h3>
<p><span>If you are at a startup, you should view hiring as a sales process.  You are selling the opportunity of working at your company. Engineers are the buyers, and it’s very much a buyers market.  The best candidates need to be sold – do not expect them to come knocking on your door.</span></p>

<p><span>You should think of bringing talent onto your team in terms of a sales funnel.  This particular funnel has three steps: 1) generating interest, 2) evaluation of fit, 3) offering and closing.</span></p>

<p><span>At the top of the funnel, there is a combination of marketing / branding, inbound traffic, outbound outreach and sourcing, referrals, recruitment, and other ways of getting candidates interested.</span></p>

<p><span>Once candidates are interested, they progress into an evaluation phase.  You should think of this in terms of finding whether the opportunity is a “fit.” Is the engineer right for your company </span><i><span>and</span></i><span> is your company right for the engineer.  It needs to be both. </span></p>

<p><span>Finally, for candidates you believe are good fit, you make an offer and go into closing mode to try to get them to sign.</span></p>

<p><span>What I describe below is what I think of as the “standard process,” which I used with success at my company.  I’m sure there are a lot of other ways of approaching this (and I’d love feedback on how to improve it).</span></p>


<h3 id="heading-who-do-you-want-to-hire-andamp-why-should-they-work-at-your-company">Who do you want to hire &amp; why should they work at your company?</h3>
<p><span>You’ve got a startup that no one has ever heard of.  Your task is to get high-quality engineers excited to come work there.  You can’t compete in terms of salary or job security. How do you do it?</span></p>

<p><span>You need to start by deciding who you are looking for, the more specific the better.</span></p>

<p><span>Here’s what I care about:</span><br /></p>

<p><b><strong>General intelligence</strong>.</b><span>  I don’t care about experience with particular technologies; I want the smartest people I can find. (I recently had someone I respect disagree here and favor hiring specialists at very early companies in order to cut out ramp up time – I don’t quite buy that strategy though)</span> </p>

<p><span><strong>Technical thinking</strong></span><strong>.</strong><span>  I don’t require a CS degree (I don’t have one), but I do favor candidates who have demonstrated an ability to think rigorously.  For me this could mean a STEM degree, a philosophy or economics degree, past technical experience at a job, impressive side-projects, etc.</span></p>

<p><b><strong>Team players</strong></b><span>.  No assholes.  I want people who put the good of the team and the product above their personal ambitions.</span> </p>

<p><b><strong>Product-first mindset</strong><span>.  See the section on Product-first vs. Code-first.  I have some questions below on how to suss this out.</span></b></p>

<p><span>For me this leads to a rubric like:</span></p>

<ul><li><span><strong>Education</strong>Undergrad degree from a good school, or self-taught ok if a strong track record</span></li><li><strong>Experience</strong>: worked at a place with a known rigorous hiring process (google, fb, or a smaller, well known startup like Oscar, Paperless Post, Betterment, Vine, etc)</li><li><strong>Any undergrad major fine</strong>, but STEM a bonus</li><li><strong>Enough CS knowledge to pass a Google-style interview</strong></li></ul>

<p><span>On the flip side, you need to consider what your target engineers are going to care about and how can you stand out.</span></p>

<p><span>As mentioned, you probably aren’t going to be able to compete based on:</span></p>

<ul><li><b><strong>Name recognition</strong>. </b><span> You aren’t Google, Facebook or Slack.</span></li><li><strong>Salary and benefits. </strong> Google pays its top engineers 7-figures and starting engineers good six figures.  You probably can’t.</li><li><strong>Perks.</strong>  Free catered food, on-site massage, volleyball courts, renting out the MOMA for holiday parties.  Maybe if you are realllllly well funded, but probably not.<br /></li><li><strong>Number of users.</strong>  You aren’t scaling out to millions of users right at the start, so by that measure the impact of your product will be lower.</li></ul>

<p><span>However, you have some advantages compared to bigger companies.</span></p>

<ul><li><b><strong>Velocity</strong></b><span>.  Engineers at big companies tend to be frustrated by how long it takes to develop, how many meetings they have, how small of an area that are able to work on, how hard it is to launch, and so on.  At your startup you can (and must) move much faster. You should lean into this when pitching engineers.</span></li><li><b><strong>Product ownership and input</strong><span>.  Engineers at your small company can own a much bigger piece of the product.  I always sell this pretty hard because it also selects for the type of engineers I want – people who care about the customer and user experience.</span></b></li><li><strong>Culture</strong>.  <span> Engineers at small startups have a chance to really shape the culture of the team.  I emphasize how smart everyone on the team is, how we have no assholes, how we self-direct and iterate on our process as a team, how we take ideas from everyone.</span></li><li><strong>Upside</strong>.  <span>There’s not only the potential upside of startup equity, but upside in terms of growth and leadership if the company grows.  Generally the people who are there first are most likely to end up in leadership positions if the company succeeds.</span></li><li><strong>Technical challenges</strong><span><strong>.</strong>  Emphasize the unique technical challenges that you need to execute on in order for your company to succeed.  Engineers want to stretch themselves and work on challenging tech problems. But be careful here not to oversell.  A lot of the challenge at an early stage startup is in figuring out what to build, not how to build for scale. You need engineers who are OK changing direction frequently and building something less than the perfect system.</span></li><li><strong>Vision and Impact.  </strong>You have an opportunity to really sell the vision and mission of your company, probably in a way that a tech giant cannot at this point.  </li></ul>


<h3 id="heading-branding-andamp-marketing">Branding &amp; Marketing</h3>
<p><span>You need to make your company as appealing as possible to an engineer who has never heard of you.  We underinvested in this at my last company and constantly ended up in a position where prospective engineers did not understand what the company did and why they should work there.</span></p>

<p><span>What this means in practice is that you need to invest in professional assets that:</span></p>

<ul><li><span>Clearly explain what your company does</span></li><li>Explain the business opportunity</li><li>Explain the mission – why does your company make the world better?</li><li>Showcase the culture</li><li>Talk about the tech you are building</li><li>Spotlight the leadership</li><li>Spotlight investors and strategic partners if you have any</li><li>Make it clear in general why someone who has never heard of you should take a big risk to come join you</li></ul>

<p><span>The assets you want in place are:</span></p>

<ul><li>A pro looking website.  It can be minimal, but should explain clearly the things above.  Here is a good example: <a href="https://www.cockroachlabs.com/careers/">https://www.cockroachlabs.com/careers/</a></li><li><span>A “one-pager” that you can send someone as a pdf that explains the company, mission, opportunity, culture and tech.</span></li><li>Bios of the co-founders and leadership.</li><li>A great job description.</li></ul>

<p><span>By professional, I mean that you should pay a designer to make them look legit.  You don’t need Red Antler, but you do need them to look good.</span></p>


<h3 id="heading-writing-a-job-description">Writing a job description</h3>
<p><span>At a minimum, the job description should succinctly describe what you are looking for and give a feel for the company culture and values.  Here’s an example from my last company.</span></p>

<hr />

<p>We are looking for an outstanding software engineer to continue building and innovating on our customer-facing product.</p>
<p>This is an ideal opportunity for a full-stack engineer looking to work in a high-velocity, high-impact environment, owning the development process from design to implementation to launch.</p>
<p>YOU</p>
<ul>
<li>Write clear, self-documenting code</li>
<li>Are a problem solver, a pragmatist, a fast-learner, not dogmatic</li>
<li>Have experience building web and mobile apps (Javascript, Node, React a plus)</li>
<li>Are confident with performance optimization, and identifying bottlenecks and scalability concerns</li>
<li>Are familiar with a range of modern data stores (relational, document, key-value, search, etc.)</li>
<li>Have a good background in algorithms, systems, and design</li>
<li>Work well with a multidisciplinary team, and communicate actively</li>
<li>Think independently and love sharing your technical knowledge with others</li>
<li>Aren’t afraid of a little database administration or dev-ops work</li>
<li>Probably have a technical degree and 1+ years of real-world development experience</li>
</ul>
<p>WE</p>
<ul>
<li>Are a small, dedicated team of smart, experienced engineers, product folks, and creatives</li>
<li>Love Github, Slack, Asana, AWS, Meteor, Node</li>
<li>Hate useless meetings, value your time, and enjoy a good work/life balance</li>
<li>Are data-driven, and take product ideas from the whole team</li>
<li>Work quickly to test and launch new ideas</li>
<li>Value design and beautiful user experiences</li>
</ul>
<p>BENEFITS</p>
<ul>
<li>100% covered Medical, Dental, and Vision Plans</li>
<li>Health &amp; wellness perks through HealthKick</li>
<li>Flexible Working Hours</li>
<li>401K Plan</li>
<li>Free Meals and Snacks with a Fully Stocked Fridge and Pantry</li>
<li>Cold Brew Coffee in the Summer, Fresh Hot Coffee in the Winter, and Seltzer on Tap Year Round</li>
<li>Subsidized Commuter Benefits for MTA &amp; CitiBike</li>
<li>Monthly Team Outings</li>
<li>20 Paid Vacation Days &amp; Unlimited Sick Days</li>
<li>Office Located in Little Italy</li>
</ul>
<p>Expect a competitive application process that will include an initial coding assignment, phone screen, and in-person interview. Thank you for your interest. We look forward to hearing from you!</p>
<p>We are an equal opportunity employer and value diversity in our company. We do not discriminate on the basis of race, religion, color, national origin, gender, sexual orientation, age, marital status, veteran status, or disability status.</p>
<hr />

<p><span>However, the job description and company branding surrounding it present an opportunity to go above and beyond and let you stand out.</span></p>

<p><span>Take a look at what Vanta does in their description: </span><a href="https://www.keyvalues.com/vanta"><span>https://www.keyvalues.com/vanta</span></a></p>

<p><span>The thing I love about this is it leads with the culture and mission is likely to be appealing to exactly the kind of engineer they want to work there – someone who is very customer-centric and willing to do more than just engineering to make the product succeed.  The effort they put into the job description shows how much they care about hiring the right people.</span></p>



<h2 id="heading-the-recruiting-workflow">The Recruiting Workflow</h2>
<p><span>Once you have your assets in place, you need to start running a recruiting workflow.  You’ll want to track this workflow using some sort of Applicant Tracking System (ATS).  </span></p>

<p><span>There are a bunch of ATS solutions out there, and I don’t have strong opinions on what is best.  We used a product called Lever, which I don’t actually recommend. But there are others and the important thing is that you have one central database that effectively de-dupes candidates and stores where they are in your recruiting funnel.  This could be a spreadsheet to start if you don’t have budget for a real system, but there are some free options out there which are better than sheets for this purpose and I recommend you use something with more structure.</span></p>

<img src="https://lh5.googleusercontent.com/fG3lJdIvbQJ69mKnoCmtAgPA9O3ZNcqUGX4zNvvDGiXJWnSCida3zgod0ZF-hvJ6skzJmJftYY7BtaAiR_jE6uuXE_FBNb7NE-9qLggiLQoc1N6tvf-m4uFGiwQhsXpcDiSU-0U3" alt />

<p><span>The above chart shows high level what the recruiting workflow looks like.  On the far left are the various places candidates come from. As you move right, there are various steps for progressing them through your funnel.  Let’s start by looking at the sources.</span></p>


<h3 id="heading-referrals">Referrals</h3>
<p><span>Referrals are the best source.  They can come from your own network, from employees, or from investors.  They are best because (a) you have an easy in for contacting the candidate, (b) they are pre-vetted, (c) the pre-existing relationship can help you close the candidate.</span></p>

<p><span>For employees, you should offer a referral bonus to incentivize them.  There are different schools of thought here – I’ve heard people say that employees should love the company enough that they want to tell their friends to come work there and that therefore referral bonuses should not be necessary or create a bad incentive.  </span></p>

<p><span>I don’t really buy this.  Recruiting is so hard and referrals are so valuable that I would do everything in your power to motivate employees to take the time to reach out to their talented friends and co-workers.  There’s a reason Google offers referral bonuses even though everyone in the world wants to work there already.</span></p>

<p><span>You should set up times to sit down with engineers on your team and go over their linkedin networks and see if they have folks who might make sense for them to reach out to.</span></p>

<p><span>For investors, you should make sure the assets I mentioned above are strong and then ask them to distribute those assets to their network.  Good investors will have in-house people focused on talent since it’s such a huge determinant of success. Form good relationships with those talent folks and make it easy for them to sell your company to people in their network.</span></p>


<h3 id="heading-sourcing-candidates-andamp-cold-outreach">Sourcing candidates &amp; Cold Outreach</h3>
<p><span>After referrals, your best option is sourcing candidates yourself and doing cold outreach.  </span></p>

<p><span>Sourcing candidates is basically a manual process.  It entails compiling a big list of potentially qualified engineers, designers, etc along with your best way to contact them.  You can sometimes bootstrap this process by getting an existing list from an investor or fellow entrepreneur. These lists are very valuable and you should ask around and try to get one.</span></p>

<p><span>Even if you get a list of engineers and their emails, you’ll need a way of expanding it.  One of the “secret” ways I had of doing this at my last startup was paying people remotely via Upwork to source candidates off of LinkedIn.  The way this works is you create a Google sheet with fields like:</span></p>

<ul><li>Name</li><li>LinkedIn</li><li>Email</li><li>Years of Experience</li><li>Company</li><li>Undergrad School</li><li>Grad School</li><li>Highest Degree</li></ul>

<p><span>And then give instructions to a remote worker on the qualifications you are looking for.  I’d provide them with a list of schools, companies, job titles, and so forth, and set them to work reading LinkedIn looking for possible candidates.  Email is generally not listed on LinkedIn, so they will need to use a tool like EmailHunter to guess the email address. </span></p>

<p><span>As this list builds up, you start emailing potential candidates.  The ethics of this are a bit gray. Technically, it is not spam in the legal sense because the email was not automatically scraped and you are not selling a product, but it always felt iffy to me to reach out and try to get in front of someone using this method.  Up to you whether you go this route, but at a startup you need to be aggressive and I think it’s basically on the right side of the line. A lot of engineers were flattered to get the outreach. Some were annoyed.</span></p>

<p><span>On a technical note, I would create a separate email address to do the outreach from. </span></p>

<p><span>You can also try contacting people directly through LinkedIn, but I found that (a) it was very expensive and (b) not nearly as effective as directly getting into someone’s inbox.</span></p>


<h3 id="heading-recruiting-platforms">Recruiting Platforms</h3>
<p><span>Another option is recruiting platforms like Hired and Vettery.  These platforms aggregate engineers who are looking for jobs and make them searchable to employers.  It’s generally free for employers to browse the platform; they only pay if they actually make the hire.  </span></p>

<p><span>The fee is steep though, usually somewhere between $15k-25k, or 15-20% of the first year’s salary.  You can negotiate discounts as a startup, and can also get discounts for bulk usage. But overall it’s a pricey solution.</span></p>

<p><span>It’s also a relatively low quality solution in my experience.  The main issue is with the quality of talent on these platforms.  As mentioned above, the best engineers and designers typically have jobs.  If they are looking for new jobs, they often have connections to go through or will target their searches. </span></p>

<p><span>I found that the people on these platforms tended to be B-level talent.  We interviewed many of them, but literally zero of them made it though our interview process on the engineering side.</span></p>

<p><span>Still, there are probably some strong candidates on there and if I were hiring again, I would definitely look.</span></p>


<h3 id="heading-inbound-candidates">Inbound candidates</h3>
<p><span>As a rule, inbound candidates (people who found your company and applied directly) tend to be the lowest quality.  They can still be good, so it’s worth posting your job description widely and seeing what comes in, but expect a high signal to noise ratio.</span></p>



<h3 id="heading-external-recruiters">External recruiters</h3>
<p><span>Outside recruiters are another option.  They generally work on contingency so that you only pay if you make a hire through them.  If you run a startup long enough they will start contacting you with potential placements.</span></p>

<p><span>The upside is that they do the sourcing work for you and sometimes have quality candidates.  </span></p>

<p><span>The downside is cost – like the recruiting platforms they take up to 25% of first year salary, although you should always try to negotiate a discount.  </span></p>


<h3 id="heading-internal-recruiters">Internal recruiters</h3>
<p><span>If you have raised enough money and are hiring enough engineers, you should hire an internal recruiter.  Typically they cost around $60k / year. So if you are hiring more than 5-6 engineers per year, it will be beneficial to have someone on staff who can fully manage the hiring process.  It’s much more bang for the buck than paying an external recruiter 20k per hire – a good internal recruiter should be able to get you ~1 engineer per month depending on who you are looking for, and they will save you personally a ton of time and overhead.</span></p>

<p><span>The internal recruiter should be responsible for the whole hiring process, from writing and reviewing the JD, to filtering inbound applications, managing outbound, setting up phone screens and interviews, corralling feedback, and so on.  All of this overhead adds up quickly, and if you don’t have someone else handling it, you will find yourself as a founder, cto, or vp eng spending a ton of time setting up meetings and responding to emails. Far better to use your time on higher leverage activities like pitching high quality candidates and closing.</span></p>



<h3 id="heading-the-pitch">The Pitch</h3>
<p><span>You need to practice a version of the pitch that is specific to engineers.  It’s a different pitch than for investors or random people you network with.</span></p>

<p><span>The specifics of the pitch are going to depend on your business, but some things that I like to hit on are:</span></p>

<ul><li><span>Mission – how is your company making the world better</span></li><li>Culture and Values – what do you care about, what type of company is it</li><li>Business Opportunity – how will the company grow and make money</li><li>Traction – it’s working…</li><li>Leadership – why are you and your cofounder and other leaders great</li><li>Tech challenges – what are the most interesting things to work on</li><li>Product process – here’s how we develop new products</li><li>Team – the other engineers on the team are great because of X, Y, Z</li><li>Customers – our customers are X, Y, Z and they need us because of Y</li><li>Investors and Funding – We raised Xm from these great investors</li><li>Product roadmap – here’s what we plan on building over the next year</li><li>Personal growth and mentorship – if you work here, you will have the opportunity to grow in X, Y, Z ways</li><li>Startups are great – emphasize the benefits of startups over big companies – velocity, culture, ownership</li></ul>

<p><span>You should practice this pitch.  You’ll find that engineers ask the same questions over and over again, and every time they ask, you should make a note and try to adjust the pitch to explain again and again.</span></p>

<p><span>For my last company SelfMade, the pitch I gave went something like this:</span></p>

<ul><li><span>Mission: “We are trying to help small businesses grow”</span></li><li>Details: “We do that by making them have awesome instagrams that drive traffic and conversions”</li><li>Background: “The company is series A, we’ve raised 11.5m from great investors, we are based in NYC, have been around for 3 years”</li><li>Opportunity: The opportunity is really big and growing – every month 20k new Shopify stores start.  Amazon does half its business through its marketplace. Instagram is THE channel that all of these businesses need to figure out, and we are helping them.</li><li>Traction and growth: We have 750 paying customers and are doing about $5mm a year in revenue, up from $1mm at the start of the year</li><li>Me: I was a principal engineer at Google.  At SelfMade, I manage product and engineering.  My co-founder is a second time entrepreneur with an exit under his belt at a company you may have heard of.</li><li>Product: The product is a platform for producing Instagram feeds and ads at scale.  Explain how it works….</li><li>Tech challenges: The challenges are in optimizing the efficiency and quality of the content we produce.  We use ML for X, Y, Z</li><li>Product roadmap: We are expanding to support paid media in addition to organic instagram content.  We are also expanding to support more platforms and higher end customers.</li><li>Investors: We’ve raised 11.5mm in funding from top tier investors in NYC and Silicon Valley.</li><li>Personal growth: I’ve mentored a lot of engineers, and would help mentor you.  You will have an opportunity to own major parts of the application<br />Our startup is great: you’ll have ownership, be able to move quickly, meet new friends, and so on</li></ul>


<h3 id="heading-initial-phone-screens">Initial phone screens</h3>
<p><span>If you have someone who is interested, the first step after email is to set up a brief phone call to pitch the company and hear about their background.</span></p>

<p><span>If you have an internal recruiter, they should set this call up and take it for most candidates.  The exception is if you have a particularly promising candidate who has come recommended, then you should consider taking the call and doing the pitch yourself.  And if you don’t have an internal recruiter, then, well, you’re taking the call.</span></p>

<p><span>The call should take 15-30 minutes max, and should cover:</span></p>

<ul><li><span>Intro</span></li><li>Candidate’s background</li><li>Candidate’s interests and desired role</li><li>Company background and pitch</li><li>Role description and pitch<br />Next steps</li></ul>

<p><span>I always have the candidates give me their background before giving the company pitch because it lets me tailor the pitch to what I think will resonate with them.  E.g. if they are interested in frontend, I pitch the opportunities to work on app frontend. If they are looking for mentorship, I talk more about my background managing engineers.  And so on.</span></p>

<p><span>The goals of this call are twofold:</span></p>

<ol><li><span>Determine if you want to continue the process with the candidate.</span></li><li><span>If yes, then get the candidate to commit to the next step.</span></li></ol>

<p><span>This call should be high-level and non-technical.  It’s purely a screen on</span></p>

<ul><li><span>Basic intelligence – is the person smart and articulate</span></li><li>Basic background – do they have roughly the right background for the role<br />Basic culture fit – did they do anything that would make you think they are obviously not going to fit at your company</li></ul>

<p><span>If all of these things are a “yes,” then you should try to get them to commit to moving forward on the call.  </span></p>

<p><span>If they have questions or concerns and seem high quality, you can offer to connect them with another leader or engineer at your company for more color.</span></p>


<h3 id="heading-coding-tests-optional-but-recommended">Coding tests (optional but recommended)</h3>
<p><span>The next step I recommend is a short online coding test.  We used a platform called Codility, but there are a number of platforms out there that work for this.</span></p>

<p><span>The idea is to make sure the candidate can code well enough that they won’t totally flail in an onsite interview.  This is not the place to ask hard coding questions – it’s just a sanity check. It should take the candidate no more than 1-1.5 hours.</span></p>

<p><span>That said, even on what I judged to be relatively easy online coding tests, this would filter out at least 50% of applicants who couldn’t get the coding test half right.   </span></p>

<p><span>We probably ended up eliminating some qualified candidates with this filter, but I don’t think the false positive rate was very high.  </span><i><span>Programming is hard</span></i><span>, and there are a lot of people who can sort of do it, but not really do it, and if you want a great team you need to aggressively weed out people who are not strong.  That said, you should take the tests yourself and make sure you can do them. If you can’t do them, they are too hard.</span></p>

<p><span>The real downside to this filter is not that qualified candidates don’t do well on the test, but that qualified candidates might not want to take the test at all.  It takes time, can be stressful, and, if they don’t do great, it hurts the ego. You don’t want qualified candidates dropping out of the funnel here, so if you see someone who has a great resume (top school or top company) who was good on the initial screen, then I would definitely skip this step.</span></p>

<p><span>That said, try hard to avoid having unqualified candidates in for onsites.  When someone comes in and starts bombing questions it puts both you and the candidate in an awkward position.  You either have to ask them to leave early or else waste a lot of valuable engineering time interviewing them. Being asked to leave an interview early is a bad experience for candidates; keeping unqualified candidates around for full interviews is a waste of time for your engineers.  So weed people out as early as you can.</span></p>


<h3 id="heading-technical-phone-screens-optional-but-recommended">Technical phone screens (optional but recommended)</h3>
<p><span>Another possible (and recommended) step is a technical phone screen with an engineer.  This can be done in addition to or in lieu of the coding test.</span></p>

<p><span>The format is a 45-60 minute phone call or video hangout where an engineer on your team poses one or two coding questions to the candidate and has them work through them using google docs or some other collaborative editor.</span></p>

<p><span>Some advantages compared to the coding test are (1) that you can learn more about how someone thinks by observing them work through a problem (2) it creates a chance for the candidate and engineer to have a personal interaction and (3) can give another person on the team a chance to evaluate intelligence and culture fit in a way that you don’t get from someone taking a coding test.  It also makes cheating impossible (and yes, people cheat on the coding tests fairly often).</span></p>

<p><span>The disadvantage is mostly that it takes time from an engineer, and, if you are in rapid hiring mode and have a relatively small group of engineers to conduct the calls, these interrupts can add up to a lot of lost productivity.</span></p>

<p><span>Overall though I recommend this step for getting the most qualified candidates into the onsite.</span></p>


<h2 id="heading-on-site-interviews">On-site interviews</h2>
<p><span>The onsite interview is the most important part of the process.</span></p>

<p><span>For a full-time engineering or product hire, you should plan on having 5-6 separate sessions with the candidate, plus some more informal time where the candidate gets to have lunch, meet some non-technical folks, and get a feel for the office.</span></p>

<p><span>Most of the engineering interviews should cover a mix of:</span></p>

<ol><li><span>Coding</span></li><li>Algorithms and runtime analysis</li><li>System design</li></ol>

<p><span>And there can be a secondary focus on</span></p>

<ol><li><span>Some particular technology (e.g. iOS or React)</span></li><li>Live coding or debugging</li><li>Product &amp; user focus</li></ol>

<p><span>The engineers giving the interviews should coordinate beforehand to make sure there is enough coverage (e.g. at least one systems focused question instead of all coding).</span></p>

<p><span>An interview session should last about 45 minutes:</span></p>

<ul><li><span>5 minutes on introductions, getting the candidate comfortable, explaining the format</span></li><li>35 minutes on one main question</li><li>5 minute wrap up at the end where the candidate has an opportunity to ask questions</li></ul>

<p><span>Everyone on the team should be able to conduct an interview, but new hires will need time to shadow experienced interviewers before jumping in on their own.  I also encourage people to develop their own questions.</span></p>

<h3 id="heading-a-good-interview-question">A good interview question</h3>
<ul><li><span>Should </span> <ul><li><span>be easy enough that it can be solved in 35 minutes</span> </li></ul><ul><li><span>be non-trivial in the sense that candidates will need to spend at least a few minutes thinking about possible solutions before diving in</span> </li></ul><ul><li><span>lend itself to different possible solutions that have different performance characteristics (often there is a “brute force” solution and then a more efficient solution)</span> </li></ul><ul><li><span>be “extensible” so that if a candidate gets the basic solution quickly you can make it harder by asking variations of it</span></li><li><span>Should be “hintable” so that if a candidate gets stuck early on you can nudge in the right direction without fully giving it away</span> </li></ul></li><li><span>Should not </span> <ul><li><span>require any specialized knowledge beyond basic coding and algorithms (unless you are interviewing for a specialized role)</span></li><li><span>be an “aha” type puzzle – no questions where you need a flash of insight to get it right (how does an insect get out of a blender, or why are manhole covers circular type questions)</span> </li></ul></li></ul>

<p><span>The point of the interview, and I always stress this prior to starting with a candidate, is not just to see if the candidate can get to the correct answer.  It’s much more about seeing how the candidate approaches a problem. I want to see whether the candidate:</span></p>

<ol><li><span>Takes the time to understand the question</span></li><li>Asks clarifying questions before starting to solve the problem</li><li>Writes down example inputs and their corresponding outputs to think through various cases</li><li>Breaks the problem down into simpler subparts</li><li>Starts with the simplest solution even if it’s slower (I always ask them to do this)</li><li>Takes instruction well when they are heading down the wrong path</li><li>Asks questions when they get stuck</li><li>Outlines the algorithm before writing the code</li><li>Writes code that is at least basically syntactically correct in the language of their choice</li><li>Describes in words what they are doing and how they are thinking</li><li>Proves to themselves and the interviewer that their proposed solution works</li><li>Can engage in a discussion about different possible solution strategies</li><li>Can describe the performance of their solution and think through possible optimizations</li><li>Can describe test cases they would write to validate their solution</li></ol>

<h3 id="heading-sample-interview-question-pascals-triangle">Sample Interview Question - Pascal's Triangle</h3>
<p><span>For instance, say the question is to write a function that determines the value at a particular position in </span><a href="https://www.mathsisfun.com/pascals-triangle.html"><span>Pascal’s Triangle</span></a><span>.  </span></p>

<p><span>I would give the candidate a function signature like:</span></p>

<pre><code>function pascalVal(row, col) {
  // your code here
}</code></pre>

<p><span>The first thing I would want to see is if the candidate understands the question.  Good questions would be:</span></p>

<ul><li><span>What is the indexing of row and column (0-based)?</span></li><li><span>What are some example solutions?</span> <ul><li><span>pascalVal(0, 0) = 1</span> </li></ul><ul><li><span>pascalVal(2, 1) = 2</span></li><li><span>pascalVal(3, 2) = 3</span> </li></ul></li></ul>

<p><span>And then I would want to see if they could get to either a recursive or dynamic programmimg solution.</span></p>

<ul><li><span>If they got the recursive solution, </span><ul><li><span>What’s the runtime performance (2^n)</span> </li></ul><ul><li><span>How could they improve that performance (memoizing, taking advantage of symmetry, etc)</span></li><li><span>Can they also write up the iterative solution</span> </li></ul></li><li><span>If they got the dynamic solution</span> <ul><li><span>What’s the runtime performance (n^2)</span> </li></ul><ul><li><span>How could they improve memory usage</span></li><li><span>Can they also write up the recursive solution</span> </li></ul></li></ul>

<p><span>There are various points in this question where candidates get stuck, and I have moves at each of them to help them keep going.</span></p>

<p><span>The goal of the interview is that the engineer is able to fill out a simple rubric about the candidate:</span></p>

<ol><li><span>What was the question?</span></li><li>What was the code the candidate produced?</li><li>How would you rate their coding (if applicable)?</li><li>How would you rate their problem solving?</li><li>How would you rate their design (if applicable)?</li><li>How would you rate their knowledge and experience?</li><li>Are they a culture fit? Why or why not?</li><li>Would you hire them (1. strong no, 2. weak no, 3. weak yes, 4. strong yes)</li></ol>

<h3 id="heading-interview-etiquette">Interview etiquette</h3>
<p><span>A few notes on interview etiquette:</span></p>

<ul><li><span>Whiteboard interviews can be </span><b>very</b><span> intense for candidates and it’s important that the interviewer be mindful and understanding.  There is nothing gained by increasing the pressure – it’s already a very contrived setup so you should try your hardest to be sympathetic and put the candidate at ease.</span></li><li>Always emphasize that getting the solution is not everything and that you care just as much about how they think through the problem, the questions they ask, whether they would fit the culture and so on.</li><li>Do not check your phone or email during an interview.</li><li>Have someone on the team who is dedicated to making the experience good – this person would typically be the recruiter, but it also could be an engineer.  They should greet the candidate, make sure all the interviews are running on time, make sure the candidate has everything they need.<br />Remember that if you make an offer you will likely need to sell the candidate on joining, and how they were treated during the interview will make a difference.</li></ul>

<h2 id="heading-post-interview">Post interview</h2>
<h3 id="heading-hiring-meetings">Hiring meetings</h3>
<p><span>After everyone has submitted their feedback, you should get together as a group and make a decision.  This can be pretty informal – everyone goes around the room reading their feedback and making an argument one way or the other.  </span></p>

<p><span>A note on bias here: </span><b>everyone needs to submit their feedback independently before the hiring meeting</b><span>.  If you don’t enforce this, then people end up biasing each other depending on who speaks first.  It’s ok to be swayed if someone addresses your concern in the hiring meeting, but if more than a couple of the interviewers are changing their minds I tend to want to pass.</span></p>

<p><span>Typically I require a unanimous “yes” in order to move forward, which effectively gives every interviewer a veto.  This undoubtedly leads to false negatives – people we should have made offers to that we ended up passing on. However, the cost of a false positive (a bad hire) is much higher than a false negative, so I’m ok with this bias.  A bad hire ends up wasting a lot of management time, money, opportunity cost in terms of hiring someone better, and so on. Keep your hiring bar high.</span></p>


<h3 id="heading-reference-checks">Reference checks</h3>
<p><span>The final step before making an offer is checking references.  Ninety percent of the time the references will reinforce your existing opinion and make you more confident in the offer.  But sometimes they will give you pause. </span></p>

<p><span>Even though it takes a bit of extra time, it’s worth it – there have been many times where I was going to make an offer, but the reference call made me change my mind (e.g. I’ve uncovered candidates lying about their previous positions; I’ve had people tell me in not so many words that the candidate was just fired, and so on).</span></p>

<p><span>I try to get three references from each candidate, where two of them had a supervisor relationship (not peers, friends or coworkers).</span></p>

<p><span>The reference call itself should take about 10 minutes.  I prefer a call to an email because it’s more likely to get honest answers and let you read between the lines.  But if you can’t get a call, then use an email – it’s way better than nothing.</span></p>

<p><span>Here’s the call template I use:</span></p>

<hr />

<p>Intro – “Hi I’m Zach, thanks for taking the call, it shouldn’t take more than 10 minutes…” </p>

<ul><li>Company overview – “We do X, Y, Z.  The company is X people”</li><li>Role overview – “We are making X an offer for software engineer”</li><li>Questions<ol><li>What is your relationship to X?</li><li>Can you describe X’s role &amp; responsibilities?</li><li>Why did X leave his job? (optional)</li><li>How would you rate X’s overall job (or school) performance?</li><li>What percent is X in for programmers? Top 5%? Top 10%? Top 25%?</li><li>For a specialist (e.g. an AI person)   How would you rate X’s expertise in the field? </li><li>How would X be at translating research into engineering?</li><li>How is X as a programmer vs. a researcher? </li><li>Do you think X would do well at an early stage startup?</li><li>How were X’s communication skills?        </li><li>How was X’s work ethic?</li><li>How quickly did X work? Is X more of a pragmatist or perfectionist?</li><li><strong>If I were to be his manager, do you have any advice on how i could help X succeed?</strong></li><li>What could X improve on?</li><li>How does X deal with conflicts?</li><li>What was it like to work with X?</li><li>Would you want to work with X again? If so, why? If not, why not?<br />Is there anything else I should know about X?</li></ol></li></ul>

<hr />

<p><span>Question 13 is bold because it’s often most telling.  It’s a way of asking about the candidate’s weaknesses without explicitly asking about them.  You need to keep in mind that the person you are getting the reference from most likely has been chosen by the candidate to say nice things about them – that’s the idea.  </span></p>

<p><span>Still, people want to be honest and if you give them a way to give honest feedback which might be less positive without feeling like they are betraying the candidate, they will do it.  That’s why this is a good question – it says, tell me how I can help the candidate, but what it’s really asking is what does the candidate need help with. </span></p>

<p><span>Everyone has weaknesses, so hearing about areas for improvement about a candidate is not at all a disqualifier – it can help you manage them.  But, if enough of the references give the same negative feedback, you might consider whether you missed something at the interview and whether the candidate really is a good fit.</span></p>

<p><span>That said, the things that are most likely to make me rescind an offer at the reference stage have to do with a candidate not being honest.  For instance, if a candidate told me they had a certain role at a company and I find out the role was different, that’s a huge flag; I had that happen with someone pretending they were full time at google, and I only found out at the reference that he was a contractor (very big difference).</span></p>


<h3 id="heading-offers-andamp-closing">Offers &amp; Closing</h3>
<p><span>The offer should come via a phone call from you – it’s more personal and exciting than getting an email.</span></p>

<p><span>It should include salary, start date, title, equity, benefits and a ton of enthusiasm about the candidate.</span></p>

<p><span>Some notes…</span></p>

<p><b>Explain your equity grant. </b><span> </span></p>

<ul><li><span>Don’t count on candidates understanding startup equity – in the interest of being transparent you should be clear how the vesting works, what the strike price is, what the exercise period is, and what percentage of the company the equity amounts to.  </span></li><li>Re: disclosing percentages vs number shares – just tell the candidate the percentage; trying to give a large sounding number of shares without explaining what it’s actually worth makes the offer harder to think about and is disingenuous.</li><li>One thing that can be helpful is showing what the equity would be worth in dollar terms in different exit scenarios.</li></ul>

<p><b>Have other folks reach out</b><span>.</span></p>

<ul><li><span>It’s a good idea to have the folks who interviewed the candidate reach out with short notes saying how excited they are and offering to answer questions.</span></li><li><span>Off for other people involved in the company (e.g. investors and advisors) to hop on a call and answer questions – having an outside perspective can be helpful for candidates</span></li></ul>

<p><b>Give the candidate some time, but don’t keep it open ended.</b></p>

<ul><li><span>There should be a date by which you and the candidate agree they will give you an answer.  I think 2-4 weeks from the day you give the offer is fair.</span></li><li>You want to give some time so the candidate gets to make an informed choice, doesn’t feel pressured, and, if they say “yes” it’s clear that the job is something they really want.</li><li>On the flip side, if it starts to really drag out what is probably happening is that they don’t want to work there that badly and they are probably using your offer as leverage in the rest of their interview process to ratchet up what they can get.<br />Having a lot of people that you’ve put the time into interviewing who are shopping your offer for something better is bad for morale at your company, and, if the candidate does eventually join, it can feel off for everyone (like they are attending their safety school).</li></ul>

<p><span>On the other hand, I don’t think it pays to be too aggressive in the deadline.  Don’t give an </span><a href="https://erikbern.com/2016/03/16/exploding-offers-are-bullshit.html"><span>exploding offer</span></a><span> – this is a good way to end up with a bad fit candidate and mess up the reputation of your company.  You might be able to strong-arm some people this way, but it’s really a shitty thing to do from a cultural perspective.  Fundamentally the candidate has the leverage in these situations and using a pressure sales tactic to try and reverse that is bad.</span></p>]]></content:encoded></item><item><title><![CDATA[Code-first vs. Product-first]]></title><description><![CDATA[There are two kinds of programmers, generally speaking. There are programmers who care more about code, and there are programmers who care more about product. The former – I’ll call them “code-first” programmers – are obsessed with how code is archit...]]></description><link>https://thezbook.com/code-first-vs-product-first</link><guid isPermaLink="true">https://thezbook.com/code-first-vs-product-first</guid><category><![CDATA[coding]]></category><category><![CDATA[Startups]]></category><category><![CDATA[software development]]></category><category><![CDATA[product]]></category><category><![CDATA[project management]]></category><dc:creator><![CDATA[Zach Lloyd]]></dc:creator><pubDate>Tue, 30 Apr 2019 07:57:25 GMT</pubDate><content:encoded><![CDATA[<p>There are two kinds of programmers, generally speaking. There are programmers who care more about code, and there are programmers who care more about product. The former – I’ll call them “code-first” programmers – are obsessed with how code is architected, what tools, libraries and languages are used, how much test coverage there is – stuff like that. Code-first programmers are psyched when they check in the perfect abstraction, when they get to use the latest language-feature, when they delete dead code. That is, they love the code they write – the code is the thing.</p>

<p>The product-first programmer cares about that stuff too, kind of, but only as a means to an end. For product-first programmers, the code is the scaffolding, the support, the steel beams in the building, but not the end product. The end product is, well, the product, not the code, and what matters to them is how well that product actually solves the underlying problem. Does the building stay upright? Do the elevators work? Is the A/C functioning? Do people like being there? Product-first programmers love building and launching and seeing users use what they’ve built. The product is the thing.</p>

<p>Anyone who has worked at a place like Google has met plenty of code-first programmers. They are the teammates who are always refactoring code and nit-picking spelling in your function comments. They are in the micro-kitchen complaining about “spaghetti code,” “technical debt,” and the lack of rigor in other teams’ code review processes. They are probably not fixing bugs or launching features. You can probably tell I’m not a huge fan of the code-first approach.</p>

<p>When I interview programmers I’m always amazed at how many of them seem to think the code-first approach is what I’m looking for. Trying to impress me, they ask: “What’s your unit test coverage like?” Pretty close to zero; this is a startup. “Do you guys use hot new technology X.” Not yet, no, how would that help us build the right thing faster? “Is there a lot of technical debt?” We will have to rewrite everything at some point, but it doesn’t matter right now because we haven’t even figured out the right thing to build.</p>

<p>They have an understandable but fundamental misconception of what programming is all about. Programming is about building products that solve problems for users not about writing beautiful code for its own sake.</p>

<p>And to be clear, this is true at all levels of the stack, whether your users are external customers, third-party developers, or internal consumers of an API. What matters is how the code works, not how the code looks.</p>

<p>Does that mean that I encourage writing bad code? That I don’t care about what technology we use or how the software is architected? Absolutely not – I care a lot! But I care because I believe if you make the right engineering choices, you will ultimately get to a better product.</p>

<p>I recently had an engineer I’m managing ask me how his code was. I responded by asking two questions back: “Did the feature work well?” and “Did you build it quickly?” “That’s what matters to me,” I said.</p>

<p>And typically, if the answers to those two questions are yes and yes, it’s likely (although not certain) that the code was actually pretty good, because good product usually implies good code. By definition the opposite doesn’t exist by the way – there is no such thing as good code that produces bad product.</p>

<p>I call this my rule of good code:</p>

<p><strong>If the product doesn’t work well, the code is not good.</strong></p>

<p>In other words, there is no such thing as good code in the abstract; good code can only exist if it’s producing a working product (again, define product loosely here to mean product at any level of the stack).</p>

<p>Over and over I see some engineers producing great product quickly, and when I see the code it’s usually well factored and smartly built. It’s not surprising since it’s hard to quickly build good product in a complicated system with code that is poorly architected or factored or not tested.</p>

<p>Conversely, when I see programmers not launching features quickly, the issue is often overengineering. Or when engineers do launch quickly but the quality is bad, then the issue is usually under-engineering or sloppy code.</p>

<p>There’s no zero sum game here: you should strive for good code, produced quickly, leading to great product. This is what great programmers produce.</p>

<img src="https://i0.wp.com/box5776.temp.domains/~thezbook/wp-content/uploads/2019/04/image-2019-04-26-at-11.57.10-am.png?resize=590%2C320" alt="Image 2019-04-26 at 11.57.10 AM" />

<p>The best programmers I know are product-first, but actually have more coding knowledge than the coding-first programmers. They know when to use the chainsaw vs the hand saw vs the chisel. When you need to really get something right (usually the deeper in the stack you are) vs. when you can fake it and just move quickly. When it’s better to just write a normal for-loop rather than a custom iterator. These choices and tradeoffs are what becoming a great programmer is all about, and the ultimate feedback mechanism is how well the product works.</p>]]></content:encoded></item><item><title><![CDATA[Host Interns]]></title><description><![CDATA[I love hosting engineering interns.  They get in early, they work on whatever you ask them to work on, and they usually seem to enjoy it, no matter what it is.  More often than not, they write good code, ask good questions, and make a positive contri...]]></description><link>https://thezbook.com/host-interns</link><guid isPermaLink="true">https://thezbook.com/host-interns</guid><category><![CDATA[Startups]]></category><category><![CDATA[hiring]]></category><category><![CDATA[internships]]></category><category><![CDATA[management]]></category><category><![CDATA[software development]]></category><dc:creator><![CDATA[Zach Lloyd]]></dc:creator><pubDate>Sun, 28 Apr 2019 05:48:40 GMT</pubDate><content:encoded><![CDATA[<p>I love hosting engineering interns.  They get in early, they work on whatever you ask them to work on, and they usually seem to enjoy it, no matter what it is.  More often than not, they write good code, ask good questions, and make a positive contribution to the team culture.  They cost relatively little, are easy to hire, and learn quickly.<br /></p>

<p>If you are an engineering manager and not hiring interns <strong>year round</strong>, you are making a mistake.  This is even more important at a startup where top talent is extremely hard to find.  If you are at Google, maybe it’s less important because of the abundance of full time talent.  But even at Google I found that interns often made outsize contributions.<br /></p>


<h2 id="heading-why-do-i-like-interns-so-much">Why do I like interns so much?</h2>
<p>There are a bunch of reasons.</p>
<h3 id="heading-interns-are-easy-to-hire">Interns are easy to hire.</h3>
<p>The way to do it is establish a relationship directly with the career placement office or computer science department at the schools you want to hire from.  When intern season comes, they will reach out to you directly about the hiring process.  If you are proactive you should be able to get a bunch of inbound traffic from students looking for summer jobs. <br /></p><p></p>
<p>The interview process for interns should be much lighter weight than for full time.  I recommend an initial phone screen with a hiring manager to get a feel for culture fit and baseline experience, followed by a short coding test and technical phone screen.  <br /></p>

<p>The main things you are looking for are (a) is this person going to fit culturally, (b) is their attitude good, (c) is their general intelligence high and (d) do they have enough baseline CS knowledge that they are not going to be in over their head in a professional setting.<br /></p>

<h3 id="heading-interns-are-available-year-round">Interns are available year round</h3>
<p>Look into schools that have CoOp programs like <a href="https://uwaterloo.ca/career-action/employers">Waterloo</a> and <a href="https://www.khoury.northeastern.edu/experiential-learning/employers/">Northeastern</a>.  I cannot recommend highly enough that you hire from Waterloo – we have had 10 excellent interns from there at my current company.  They are the same quality that you would find at a top eng school in the US, but are available all year.<br /></p><p></p>
<h3 id="heading-interns-will-work-on-anything">Interns will work on anything</h3>
<p>Most of what they are learning is how to be productive in a professional software development setting, so the particular tasks matter less.  They have not yet developed the sense of entitlement and need to work on particular tasks that ~some~ full time engineers get 🙂<br /></p><p></p>
<h3 id="heading-interns-are-fun">Interns are fun</h3>
<p>Most of them are, anyhow.  Having a rotating group of students who are learning how to code in the office is just plain fun.  They enjoy coding in a way that I remember enjoying it when I took my first CS class and stayed up all night coding my first project.  The positivity they bring improves the whole office.<br /></p><p></p>
<h3 id="heading-mentoring-interns-is-a-growth-opportunity-for-engineers">Mentoring interns is a growth opportunity for engineers</h3>
<p>Every intern should be managed by an engineer, usually one who is not already a manager.  It’s a great opportunity to train engineers to have their first reports.  I always have engineers successfully mentor interns before asking them to manage.<br /></p><p></p>
<h3 id="heading-interns-are-relatively-inexpensive">Interns are relatively inexpensive</h3>
<p>Good interns definitely are not free, and at first you might balk at what you have to pay.  At a minimum you will need to pay 50% of the rate you pay a junior engineer.  If you are competing against Facebook and Google, you will need to pay more (as of writing this, you might need to pay up to $7k/month).  <br /></p><p></p>
<p>However, if you are getting high-quality interns it’s worth it.  In my experience the best ones quickly become as productive as your junior engineers, for a much lower price.<br /></p>

<h3 id="heading-internships-are-a-pipeline-for-full-time-hiring">Internships are a pipeline for full time hiring</h3>
<p>I haven’t had quite as much success with this at my startup as we had at Google, but if you bring on interns and they have a great experience it’s definitely a leg up for hiring them post graduation.<br /></p><p></p>
<h2 id="heading-how-to-host-an-intern">How to host an intern</h2>
<p>It’s pretty easy, actually, but there are a few things to get right.</p>

<ul><li>Pair each intern with a <strong>dedicated mentor</strong>.  Every intern should have a host engineer to answer questions and meet with them regularly to check in on progress.</li><li><strong>Start interns on very small tasks</strong>.  Start with trivial bug fixes, followed by small features.</li><li><strong>Give every intern a “big” project</strong>.  After a few weeks, interns should get to focus on bigger, more impactful projects.<ul><li>DO: Make this project something that your product actually needs.  Interns should make a real impact.  </li><li>DO: Make it meaty enough that it’s anywhere from a few weeks to a couple months work in total.</li><li><strong>DO NOT: have the intern work on it alone.</strong>  This is a good way to end up with a project that you have to completely throw away because the code is written wrong.  Always have a real engineer working with an intern.</li><li>DO NOT: make this an experimental side project.  The best way to get the most out of interns is to have them work like real engineers on real projects that you actually need.</li></ul></li><li>Give frequent feedback.  Like you would for a full-time engineer.</li></ul>

<h2 id="heading-gotchas">Gotchas</h2>
<p>There are a few things to look out for to make sure your interns are net positive contributors.<br /></p>

<p>The biggest risk of hiring interns is that you will throw away their code.  I do not recommend that you put them on something that is outside of the main part of your code base, and I can’t emphasize enough that <strong>they should not work on their projects alone</strong>.  The unsuccessful internships I’ve hosted have always followed this pattern.<br /></p>

<p>A second risk is that an intern will unwittingly do something really costly, like bringing down your app.  This is on you, as an eng manager or host, to prevent.  It’s a real issue; at SelfMade, one of our interns accidentally deleted one of our production databases; another deleted our Facebook app.  <br /></p>

<p>Do not let interns work on super-sensitive parts of the code; lock down what actions they are able to take; carefully review their work, make them write tests, etc.  But the truth is I have seen senior engineers bring down services far more often than interns.<br /></p>

<p>The final risk is that interns won’t be productive and will be a net negative in terms of the resources needed to manage and train them.  This is possible if the interns you hire are too junior or not high caliber. You need to tackle this high up in the funnel by only getting interns from CS programs at good schools.  I’ve had some random high-school students intern and it was more work to clean up their code than if they had never written it.  <br /></p>

<h2 id="heading-secret-weapons">Secret Weapons</h2>
<p>We had so much success with interns at my last company that we thought of them as a sort of secret weapon, an advantage over our competitors in the war to get great engineering talent.<br /></p>
]]></content:encoded></item><item><title><![CDATA[Multiply by 𝝅]]></title><description><![CDATA[There’s no question that’s harder to answer as an engineer, eng manager, or PM, than “when is this project going to launch?” Honestly, the question is hard to answer because it’s hard to actually know. And generally, the bigger the project, the large...]]></description><link>https://thezbook.com/multiply-by-f0-9d-9d-85</link><guid isPermaLink="true">https://thezbook.com/multiply-by-f0-9d-9d-85</guid><category><![CDATA[Startups]]></category><category><![CDATA[management]]></category><category><![CDATA[project management]]></category><category><![CDATA[planning]]></category><category><![CDATA[software development]]></category><dc:creator><![CDATA[Zach Lloyd]]></dc:creator><pubDate>Fri, 19 Apr 2019 07:18:37 GMT</pubDate><content:encoded><![CDATA[<p>There’s no question that’s harder to answer as an engineer, eng manager, or PM, than “when is this project going to launch?” Honestly, the question is hard to answer because it’s hard to actually know. And generally, the bigger the project, the larger the uncertainty. This is doubly unsatisfying because big features are most anticipated and folks are most disappointed when they run late, as they usually do.</p>

<p>I led a project at Google that was over a year late. Granted, it was a big project – a rewrite of Google Sheets. But I was off by a whole year, which seems crazy in retrospect. How did this happen?</p>

<p>I made a few mistakes right at the outset.</p>

<p>I, like most engineers, have a bias towards optimism in my coding ability. I thought my and my team’s code wasn’t going to have as many bugs as it ended up having. I misjudged the number of tasks we had to complete. I underestimated the number of external dependencies we had. And so on… it’s just a lot easier to think of what you need to do if the project goes perfectly than if things go wrong.</p>

<p>I also over-promised to get buy-in. I’m typically pretty reserved in making promises, but for big projects there is a built-in incentive to say they are going to go as well as possible and under-represent the risks. If you give too conservative of a timeline you run the risk of not getting the go-ahead from decision makers – no one wants to fund a 4-year software project (for good reason).</p>

<p>I also just flat out didn’t think through how much work was really going to be involved.</p>

<p>During the first internship I ever had – at a dot-com-bubble company that’s long since gone – the CTO spoke to this question. He said “Here’s how I estimate: I take whatever time the engineer says and multiply by 𝝅. Why 𝝅? Because it’s more fun than 3, so why not?” I thought it was really weird at the time.</p>

<p>Almost 20 years later, the multiply by 𝝅 rule seems pretty accurate. I’ve seen very, very few projects or large features launch on time, but scores that have taken over 𝝅x as long as they were supposed to.</p>

<p>Projects tend to start slow. When we first started on the Sheets rewrite we wanted to do everything The Right WayTM. All our classes were perfect. We agonized over code reviews. We were determined not to make the mistakes of the prior version. Of course, all of this “perfection” came at a cost of time. But at the beginning the time pressure wasn’t intense, so it seemed fine.</p>

<p>As we got further along, we started to lose the luxury of time. Stuff came up that we couldn’t or didn’t foresee. A year into the project we realized the performance of our new architecture was actually way worse than expected, worse than the version we were replacing. Oops.</p>

<p>We had to stop all forward progress and spend the next four months working on speeding up the app (thankfully we were able to). It would have been hard to plan for this particular issue, but I should have seen the risk of something like this happening.</p>

<p>The specifics vary, but the general pattern is the same – shit happens and your project gets delayed. And once it’s delayed, there’s usually no way to get it back on schedule. The instinct around adding more engineers usually ends up in Mythical Man Month-land slowing things down further. The best thing is often to just start cutting features. No one really likes this though.</p>

<p>How can you minimize the risk in the first place? Ever since the sheets rewrite, I always start by taking the project’s big tasks and breaking them into smaller ones. However, the idea is not that you get to a more accurate estimate of the big task by dividing it into smaller ones and adding them up.</p>

<p>The idea is more that by breaking up the big tasks you can get a better sense of the true surface area of your feature or project – it’s a reality check.</p>

<p>For our Sheets rewrite I would have ended up with a huge list of features, functions, and so on – everything that goes into a spreadsheet app from the UI of formula editing, to pivot tables, to sorting, and so on. I couldn’t have really said that writing pivot tables was going to take X weeks and charts Y months with any accuracy. But by looking at those features I could have realized at some subconscious level how big the effort really was. I should have been more scared.</p>

<p>As an aside, “divide and add up” is not a good estimation method. The problem is that most of the time in software development isn’t spent writing code for features. It’s spent in integration, debugging, testing, handling changing requirements and so on.</p>

<p>There’s an 80/20 rule at play here, and goes against the instincts of the estimator – the 80% is spent after the initial code is written, but it’s very hard to list out how this time will be spent beforehand. When you divide and add up you leave out those hard-to-name tasks and end up with an underestimate.</p>


<h2 id="heading-deadlines">Deadlines</h2>
<p>So what’s the actual way to deliver on time? Unfortunately, the best thing I’ve seen is to set a deadline.</p>

<p>I say “unfortunately” because from the developer’s perspective, deadlines suck. Developers tend to think things “take as long as they take” and adding on an arbitrary date doesn’t change the fact that the software takes a certain amount of time to write and debug. It just adds pressure. It creates a death march mentality.</p>

<p>I totally get this perspective.</p>

<p>However, setting a launch deadline and orienting the team around it has all sorts of benefits that actually do move projects along faster.</p>

<p>The proper way to set a deadline is to establish the “when” and leave a little bit of flexibility for the engineering team around the “what;” meaning you say that product/feature X needs to launch by day Y, but there is some flexibility around what exactly will launch depending on what is feasible. But the goals should be aggressive.</p>

<p>Once you have a deadline, time becomes a limited resource; you become more conscious of wasting it.</p>

<p>Deadlines let you backtime; if the deadline is date X, then you know you need to have rolled out to internal testers by X – 4 weeks, and that means the code needs to be complete by X – 8 weeks, and so on, which means your first feature needs to be done in 2 weeks. Better start coding!</p>

<p>Deadlines create competitive motivation. You don’t want to be the sole engineer on the team who makes the project ship late.</p>

<p>Immovable deadlines really motivate. If your deadline is tied to a public facing event (say Google IO or the launch of GDPR), then you most likely will have something ready to ship.</p>

<p>The issue, of course, is that deadlines can seem arbitrary and if you use them too often it ends up feeling to engineers like a never ending emergency.</p>

<p>The best way to overcome this is to:</p>

<ul><li>Not always be in deadline mode – sometimes there needs to be space for exploration, design, cleanup etc.</li><li>Save deadlines for the most important features</li><li>Try to pick deadlines that have a plausible business rationale (e.g. an external conference or a competitor releasing a product)</li><li>Get the leaders on the team totally bought in on the deadline and make it a fun cultural thing (print tee shirts, and so on)</li><li>Make the deadline as realistic as you can without sandbagging</li></ul>

<p>In retrospect, I wish our Sheets rewrite had a deadline. I bet we could have gotten it done at least six months sooner. There would have still been unforeseen issues, feature cutting, and so on, but we would have approached the whole project with a greater sense of urgency and clearer prioritization from the get-go.</p>

<p>Also, be careful of rewrites in general! That’s a subject for another post though…</p>]]></content:encoded></item><item><title><![CDATA[Coding]]></title><description><![CDATA[How to make a change to a shared codebase
When multiple developers are working on the same codebase, it’s important that everyone follow the same procedure for making changes.  This is software engineering 101, but the details matter and new engineer...]]></description><link>https://thezbook.com/coding</link><guid isPermaLink="true">https://thezbook.com/coding</guid><category><![CDATA[Startups]]></category><category><![CDATA[software development]]></category><category><![CDATA[code review]]></category><category><![CDATA[code]]></category><category><![CDATA[coding]]></category><dc:creator><![CDATA[Zach Lloyd]]></dc:creator><pubDate>Fri, 01 Mar 2019 08:46:49 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-how-to-make-a-change-to-a-shared-codebase">How to make a change to a shared codebase</h2>
<p>When multiple developers are working on the same codebase, it’s important that everyone follow the same procedure for making changes.  This is software engineering 101, but the details matter and new engineers don’t always come out of school knowing how to do this.<br /></p>

<p>Here’s how I have done it with my teams in the past.  <br /></p>

<p>Let’s assume for simplicity’s sake that we have the following set up (if you don’t have something like this, then start by getting it in place):</p>

<ul>
<li>Your code is stored in some shared repo, say Github.</li>
<li>Everyone is using git or something similar for version control.</li>
<li>There is a continuous build, test and deployment system.</li>
<li>There are at least three environments code can run in: local (not committed), staging (not real users, but hosted in a prod-like environment), and production.</li>
<li>The goal is to write and test code locally, test it in staging with real-ish data and services and other pending changes, and push it to production as quickly as possible and with as few bugs as possible.</li>
</ul>
<p>How to make a change?  Bear with me if this seems basic – i’ll add some color below.</p>

<ol>
<li><strong>Create a local branch</strong> off whatever your team’s “head” branch is.  Usually this is <em>develop</em> if you are using <a href="https://datasift.github.io/gitflow/IntroducingGitFlow.html">gitflow</a>, but it could also be <em>master</em> or some other branch.  It’s where the up to date code lives and features and bug fixes start from.</li>
<li>Make a <strong>small, incremental change</strong>, test it locally, push it to staging and test there.</li>
<li><strong>Review your own code</strong> before sending it to someone else to review.</li>
<li><strong>Assign a code reviewer</strong> and ask them for a code review.</li>
<li><strong>Respond to or acknowledge every code review comment</strong> from the reviewer and ask them to look again until they approve.</li>
<li><strong>Deploy your code to production</strong> and merge the branch into master.</li>
<li>Repeat.</li>
</ol>
<p>That’s the basic procedure.  Here are the rules on how to do this workflow well…</p>

<h2 id="heading-writing-code">Writing Code</h2>
<h3 id="heading-incremental-changes">Incremental changes</h3>
<p>Changes should be as small as possible while still doing something meaningful; small, incremental changes are</p>
<ul>
<li>Easier to review: it’s easier for a reviewer to grok a small change and also less of an interrupt so you are likely to get a review more quickly</li>
<li>Easier to test: smaller changes mean less surface area for testing and more confidence that they work</li>
<li>Less likely to have merge conflicts when you sync locally</li>
<li>Less likely to cause merge conflicts for others when you submit</li>
<li>Easier to roll back</li>
<li>Pretty much better in every respect</li>
</ul>
<p>But don’t make the change so small that the overhead of the review and commit would make it make sense for the change to be bigger. <strong>Be pragmatic.</strong></p>
<h3 id="heading-feature-flags">Feature-flags</h3>
<p>Use feature-flags or some similar mechanism to check-in incomplete code</p>
<ul><li>The most common reason I see big changes is because engineers don’t want to check in half-working code.  Feature-flags are the solution here.</li><li>It’s fine for code that is not fully functional to be committed so long as it is not executed.</li><li>Feature flags also have other important uses for staged rollouts and canarying, so it’s good to get them in place right from the start.</li></ul>


<h3 id="heading-thoroughly-test-your-own-code">Thoroughly test your own code</h3>
<ul><li>If you’re fortunate enough to have support in the form of a QA team or a group of manual testers, that’s great, but ultimately <strong>you are responsible for the quality of what you launch</strong>.</li></ul>


<h3 id="heading-get-code-reviewed-early-on">Get code reviewed early on</h3>
<ul><li><strong>The beginning of a feature is the most important time to get a code review</strong>.  It is preferable to make an initial commit on a new feature as early as possible because most of the important design decisions are made at the beginning of implementing it.  </li><li>A common mistake I see in feature development is not getting the code reviewed until way too much of it has been written, at which point it becomes much more painful to adjust in case a reviewer requests a big design change.</li><li>I’ve seen a lot of sub-par code checked in because the initial change was too big and the author didn’t want to redo it and the code reviewer didn’t want to push the author because of the amount of time it would take.  That’s a bad outcome.</li></ul>

<h3 id="heading-dont-group-unrelated-changes-in-a-single-review">Don’t group unrelated changes in a single review</h3>
<ul><li>It makes the change harder for a reviewer to understand.</li><li>It makes it harder to selectively roll back if one part of it causes an issue but the other part is fine.</li><li>But again, be pragmatic.  You don’t need to send five distinct code reviews if that would end up taking everyone a lot more time.</li></ul>

<h3 id="heading-code-should-make-it-all-the-way-to-head-on-every-review">Code should make it all the way to head on every review</h3>
<ul><li>Don’t have code incrementally reviewed on a single branch as you build out a feature and then submit that one branch once the feature is fully built</li><li>This leads to committing one big change at the end, which, for reasons stated above, is bad</li><li>Use feature-flags to submit incomplete code – that way you can separate committing and pushing the code from enabling the code.</li></ul>

<h3 id="heading-keep-working-while-your-code-is-being-reviewed">Keep working while your code is being reviewed</h3>
<ul><li>The technique I recommend is “branching off of your current branch” to keep going. </li><li>E.g. if you are having “feature_branch” reviewed, then you should locally do “git checkout -b feature_branch_2” from feature_branch and keep working. </li><li>As you make changes for the initial review in “feature_branch” you merge them into feature_branch_2 so it picks them up. </li><li>Finally, when you submit feature_branch, you merge master into feature_branch_2 and it becomes the next thing you have reviewed.</li></ul>

<h3 id="heading-do-not-share-feature-branches">Do not share feature branches</h3>
<ul><li>Under no circumstances should engineers share feature branches.  By “sharing”, I mean if two or more engineers are working on a single feature off of a non-head branch.  </li><li>There are many reasons this is a bad idea, but the primary one is that this encourages the submission of very large changes, and for the reasons listed above, large changes are bad.</li><li>It also makes it hard for other engineers on the team to review code early enough to catch errors.</li></ul>

<h3 id="heading-use-a-linter-for-enforcing-style">Use a linter for enforcing style</h3>
<ul><li>Using a linter like <a href="https://eslint.org/">eslint</a> or <a href="https://prettier.io/">prettier</a> that enforces a particular code style saves a lot of time commenting on style issues in code reviews and also keeps the code consistent.</li><li>I’ve seen teams put in presubmit checks that verify the code style is followed.  I don’t recommend this because it’s likely to annoy anyone external to your team who is trying to make a small fix in your codebase and doesn’t have your linter configured.  Either make it so the linting is automatic or don’t rigorously enforce at check in time.  Someone will fix it on the next PR.</li></ul>

<h2 id="heading-code-reviews">Code reviews</h2>
<p>Code reviews are <em>the</em> most important quality check there is in writing new code.  If there is one quality control practice I would prioritize above all others it’s a culture of good code reviewing.</p>
<h3 id="heading-for-the-author">For the author</h3>
<ul>
<li>Always merge master into your feature branch before starting the review process – otherwise your diff might show spurious changes and you could end up with a change that needs merge conflict resolution after the review</li>
<li><strong>Review your own code before you ask someone else to review it!  </strong>Make sure what you present to the code reviewer doesn’t have changes you know you should make.</li>
<li><strong>Do not expect code reviewers to find bugs!</strong>  They sometimes will, but that is not their job.</li>
<li>Assign the review to the person who knows the area of code you are working on best, not the person who does the easiest reviews.  But try to spread your reviews around if you can.</li>
<li>New team members should act as “secondary” reviewers on a bunch of code reviews before reviewing code on their own.  </li>
<li>If you are really trying to scale a codebase, you can introduce a concept of “readability;” any engineer who has “readability” in a programming language is allowed to approve a change on his or her own.  Otherwise, they need another reviewer to approve. Google has this process in place, but they also have a huge codebase they are trying to scale.  I would not recommend this for a startup.</li>
<li>Continue working by branching off of your feature branch while you are waiting.  This is a powerful way not to get blocked.  See the technique of branching off a branch above.</li>
<li>If you are blocked on a review, you should be aggressive in pinging the reviewer, and, if that doesn’t work, a manager.  <strong>Fast code reviewing is a key part of a healthy team and everyone should feel responsible for reviewing code quickly.  </strong>Speed of review is inversely correlated with the size of the change, so if you want your changes reviewed quickly, keep them small.</li>
<li>When a review comes back, address every comment, even if just acknowledging that you made the suggested change.</li>
<li>Test your code again after you have made the suggested changes!  Blindly commiting the reviewer’s suggested change is a common source of bugs and build breaks.</li>
<li>Code reviews from more senior engineers are how you become a better coder – remember that.  Don’t get defensive when an engineer requests changes.</li></ul>

<h3 id="heading-for-the-reviewer">For the reviewer</h3>
<ul>
<li><strong>Treat code reviews as high priority.</strong>  If you can’t immediately direct your attention to the review, you should let the author know when you expect to get to it.  I don’t think any review should sit for more than a couple hours unaddressed.</li>
<li><strong>Focus on design issues first and foremost. </strong> The most impactful reviews ask a few key questions about design issues that are likely to cause problems down the line if not addressed early on.</li>
<li>Keep the tone focused on learning and improvement and not critical.  Engineers are sensitive about criticism and the more you focus on making the code better and not pointing out what someone has done wrong, the better – i usually frame my feedback as suggestions.</li>
</ul>
<p>Example good feedback:</p>
<ul>
<li>“It looks like this might run in n^2 time – is there a way to make it linear?”
“I think this is making a network call within a tight loop.  Maybe add a bulk api on the server side so you can do the work in one call?”
“I’d think about putting all of these methods into their own class and memoizing the calls if you can”</li>
</ul>
<p>And not so good feedback:</p>
<ul>
<li>“Style guide for JS Doc calls for two newlines between top level file comments.”</li>
<li>“NPE”</li>
<li>“I didn’t understand how this worked but if you’re sure it produces the right results, then ok.”</li>
</ul>
<h2 id="heading-presubmit-checks">Presubmit checks</h2>
<ul><li>A “presubmit” check is a trigger that automatically runs <em>before</em> your code gets merged and deployed.</li><li>Examples of presubmit checks are scripts that check the formatting and linting of code, ones that check the code has been reviewed, etc.</li><li>The most valuable presubmit routine you can have is one that takes the code you are about to merge, integrates it into the production “head” in another sandbox environment, and builds and runs all of your tests against it.  The important thing is that this happens <em>before</em> the code is merged, so you avoid breaking the build and tests.</li><li>See this awesome <a href="https://blog.bubble.is/look-ma-no-master-decentralized-integration-3706d43d5c86">post</a> by Josh Haas on how they implement this at Bubble.</li></ul>

<h2 id="heading-after-submitting-and-pushing-the-code">After submitting and pushing the code</h2>
<ul><li>Code is almost never “done.”  There are always bugs that arise, which brings me to my next point…</li><li><strong>FIX YOUR BUGS. </strong>If you push a bug, fix it. If you create a bug somewhere else in the product because of your change, fix it or roll back your change.  Great engineers are always fixing not only their own bugs but other bugs they find in the product.</li></ul>

<p><strong>IF YOU BREAK A BUILD, ROLL BACK.</strong>  This depends somewhat on the nature of the break, but a broken build slows everyone down and your default should be to roll back your change rather than trying to roll forward with a fix.</p>
]]></content:encoded></item><item><title><![CDATA[Planning]]></title><description><![CDATA[So you’ve decided on the general outlines of what you want to build.  You have an engineering team, designers, PMs.  It’s time to figure out who works on what, what order to build things in, what you are really building, and so on.  It’s time to get ...]]></description><link>https://thezbook.com/planning</link><guid isPermaLink="true">https://thezbook.com/planning</guid><category><![CDATA[Startups]]></category><category><![CDATA[management]]></category><category><![CDATA[project management]]></category><category><![CDATA[planning]]></category><category><![CDATA[software development]]></category><dc:creator><![CDATA[Zach Lloyd]]></dc:creator><pubDate>Fri, 01 Mar 2019 08:06:32 GMT</pubDate><content:encoded><![CDATA[<p>So you’ve decided on the general outlines of what you want to build.  You have an engineering team, designers, PMs.  It’s time to figure out who works on what, what order to build things in, what you are really building, and so on.  It’s time to get to the nitty gritty of building a product.<br /></p>

<p>What’s the best way to actually do this?  There are a lot of methodologies out there – agile, scrum, kanban, waterfall, and so on.  I don’t really subscribe to any of them, but instead I can tell you the general outlines of what I’ve done in the past, some principals that work, some pitfalls to look out for.<br /></p>


<h2 id="heading-okrs">OKRs</h2>
<p>Let’s start with the question of goal setting.  <br /></p>

<p>A good practice that I took away from Google is starting with quarterly <a href="https://en.wikipedia.org/wiki/OKR">OKR</a>s.  OKRs stand for “objectives and key results.”  You make a list of the things you want the team to get done (e.g. improve onboarding) and for each one of those things specify the metric that lets you measure it (e.g. % of users who complete onboarding goes from 60% to 80%).  <br /></p>

<p>These Objectives should generally be <em>outcome</em> driven goals (e.g. improve performance, improve conversion, improve customer satisfaction) rather than <em>output</em> goals (e.g. minimize JS, put button in a different spot on page; add chat widget to homepage).  <br /></p>

<p>The Key Results can be numeric metrics (if possible) or output oriented if it’s not yet possible to attach a reasonable number to the goal.  If you are too early in your development process then the result you are shooting for might just be building and launching the thing, rather than moving a metric. <br /></p>

<p>Here are some OKRs from my last company:<br /></p>

<ul><li><strong>Improve our ability to edit photos to match a customer’s brand</strong><ul><li>Increase positive outcome rate to 70%</li><li>Reduce revisions citing “Doesn’t match style” to 3%</li></ul></li><li><strong>Improve the performance of our image specialists</strong><ul><li>Increase positive outcome rate to 70%</li><li>Reduce revisions citing “Looks fake” or “Didn’t follow my instructions” to 10%</li></ul></li><li><strong>Improve the growth rate of our customers and their engagement in our app</strong><ul><li>Increase % of members using the planner weekly to 50%</li><li>Increase median time in app to 4:00</li><li>Increase members’ followers by 10% MoM (median)</li></ul></li></ul>

<p>Notice that we were going for very specific changes in metrics.  I’ll speak more to the question of whether you should be prioritizing completing features or driving customer outcomes in a bit.<br /></p>

<p>You make this list at the beginning of the quarter and spend the next three months working on it and tracking your progress.  You’ll want to check on how you are tracking on these goals every month at a minimum.  Importantly, at the end of the quarter, before making your next list you go back and grade yourself on how you did on the last one.  <br /></p>

<p>The grades should be pretty high-level; I like to use a green/yellow/red framework: green = you nailed it; yellow = some progress but incomplete; red = you missed it.  The grading keeps you accountable to yourself and the rest of the company.<br /></p>

<p>Quarterly OKRs should not appear out of thin air as a diktat of a single product leader.   Instead there should be a collaborative process for arriving at them.  The exact process doesn’t matter that much, but it needs to synthesize data from a lot of different points.<br /></p>

<p>Those data points ideally include input from users, engineers, PMs, designers, sales, marketing, and other stakeholders.  Common ways of getting this data are surveys, retros, feedback-emails, bug reports, NPS surveys, etc.<br /></p>

<p>Good ideas come from everywhere and gathering input with a wide net is a good idea.  But, at the end of the day, someone needs to decide what the real priorities are and be able to justify them to the larger team.  <br /></p>

<p>Deciding what not to do is just as important as deciding what to do.<br /></p>

<p>At a small startup the ultimate decider is the CEO or CTO.  At a bigger one it might be a VP of Product or Engineering.  At a place like Google it’s typically the tech lead, eng manager or PM.  OKRs roll up through an organization, so there will be OKRs of increasing scope the higher up in the org you get.<br /></p>

<p>The way the decider should pick what to work on is by looking at a lot of different factors and arriving at a stack rank.  Then you choose as many of the items from the top of the list as you have resources to get done.<br /></p>

<p>And these decisions should happen pretty quickly.  If you are spending more than a week or at most two deciding on what to work on, then you are spending too long.  You need to <a href="https://www.fastcompany.com/3049164/how-to-make-decisions-more-efficiently">move fast</a>.<br /></p>

<p>Which brings me to the topic of prioritization…<br /></p>

<h2 id="heading-prioritization">Prioritization</h2>
<p>I’ve had to prioritize a lot of projects and the only thing I’m certain of on the topic is that no matter how you prioritize someone is going to think you are doing it wrong.  <br /></p>

<p>To start, let’s admit that prioritization is a hard problem, and you are not going to come up with a perfect solution. You will never know if the priority order you came up with was the right one.  <br /></p>

<p>The best you can do is use a reasonable framework and come up with your best guess and get on with building.  <br /></p>

<p>That said, it’s good to start by judging candidate projects along a few big dimensions:</p>

<ul><li><strong>Impact</strong>: how big of a deal will it be if you get the project done – how much does it help you hit the OKR?</li><li><strong>Effort</strong>: How much work is it? How long will it take?</li><li><strong>Risk</strong>: Can you actually build it?  And, if you do, are you sure it will achieve the desired outcome?</li><li><strong>Definition</strong>: How scoped is the work?  Do you actually know what you want to build?</li><li><strong>Resources</strong>: Do you have the right resources available to work on the project?</li></ul>

<p>E.g. say you are building an asset library for a photo editing tool.  You might weigh one feature that lets users find content on the web and upload it themselves against another that uses machine learning to find and identify content.  The first would probably be lower risk and lower effort, but also lower impact.  The second (the ML solution) could be risky, take longer and be harder to scope but might have a bigger payoff.  It also might require special resources in terms of engineering talent and data.<br /></p>

<p>The goal, per above, is to make sure you hit the OKRs.  Typically you do this by maximizing impact and reducing effort and risk.  In our hypothetical asset library example you would weigh the difference in impact, effort, etc and make a judgement call on whether the extra risk and effort was worth the payoff.<br /></p>


<h2 id="heading-the-real-world-is-messy">The Real World is Messy</h2>
<p>In the real world though things are rarely so simple and if you do prioritization just based on the above, you’re likely to land in a world of pain.  There are other things to consider…<br /></p>

<p>You need to make sure the engineers on the team are <strong>happy</strong> and working on things they find interesting.  If you don’t you may have attrition.  You also will have less productivity as engineers stop working as hard, start coming in late, feel demotivated and so on.  You want <a href="https://svpg.com/missionaries-vs-mercenaries/">missionaries not mercenaries</a> on your team.<br /></p>

<p>You need to make sure that engineers are on a <strong>growth path</strong> and being prepared for promotion at some point.  Every engineer wants better skills, a higher salary, and more responsibility.  Some projects lend themselves more to growth than others.<br /></p>

<p><strong>You don’t want anyone idling</strong>.  Everyone should be engaged in productive work at all times.  This can be tough to manage because the features you most want people working on might not be specced for a while.  If specs aren’t ready, you can also have engineers working on the product discovery process by prototyping and feasibility testing.<br /></p>

<p>You want to make sure that <strong>pressing bugs</strong> and other one-off issues are addressed.  Often these will not fit neatly under one of your OKRs, but you still need to fix them.<br /></p>

<p>You want to be <strong>flexible</strong> enough that if some new but important issue arises you aren’t slavishly following the OKRs.  This happens all the time at startups.<br /></p>

<p>You want <strong>redundancy</strong> in who knows different areas of the codebase in case an engineer decides to move on.<br /></p>

<p>You have to accommodate <strong>vacation, parental leaves, sick days</strong>.<br /></p>

<p>You have to recognize that <strong>engineers are not fungible</strong>.  They know different parts of the stack, different technologies, different parts of the codebase, and will work on projects at different rates with different quality outputs.<br /></p>

<p>You sometimes need to build things to increase company value in some strategic way that might not be directly tied to a user story (say for an investor demo).<br /></p>

<p>The things you build can’t just be the product of a stack rank.  They need to blend into a <strong>cohesive</strong> product.<br /></p>

<p>You may want to bundle certain features for a specific launch.<br /></p>

<p>And so on…<br /></p>

<p>In short, figuring out who should work on what, and in what order, is a big constraint maximization problem that has no clear best answer.  Putting together a simple spreadsheet that weighs the options can be helpful, and I recommend it.  <br /></p>

<p>At the end of the day, you want a set of goals that are high impact, cohesive, and the team can rally behind.  You want something that can be packaged into a neat effort that you can attach a launch deadline to.  The results should be measurable and something everyone on the team can work towards. <br /></p>

<p>But ultimately it’s a judgement call to be made (and defended) by the product decider.  Like I said, someone is going to be unhappy.  But it’s your job to get agreement to move the project forward if not agreement on the actual priorities.<br /></p>


<h2 id="heading-week-by-week-sprints">Week by Week – Sprints</h2>
<p>Once you have your overall priorities and roadmap set, it’s time to start working on a week by week cadence.<br /></p>

<p>What has worked best for my teams in the past is dividing up tasks into weekly sprints.  Two-week sprints are ok as well.  Every sprint should be kicked off by a short weekly meeting where each engineer and designer publicly commits to what they are going to get done that week.<br /></p>

<p>A few points here:</p>

<ul><li>The things that you want to get done that week should be visible in some public place.  It could be a shared spreadsheet, a tool like Asana or Trello or Jira, or just a plain document.  Don’t obsess on the format.  What matters is that it’s visible to all.</li><li>It’s important to start the week with everyone publicly saying to the whole team that they are going to get X done.  For more senior engineers on the team, they should be coming up themselves with what X is.  For less senior folks, the engineering manager should assign tasks and communicate them   Either way it’s important that the engineers themselves commit. This creates <strong>accountability within the team</strong>.</li><li>X should be sized appropriately for a week.  This can be tricky, but check with the engineer or designer to make your best guess.  I’ve tried to use point systems or other sizing methodologies, but I have never found them to work particularly well.  But I’m not against them.  Be pragmatic and don’t get caught up looking for the perfect process.</li><li>X should be scoped and defined so that everyone knows what it actually is.</li></ul>

<p>Here’s an example weekly task list from my last company:<br /></p>

<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647493433722/E6_x7XsV2.webp" alt="image-2019-04-30-at-4.22.55-pm.webp" /></p>
<p>As mentioned, the exact format doesn’t much matter – this one was a google doc that linked out to Asana tasks that had more granular detail on the tasks.  We could have done this same type of list in a spreadsheet or in Asana itself, but we liked the simplicity and readability of the Google Doc.<br /></p>

<p>After the engineers and designers have made their commitments for the week, I suggest sending them to some larger group outside of the product team.  This could be a higher up manager, the sales or marketing team, the CEO, etc.  Sending the weekly plan outside of the product team creates <strong>whole team accountability</strong> and gives visibility as to what is currently being worked on.<br /></p>

<p>The thing you send should also <strong>highlight what you got done last week</strong>.<br /></p>



<h2 id="heading-day-by-day-the-daily-standup">Day by Day – The Daily Standup</h2>
<p>I recommend starting every day except the day of the product team meeting with a short team standup.  I’ve seen standups work a number of ways (and not work at all).<br /></p>

<p>The point of the standup is to discover issues that could prevent folks from reaching their weekly goal.  It’s the main tool an engineering manager and PM has for understanding what is going on, what is blocking the team, etc.<br /></p>

<p>The mechanics are simple: get every person on product team in the same room in the morning at a fixed time and have each person say:</p>

<ol><li>What they got done yesterday</li><li>What they are going to get done today</li><li>What they are blocked on or need help with</li><li>And that’s it.</li></ol>

<p>Each person should talk for less than 30 seconds.<br /></p>

<p>Good issues to surface:</p>

<ul><li>Engineers blocked on code reviews</li><li>Engineers blocked on design input / not sure how to build something</li><li>Engineers stuck on difficult bugs and needing help</li><li>Engineers being behind on tasks and needing help</li><li>Engineers and dev/ops stuck on deployment cycles and bad merges</li><li>Designers needing input and/or feedback</li><li>Two people working on the same thing by accident</li><li>Two people working in a way likely to cause a conflict</li><li>Bad bugs that have come in during the week and how they are being fixed</li></ul>

<p>Things to look out for:</p>

<ul><li>Do not get into deep technical discussions in standups.  Anytime this is happening you should move the discussion to after the standup.</li><li>Do not try to define features or debate priorities during standup.  Keep things short.</li></ul>

<p>The standup is the main way that engineering managers and PMs are able to see if the team is on track for the week.  If not, it’s an appropriate time to adjust and rebalance tasks, unblock folks, and so on.<br /></p>

<p><strong>Standups tend to deteriorate in attendance and quality over time</strong>.  I’ve seen this again and again.  Engineers start coming in late, the standup gets cancelled a few days when lots of folks are out, the standup goes badly a few times, standup updates start to come in via slack rather than in person.<br /></p>

<p>When this happens <strong>it is the job of the team leaders to get it back on track</strong>.  The standup deteriorates because engineers would rather not do it.  It requires them coming in at a fixed time, it pulls them away from their computers and forces them to talk in front of a group.  But it’s important to do because without it, you, as a leader, will not know what’s going on with the team.<br /></p>

<p>At my last company I literally resorted to taking attendance.  Each engineer had a “standup streak:” the number of consecutive standups they had attended in a row.  There were rewards for hitting certain milestones – ten straight standups got you a free coffee, and so on.  It felt like elementary school, but, when we pushed it, it worked.<br /></p>

<p>A few folks have asked what I have against Slack standups.  I’ll probably write a section on when I think Slack is appropriate (not that often), but I definitely don’t like it for standups because:</p>

<ol><li>Slack updates aren’t interactive in the same way as in person – it’s much harder to ask questions quickly</li><li>New slack messages push the standup updates out of the window (i find this to be a general issue with any kind of group slack)</li><li>They tend not to all come at the same time, which causes the standup to actually take longer and cause more distraction</li></ol>


<h2 id="heading-the-perfect-process">The Perfect Process</h2>
<p>As an aside, I’ve come across many folks in the product world whom I consider overly-dogmatic about product process.  People tend to hold something like religious beliefs on how things need to be done.  <br /></p>

<p>This is not me.  I’ve tried a lot of different systems, tools, and so on, and what I think works best is a pragmatic approach.  Do what makes the most sense in the context of your product, team, stage, company, culture and so on.<br /></p>

<p>For instance, if you are a very early stage startup with no product, it doesn’t make a lot of sense to base your OKRs on moving customer metrics.  You should base your OKRs on getting your <a href="https://blog.leanstack.com/minimum-viable-product-mvp-7e280b0b9418">MVP</a> built as quickly as possible.  The Key Results should be MVP features.<br /></p>

<p>The specific product planning tools you use rarely matter in my experience.  At Google, it was a set of in-house tools.  Externally I have used Asana, spreadsheets, documents, github tasks.  The more advanced tools have various bells and whistles, which can enable some advanced workflows.<br /></p>

<p>What actually matters is commitment to a process and constant vigilance by the management.  And more than that, what matters is the culture you build.  If the culture favors pragmatism and a commitment to putting the user first, then you will likely be successful no matter what the particulars of the process are.</p>
]]></content:encoded></item></channel></rss>