{"componentChunkName":"component---node-modules-gatsby-theme-medium-to-own-blog-src-templates-blog-post-js","path":"/startup-pre-series-a-tech-choices-you-can't-compromise-on/","result":{"data":{"site":{"siteMetadata":{"siteUrl":"https://javame.netlify.app","githubUrl":"https://github.com/aterreno/blog"}},"mdx":{"fields":{"slug":"/startup-pre-series-a-tech-choices-you-can't-compromise-on/"},"excerpt":"If you spent any time in an early stage startup you know what it’s like, it’s a rollercoaster of we are going to make it, we are killing it…","timeToRead":3,"frontmatter":{"title":"Startup Pre-series A tech choices you can’t compromise on","description":"If you spent any time in an early stage startup you know what it’s like, it’s a rollercoaster of we are going to make it, we are killing…","categories":[],"date":"February 06, 2019","canonical_link":"https://javame.netlify.app//startup-pre-series-a-tech-choices-you-cant-compromise-on-a499a75f3f06"},"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"Startup Pre-series A tech choices you can’t compromise on\",\n  \"description\": \"If you spent any time in an early stage startup you know what it’s like, it’s a rollercoaster of we are going to make it, we are killing…\",\n  \"date\": \"2019-02-06T12:54:25.617Z\",\n  \"categories\": [],\n  \"published\": true,\n  \"canonical_link\": \"https://javame.netlify.app//startup-pre-series-a-tech-choices-you-cant-compromise-on-a499a75f3f06\",\n  \"redirect_from\": [\"/startup-pre-series-a-tech-choices-you-cant-compromise-on-a499a75f3f06\"]\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"If you spent any time in an early stage startup you know what it\\u2019s like, it\\u2019s a rollercoaster of we are going to make it, we are killing it, oh no, we are not.\"), mdx(\"p\", null, \"Investing time (and therefore money) into certain practices and tools might be a choice you can\\u2019t afford at this stage.\"), mdx(\"p\", null, \"So here is what we did at \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://thelabrador.co.uk\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Labrador\"), \", in my first year and a half, indeed it\\u2019s all very context based, but I think some choices are universal and so basic that you can\\u2019t get away with.\"), mdx(\"hr\", null), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"Limit your infrastructure as much as you can and for the little that you\\u2019ve got to build automate it\")), mdx(\"p\", null, \"We embraced \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://serverless.com/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"serverless\"), \" and it\\u2019s a choice that has been paying off, the learning curve it\\u2019s flat, the speed of going to production without worrying about the necessary infrastructure or service discovery beats any other technology I\\u2019ve used before, however, some third-party integrations require \\u2018real servers\\u2019, we used \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.terraform.io/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Terraform\"), \" to build those, even if we barely touched them in the last few months, it\\u2019s a must-have safety net that I would never compromise on: applying security updates, upgrading the OS, rebuilding the instances on AWS when necessary has been a piece of cake: no dramas, no panic mode because you have no time.\"), mdx(\"p\", null, \"I\\u2019ve asked myself a few times, would we have been better off with a monolith? What if instead of 150~ lambdas we\\u2019d be working on a Rails/Django monolithic application? I think we\\u2019d probably been just as fast, but this goes into my next point\"), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"Don\\u2019t worry too much about code quality, what is good today might be trashed tomorrow\")), mdx(\"p\", null, \"We copied and pasted, we didn\\u2019t write many tests, the good things about lambdas (as it\\u2019s for microservices but here we are at the \\u2018nano-services\\u2019 size) it\\u2019s that it\\u2019s easy to trash something and rewrite later. We limited homegrown npm packages (not enough!), architectural dependencies between lambdas.\"), mdx(\"p\", null, \"In my consulting career, I had to deal way too many times with monolith apps which grew and grew and grew to the point it was impossible to replace areas of functionality, lambda-coding forces you to decouple.\"), mdx(\"p\", null, \"Now you\\u2019ll think, you are a reckless cowboy, but this goes into the next two uncompromisable values: operability and architecture.\"), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"Build operability from day zero\")), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"Operability is the ability to keep an equipment, a system or a whole industrial installation in a safe and reliable functioning condition, according to pre-defined operational requirements. \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://en.wikipedia.org/wiki/Operability\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Wikipedia\"))), mdx(\"p\", null, \"For us this implies using \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.iopipe.com/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"IOPipe\"), \" on all our lambdas, implies always set up at least one alert in both non-prod and prod environment for every new lambda.\"), mdx(\"p\", null, \"Serverless Architectures are complex, highly distributed systems, with eventual consistency baked in, I would say that there is also eventual correctness of the system: if you think that your system is behaving correctly because you wrote a bunch of tests, bless you but you are so wrong!\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"Troubleshooting time is precious, investing in tracing, logging, centralised monitoring has been very valuable for us.\"), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"Hack in the small but architect in the large\")), mdx(\"p\", null, \"Back at \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.equalexperts.com/our-people/our-values/?=technical\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Equal Experts\"), \", we came up with \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.equalexperts.com/our-people/our-values/?=technical\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"a value\"), \" that still sits strongly in my head\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, mdx(\"em\", {\n    parentName: \"p\"\n  }, \"We value overall simplicity over localised simplicity\"))), mdx(\"p\", null, \"I think we did our best to design a resilient system, with lambdas loosely coupled (in fact no lambda calls another lambda in our system, it\\u2019s (or it was!) an unwritten rule. We invested in building an event-driven system, we can replay events and re-build our data if an unexpected condition happened (and trust me, it will happen, \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://en.wikipedia.org/wiki/Murphy%27s_law\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Murphy Law\"), \")\"), mdx(\"p\", null, \"As much as we value freedom and empowerment overall simplicity this also implies no polyglot, no multi-cloud: we love AWS, Node.JS and React: those are our weapons to turn business goals into software, we strive to minimise third-party tools and SaaS accounts to build, run, monitor our systems.\"), mdx(\"p\", null, \"For everything else, I can only quote \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/Scout24/scout24-it-principles\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Scout24 IT Principles\"), \", which I respect, admire and try to implement as best as I can here as well.\"), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"What do I think it\\u2019s next?\")), mdx(\"p\", null, \"Hard to tell, and subject to change, but we need to invest in anomaly detection, centralised logging and potentially invest in automated tests, especially for the front-end codebase.\"), mdx(\"p\", null, \"We recently started looking at \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.puresec.io/\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"Puresec\"), \" to secure our lambdas and we integrated into our ci/cd \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/Yelp/detect-secrets\",\n    \"target\": \"_blank\",\n    \"rel\": \"nofollow noopener noreferrer\"\n  }), \"this excellent library\"), \" from yelp to make sure \\u2018secrets\\u2019 don\\u2019t flood into the codebase.\"), mdx(\"p\", null, \"We worked on an almost-no process, Trello/Kanban/Just in Time Requirements but we might need to start introducing more agile practices, we are not anymore 5 people sitting on the same desk, but growing fast, currently counting a total of 20 people.\"));\n}\n;\nMDXContent.isMDXComponent = true;"},"allWebMentionEntry":{"nodes":[]}},"pageContext":{"id":"3d69d86d-193c-5f75-877d-e588ffac32c0","previous":{"id":"b9169ea0-41a7-5086-a441-50c17394f9e8","fields":{"slug":"/one-year-of-serverless/","published":true},"frontmatter":{"redirect_from":["/one-year-of-serverless-61bfc475b23b"],"redirect_to":null,"title":"One year of serverless"}},"next":{"id":"2c739b3e-932e-5e1b-b05e-4f0ac8751522","fields":{"slug":"/things-about-serverless-i-wish-i-used-from-the-start/","published":true},"frontmatter":{"redirect_from":["/things-about-serverless-i-wish-i-used-from-the-start-edd3841d6a95"],"redirect_to":null,"title":"Things about serverless I wish I used from the start"}},"permalink":"https://javame.netlify.app/startup-pre-series-a-tech-choices-you-can't-compromise-on/","themeOptions":{"plugins":[],"config":{"title":"Antonio Terreno","description":"Antonio Terreno's blog archive","shortBio":"","bio":"Principal Consultant at Equal Experts","author":"Antonio Terreno","githubUrl":"https://github.com/aterreno/blog","siteUrl":"https://javame.netlify.app/","social":{"twitter":"javame","medium":"","facebook":"","github":"aterreno","linkedin":"antonioterreno","instagram":"tritonitri"},"goatCounterCode":null}}}},"staticQueryHashes":["4131332129","645483741"]}