In an early stage company, the practices differ from industry standard established for more mature organizations. Here’s a handful of notes on what made my journey as lead engineer at Agentnoon (YC W22) successful. This is how I think about engineering, team dynamics and technical decisions that allow a small team to outperform huge orgs.

  • The greatest advantage is a lean stack, speed of execution and ability to deliver delightful product that’s easy to use.
  • At the highest level, engineer’s job is about managing complexity. The simpler the output, the better:
    • eliminate scope or special cases in a feature design phase (either from UX or technical perspective)
    • encapsulate complexity in modules with simple interfaces
      • a need to write the “ugly and complex code” is inevitable. Make sure that complexity of specific module doesn’t spill over to other modules that communicate with it
      • example: ppt export that is a high complexity module should only require a simple dataset to perform the complex operation of generating a file, limiting the number of dependencies on other concepts in the app
    • follow existing codebase patterns to reduce cognitive load for developers working with the code
  • A small team needs to live with suboptimal decisions and pick its fights
    • it’s important to prioritise and know which areas have highest ROI in relation to time spent on them
  • A startup is in a process of iterative, bottom‐up organizational learning
    • every day we learn more about the domain and customers needs
    • the code needs to reflect that: be flexible, simple and open for change
  • Start with the lightest weight solutions and only progress towards massive solutions as earlier efforts collapse under scale
    • do the easy thing first – build things with enough complexity to convey value and offer top notch UX, but simple enough that they are shipped fast and can be verified out in the wild.
    • Bad product engineers cut too many corners but great ones know that minimum loveable products need the right depth to be considered during the build phase.
  • It’s effective to prioritise hot spots until it gets too hard
    • at some point we find that we’re creating quality problems faster than we’re able to fix hot spots, and that’s when it’s time to move on to adopting best practices in that area
    • this ties to sub-optimal decisions too. If a sub-optimal decision leads to a failure once every 6 months, we can probably live with it
  • Majority of the code is disposable
    • ability to remove code is as important as writing new code
    • make sure that the code is not tightly coupled and highly dependant on other modules
    • assess code by how easy it is to remove it
  • Wrong abstractions are costly
    • reference: https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction
    • prefer duplication, especially for features in discovery phase (MVP, prototype, v1)
    • striving for future-proof, abstract problem solution can create complexity in the long run and impact delivery of the initial feature as well as impact every iteration afterwards
    • remember: majority of the code is disposable and often initial versions of features don’t last longer than 6 months
  • Allow for organic discovery – not every decision needs to be perfect right away
    • do the easy thing and test it by making it work and used by the end users
    • start with simple data structure, algorithm or approach. iterate when new conditions arise
  • Be wary of accounting for future use cases
    • there’s only a handful of features that are stable and their scope is well defined. This means most features we develop change drastically or are removed in the span of a year
  • General engineering philosophy
    • systems design through discovery – iterative process
    • critical thinking & good scout rule
      • make changes and leave the code in a better state than when you’ve started

Leave a Reply

Your email address will not be published. Required fields are marked *