<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Viach Kakovskyi</title>
    <description>The latest articles on DEV Community by Viach Kakovskyi (@backendandbbq).</description>
    <link>https://dev.to/backendandbbq</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F25129%2Ff5648ff9-4d7b-4dee-97f8-f757b4489cd2.jpg</url>
      <title>DEV Community: Viach Kakovskyi</title>
      <link>https://dev.to/backendandbbq</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/backendandbbq"/>
    <language>en</language>
    <item>
      <title>Running Production Systems: Level 1, Software Firefighting</title>
      <dc:creator>Viach Kakovskyi</dc:creator>
      <pubDate>Sun, 23 Sep 2018 21:50:02 +0000</pubDate>
      <link>https://dev.to/backendandbbq/running-production-systems-level-1-software-firefighting-20j4</link>
      <guid>https://dev.to/backendandbbq/running-production-systems-level-1-software-firefighting-20j4</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on my blog:&lt;/em&gt; &lt;a href="http://allyouneedisbackend.com/blog/2018/09/21/software-firefighting-running-production-software/"&gt;All You Need Is Backend&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0W7Dsr8m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vlrx4ptwkk57rf8sq428.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0W7Dsr8m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vlrx4ptwkk57rf8sq428.jpg" alt="Software Firefighting" title="Software Firefighting"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You Build It, You Run It.&lt;/strong&gt; The slogan spreads all around the world across software engineering teams. It's working great - the successful teams care not only about writing good code, but also how the code is serving the end-users in the production environment.  &lt;/p&gt;

&lt;p&gt;For &lt;a href="http://allyouneedisbackend.com/blog/2017/08/30/what-is-highload/"&gt;Highload projects&lt;/a&gt; running software turned into a separate discipline called &lt;strong&gt;Site Reliablity Engineering&lt;/strong&gt;. As one my fellow (former DevOps Engineer, SRE now) told me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;h4&gt;
  
  
  SRE is the next level of DevOps
&lt;/h4&gt;
&lt;/blockquote&gt;

&lt;p&gt;I think that engineering teams should know how the software will be running in production starting at the very beginning of the project. It includes the knowledge about infrastructure, data storages, monitoring, and deployment pipeline. Good, if you know the budget for all the things.&lt;/p&gt;

&lt;p&gt;In the &lt;em&gt;series of blog posts&lt;/em&gt;, we focus on the approaches that I've seen during my career, starting from the simplest to the most sophisticated one.&lt;/p&gt;

&lt;p&gt;Let's check out the very first level that I called &lt;strong&gt;Software Firefighting&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why put firefighting foam on your code
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Software Firefighting&lt;/strong&gt; - is the spot where engineers usually start. You do not need to have any experience to begin. Doing that actually can help you to grow... until some point.&lt;/p&gt;

&lt;p&gt;You write some code, push it to production, and hope that everything works fine. Yes, you do not have a lot of information on how the system behaves and how healthy is that.&lt;/p&gt;

&lt;p&gt;This tactic is OK for the cases when it's not a big deal if your service does not operate properly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pet projects&lt;/li&gt;
&lt;li&gt;Students' projects&lt;/li&gt;
&lt;li&gt;Hackathons (I've never had proper monitoring during a hackathon, have you?) &lt;/li&gt;
&lt;li&gt;Prototypes/demo projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But I used to work in the environment when business-related applications do not have any telemetry. &lt;/p&gt;

&lt;blockquote&gt;
&lt;h4&gt;
  
  
  My boss called me at 11 PM to tell that the piece of &lt;del&gt;sh*t&lt;/del&gt; fantastic software is not working, and the next morning we're demoing the system for the customer that should pay for that.
&lt;/h4&gt;
&lt;/blockquote&gt;

&lt;p&gt;Trust me; it's not funny at all. After such calls, you connect to the box that runs the software via SSH. You try to understand what's going on. In Software Firefighting mode you try to reproduce the issue in production to see something useful in logs. Another option if your logs are not very verbose or you want to jump into lower level - attach a debugger to a running process. &lt;/p&gt;

&lt;p&gt;If you stick with the Software Firefighting approach for running production software, I see a high probability for you to be working late at night. Very late at night... Might be OK for the fans of nightly coding. Not sure if you be paid for the overtime though.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h4&gt;
  
  
  The vendor from another continent dialed me. They asked to expedite issues with our software that are happening right away during the exhibition. It happened to me at 3 AM. The exciting experience that I would like to avoid in the future.
&lt;/h4&gt;
&lt;/blockquote&gt;

&lt;p&gt;When you find the cause - you experiment on the live instance try to patch the code, eventually create a PR that starts with the word &lt;code&gt;hotfix&lt;/code&gt; and deploy this straight to production without proper peer reviews. Your team will learn about that later... hopefully not from a new incident.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ultimate Software Firefighting workflow
&lt;/h2&gt;

&lt;p&gt;Well, I warned you that it's not suitable for business applications. Now I will share my thoughts on how to do it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Identify the problem.

&lt;ul&gt;
&lt;li&gt;Connect to the production environment.&lt;/li&gt;
&lt;li&gt;Collect live stats (in the next section will discuss how to get trained in that area).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reproduce the problem.

&lt;ul&gt;
&lt;li&gt;Localize - find the place where it's happening. The smaller is the localized area - the better it is for you: service, module, class, method, code statement, variable...&lt;/li&gt;
&lt;li&gt;Repeat the harmful action to verify if that is the right place (only if that's safe from the business perspective).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Prepare the hotfix.

&lt;ul&gt;
&lt;li&gt;Find similar problems in your incidents registry/closed Jira tickets or on Stack Overflow.&lt;/li&gt;
&lt;li&gt;Make the change locally.&lt;/li&gt;
&lt;li&gt;Test it without touching production.&lt;/li&gt;
&lt;li&gt;If you're sure about the change - move it to production.&lt;/li&gt;
&lt;li&gt;Verify that the problem is solved (and the new issues were not created).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Write a blog for your team to share your learnings from the firefighting session.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Train the firefighters
&lt;/h2&gt;

&lt;p&gt;Troubleshooting in production is a great skill. I wish I had it on the higher level then it's now (but I do not want any business to pay for that). Here're the levels of troubleshooting, ordered from the easiest to more complex things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Check the state of the box that is running the application (healthy or not)&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://linux.die.net/man/1/top"&gt;top&lt;/a&gt;&lt;/strong&gt; - the command collects resource usage statistics on your machine and provides the dynamic view on the resources utilization. That's the easiest thing that you can do to gain some situational awareness. Links for learning:

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.brendangregg.com/blog/2017-08-08/linux-load-averages.html"&gt;Linux Load Averages: Solving the Mystery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gtacknowledge.extremenetworks.com/articles/How_To/Understanding-the-output-of-the-TOP-command"&gt;Understanding the output of TOP command&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.thegeekstuff.com/2010/01/15-practical-unix-linux-top-command-examples/"&gt;15 Practical Linux Top Command Examples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Check the statements that the software is logging&lt;/strong&gt;. The logs for your service, web server, load balancer - all the things. &lt;code&gt;grep&lt;/code&gt; and &lt;code&gt;tail&lt;/code&gt; are your best friends there.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Investigate the suspicious running process(es) without restarting.&lt;/strong&gt; Since it's not always straightforward how to reproduce bugs in production, I was thrilled when I learned that we could connect to the code that already serves our customers. It gives the ability to have a way deeper look into details. Some tools that can give you a clue:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.gnu.org/software/gdb/"&gt;gdb&lt;/a&gt;&lt;/strong&gt; - is the GNU debugger that allows you to set breakpoints and temporarily stop the execution of a process to see values of variables in real time. The more you understand source code of the program the easier it would be to find the error. When you need to investigate a crash you can set a breakpoint just before the program crashes. Some tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can &lt;a href="https://benbernardblog.com/my-startling-encounter-with-python-debuggers/"&gt;see waiting threads using gdb&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;You can &lt;a href="https://sourceware.org/gdb/onlinedocs/gdb/Python.html"&gt;extend gdb using Python&lt;/a&gt; (you can also go that with GoLang AFAIK)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;h4&gt;
  
  
  The tool helped me to figure out an issue with regular expressions that caused a major incident in a large cloud system.
&lt;/h4&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;gdb&lt;/strong&gt; gives you more insights that you have looking only in logs. You can find many blogs on how to use the debugger for your technology stack. I'd like to share the link to blog post about &lt;a href="http://podoliaka.org/2016/04/10/debugging-cpython-gdb/"&gt;Debugging of CPython processes with gdb&lt;/a&gt; by &lt;a href="https://twitter.com/rpodoliaka"&gt;Roman Podoliaka&lt;/a&gt;. For the backend applications written in Python it can be more convenient to use &lt;a href="https://docs.python.org/3/library/pdb.html"&gt;pdb&lt;/a&gt;. Here's &lt;a href="https://github.com/spiside/pdb-tutorial"&gt;the great tutorial&lt;/a&gt; how to start using the tooling. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Trace all the things on the box (network traffic, library calls, system calls)&lt;/strong&gt;. If nothing of above helps - look into the universe of tools and approaches for introspecting your software. Check out the links for learning:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.brendangregg.com/blog/2015-07-08/choosing-a-linux-tracer.html"&gt;Choosing a Linux Tracer (2015)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.brendangregg.com/linuxperf.html"&gt;Linux Performance&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, we have a couple of tools suggested by subscribers (&lt;a href="https://twitter.com/CarlosN26157061"&gt;Carlos Neira&lt;/a&gt; and &lt;a href="https://twitter.com/Amie42"&gt;Amie Wang)&lt;/a&gt; from &lt;a href="https://twitter.com/BackendAndBBQ/status/1026138692514205699"&gt;the related Twitter thread&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/iovisor/bcc"&gt;BPF Compiler Collection - Tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.kernel.org/doc/html/v4.15/dev-tools/kgdb.html"&gt;kgdb&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.oracle.com/cd/E18752_01/html/816-5041/intro-1.html"&gt;mdb&lt;/a&gt; for Solaris OS&lt;/li&gt;
&lt;li&gt;&lt;a href="http://valgrind.org/"&gt;Valgrind&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're interested especially in Performance Optimization, I extremely recommend you to watch the videos (90 mins) about &lt;strong&gt;Linux Performance Tools&lt;/strong&gt; by &lt;a href="http://www.brendangregg.com/"&gt;Brendan Gregg&lt;/a&gt; - &lt;a href="https://www.youtube.com/watch?v=FJW8nGV4jxY"&gt;Part 1&lt;/a&gt; and &lt;a href="https://www.youtube.com/watch?v=zrr2nUln9Kk"&gt;Part 2&lt;/a&gt;. He explains &lt;a href="http://www.brendangregg.com/methodology.html"&gt;the performances optimization methodologies&lt;/a&gt; and provides a good number of practical examples. And &lt;a href="http://www.brendangregg.com/overview.html"&gt;read his blog&lt;/a&gt;. It's a lot of knowledge.&lt;/p&gt;

&lt;p&gt;During learning the topic, I also found &lt;a href="http://lethargy.org/~jesus/misc/production-troubleshooting.pdf"&gt;the slides&lt;/a&gt; from &lt;a href="https://lethargy.org/~jesus/page/about/"&gt;Theo Schlossnagle&lt;/a&gt; interesting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pros and Cons
&lt;/h2&gt;

&lt;p&gt;Let's analyze the benefits of the cowboy style of running production software.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Heroism.&lt;/strong&gt; You feel like a hero rescuing your business from disasters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cheap.&lt;/strong&gt; No investments in your infrastructure are needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Affects the reputation of your business.&lt;/strong&gt;  You're aware only when customers/business owners find that service does not work. Example: you learn from Twitter feed that your service does not work for end-users and they're moving to a competitor. It sucks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Requires engineering team to be trained.&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time-consuming.&lt;/strong&gt; You need to reproduce the issue in prod to gather telemetry right on the box.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not accountable.&lt;/strong&gt; Leads to running hotfixes in production that might not exist in your repository. And the other engineers on your team might learn nothing on how to fix such issues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stressful.&lt;/strong&gt; Dangerous to your mental and physical health. As well as your personal life.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-cooperative.&lt;/strong&gt; It's hard to handover work if you need to step-out.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Again, I do not recommend running business software applications in the Firefighting mode.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;We can remove some disadvantages of the approach. To achieve that we need to grow and reach the next level of maturity. The second blog post in the series will be published soon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Well, what's your favorite debugging/performance tool?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S.&lt;/strong&gt; The blog post started as &lt;a href="https://twitter.com/BackendAndBBQ/status/1026138692514205699"&gt;the Twitter thread&lt;/a&gt;.  You can subscribe to my Twitter account or blog to do not miss the next knowledge sharing session about backend software engineering.&lt;/p&gt;

</description>
      <category>sre</category>
      <category>devops</category>
    </item>
    <item>
      <title>What Does a Tech Lead Do?</title>
      <dc:creator>Viach Kakovskyi</dc:creator>
      <pubDate>Sun, 05 Aug 2018 18:58:28 +0000</pubDate>
      <link>https://dev.to/backendandbbq/what-does-a-tech-lead-do-1cpj</link>
      <guid>https://dev.to/backendandbbq/what-does-a-tech-lead-do-1cpj</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on my blog:&lt;/em&gt; &lt;a href="http://allyouneedisbackend.com/blog/2018/08/03/what-does-a-tech-lead-do/" rel="noopener noreferrer"&gt;All You Need Is Backend&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9sfpknhwedy82i11v0oz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9sfpknhwedy82i11v0oz.png" title="What Does a Tech Lead Do?" alt="What Does a Tech Lead Do?"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tech Lead&lt;/strong&gt; is a relatively new role in the hierarchy of software development organizations. When I heard about the role for the first time, my first thought was &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is a that &lt;strong&gt;software architect + team lead&lt;/strong&gt;? &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I do not think that the definition is correct, but it's a good way of thinking about that. In the post, I  retrospect 3.5 years of my experience in the position that includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;leading one of the teams for &lt;strong&gt;&lt;a href="https://www.stride.com/" rel="noopener noreferrer"&gt;Atlassian Stride&lt;/a&gt;&lt;/strong&gt; - complete team communication solution. Within almost 2 years the team had from 5 to 10 engineers.&lt;/li&gt;
&lt;li&gt;leading &lt;strong&gt;KPIdata&lt;/strong&gt; a non-profit organization that developed software for accessing the quality of higher education in &lt;a href="https://en.wikipedia.org/wiki/Igor_Sikorsky_Kyiv_Polytechnic_Institute" rel="noopener noreferrer"&gt;Kyiv Polytechnic Institute&lt;/a&gt;. The team was expanded to 10 core members (only 3 software engineers including myself) and eventually, 180+ individual contributors helped us to deliver the project.&lt;/li&gt;
&lt;li&gt;leading a team of 4 engineers (including myself) at &lt;strong&gt;&lt;a href="https://www.linkedin.com/company/vit-ltd/" rel="noopener noreferrer"&gt;Video Internet Technologies Ltd&lt;/a&gt;&lt;/strong&gt; for Integration of Video Management Systems (CCTV).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note, that the same positions might have different responsibilities in different companies. &lt;/p&gt;

&lt;p&gt;Check out the blog post to learn about my reality of being a full-time owner of software systems. I elaborate on &lt;strong&gt;pros and cons&lt;/strong&gt; being on a Tech Lead position.&lt;/p&gt;

&lt;p&gt;From the practical standpoint - the list of &lt;strong&gt;the most critical skills&lt;/strong&gt; for the position is provided at the very end of the blog.&lt;/p&gt;

&lt;h2&gt;
  
  
  Being a full-time owner
&lt;/h2&gt;

&lt;p&gt;The first thing that I found on the position is that now &lt;strong&gt;I'm 100% responsible&lt;/strong&gt; for one of the chapters of an engineering organization. The good part about that - the new chapter did not have anything in production yet. So, I did not have any legacy code from previous maintainers to support and extend. That was nice. &lt;/p&gt;

&lt;p&gt;However, it's not the rule, and every company is different. I think that more often you have a chance to enhance an existing software system instead create something from scratch. So, be ready to be responsible for the projects that were not started and designed by your team. &lt;/p&gt;

&lt;p&gt;What does it mean to be a full-time owner?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;You receive tasks are tied up to specific business goals.&lt;/strong&gt; Actually, the tasks are projects. Moreover, the requirements can be partially defined. You need to go ahead and figure out all the requirements and constraints. You want to specify the desired outcome of the project as much as you can to prevent scope creep. Understanding and defining the end goals is the very first step.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You can do whatever is reasonable for you within your time/budget to achieve the goals.&lt;/strong&gt; We look into that in more details in the next section.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;All successes (and failures) of the software that is created to achieve the goal are associated with you.&lt;/strong&gt; If something is broken in your system or does not work as expected - it's your responsibility and fault. In the case when the goal is overachieved - great job! Do not forget to give credit to your team for the successes though. The people deserve it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The space for the engineering creativity
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Yes, you can do anything to achieve the engineering goals.&lt;/strong&gt; Here's the list of the things that I was able to change or implement. Note, that you should get buy-in from your team to make the changes persistent. People make software. Happy people make working software. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Software development methodology&lt;/strong&gt;. Strongly depends on the goals of the project and deadlines. Answer the questions to define that:

&lt;ul&gt;
&lt;li&gt;How many days are in an iteration?&lt;/li&gt;
&lt;li&gt;What's the planning process? Which tasks should be estimated? How to estimate tasks?&lt;/li&gt;
&lt;li&gt;Should we accept changes in requirements or not between iterations?&lt;/li&gt;
&lt;li&gt;What are the rules for the tasks of different types/priorities? Example: all bugs for the &lt;em&gt;Billing&lt;/em&gt; component must be fixed ASAP regardless severity.&lt;/li&gt;
&lt;li&gt;How to demo that to the rest of the organization?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Technical stack&lt;/strong&gt; for the project. It can include but not limited to programming languages, frameworks, data storages, libraries, monitoring solutions. Sometimes you have some pre-defined preset dictated by the company's policies. For our chapter the stack was the following:

&lt;ul&gt;
&lt;li&gt;Python 3, asynchronous programming, asyncio&lt;/li&gt;
&lt;li&gt;MySQL, Elasticsearch, Redis&lt;/li&gt;
&lt;li&gt;AWS (EC2, RDS, ElastiCache, S3, SQS, CloudFormation, CloudWatch)&lt;/li&gt;
&lt;li&gt;DataDog, Elasticsearch/Logstash/Kibana, ElastAlert, Splunk&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Software architecture&lt;/strong&gt;. You define the structural parts of the software system. You can build something new. You can reuse existing in-company or third-party services. Designing interfaces between different components is also your responsibility if you're a Tech Lead. Have fun with all that!&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Non-functional requirements&lt;/strong&gt;. That's about defining the border between &lt;em&gt;good enough&lt;/em&gt; and &lt;em&gt;perfect&lt;/em&gt; software. I never was encouraged to make an ideal commercial solution. Usually, people &lt;em&gt;just&lt;/em&gt; need a stable solution to solve their business problems. The solution should be flexible enough to let us apply new changes fast. For me, that means setting the reasonable expectation for engineers to make the business happy. Examples:

&lt;ul&gt;
&lt;li&gt;The component should be resilient to database restarts...&lt;/li&gt;
&lt;li&gt;...but if the connection cannot be established within 60 seconds - please, alert&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Internal milestones&lt;/strong&gt;. You can set the focus for the team for different stages of the project as well as define deliverables for that. 

&lt;ul&gt;
&lt;li&gt;For example, the project roadmap can be optimized to have a version of the system in production ASAP to establish CI/CD pipeline as well as ensure that your ideas are principally working. &lt;/li&gt;
&lt;li&gt;Another example - you can target to make your teammates as autonomous as possible (a good idea when Y'all geographically distributed) - then you need to spend more time for planning to define independent work streams. &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Service Level Indicators&lt;/strong&gt;. As a Tech Lead, you're in charge of defining when your software provides the needed quality of service. Picking the right set of the indicators that reflect the reality of your business is vital because it sets the target for your team as well as the direction for engineering improvements. Examples from my experience:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Availability.&lt;/strong&gt; Can the service be used?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Number of processed jobs.&lt;/strong&gt; Do we still need the service? How much useful work we're doing?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Success rates for the principal components.&lt;/strong&gt; -Helps us to see problems on the middle level.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Rollout schedule&lt;/strong&gt;. It includes how often to deploy the software to different environments. 

&lt;ul&gt;
&lt;li&gt;As soon as a pull request is merged&lt;/li&gt;
&lt;li&gt;OR do releases once per 4 months.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Communication.&lt;/strong&gt; How does the team communicate about the daily progress?

&lt;ul&gt;
&lt;li&gt;30-minute video calls two times per day &lt;/li&gt;
&lt;li&gt;Text standup once per week &lt;em&gt;(maybe)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Split of work&lt;/strong&gt;. How are the tasks in your Jira assigned? 

&lt;ul&gt;
&lt;li&gt;You assign each task to every engineer and they do not have any chance to change that without your written permission (not very good tactic)&lt;/li&gt;
&lt;li&gt;Everybody can take any task regardless priority and dependencies&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Code review policy&lt;/strong&gt;. Who should approve a pull request to let the creator merge it to master? Options:

&lt;ul&gt;
&lt;li&gt;Consensus - all concerns are answered and all default reviewers approved the changes&lt;/li&gt;
&lt;li&gt;At least 2 approvals from Senior engineers should be received to proceed&lt;/li&gt;
&lt;li&gt;I can approve my PR and deploy after 2 hours after the last commit&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Retrospectives.&lt;/strong&gt; How often to do them? My recommendation is once per 4 weeks, but I know that some teams do it every 2 weeks. Btw, how often do you do them?&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;I omitted some things so feel free to add your ideas as comments.&lt;/p&gt;

&lt;h2&gt;
  
  
  How technical is a Tech Lead?
&lt;/h2&gt;

&lt;p&gt;My mission was to enable the team to implement the right solution to the problem.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You do not write much code on a daily basis&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before I became a Tech Lead on the latest team, I was working more than 1.5 years on Intermediate/Senior Software Engineer positions in the same area within the same group of people. It was essential for me to gain the needed practical experience with asynchronous programming, relational and non-relational databases, instant messaging, and highload systems.&lt;/p&gt;

&lt;p&gt;To make your project successful first of all you should &lt;strong&gt;read&lt;/strong&gt; a lot of: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code

&lt;ul&gt;
&lt;li&gt;Pull requests made by your team.&lt;/li&gt;
&lt;li&gt;Solutions that your systems reuse.&lt;/li&gt;
&lt;li&gt;Code of third-party services maintained by other teams that you need work with.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Technical documentation

&lt;ul&gt;
&lt;li&gt;Description of the services that you can re-use (both in-house and third-party ones).&lt;/li&gt;
&lt;li&gt;Implementation details of the solutions.&lt;/li&gt;
&lt;li&gt;Known issues for them (nothing is perfect) - to understand risks and plan mitigation for them.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;After the lots reading you &lt;strong&gt;write&lt;/strong&gt; a bit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Engineering proposals - &lt;a href="https://www.atlassian.com/team-playbook/plays/daci" rel="noopener noreferrer"&gt;DACI&lt;/a&gt; is a useful framework. I love it.&lt;/li&gt;
&lt;li&gt;After the proposals are decided - design pages.&lt;/li&gt;
&lt;li&gt;And in the very end - tickets for some work (my team runs on &lt;del&gt;caffeine&lt;/del&gt; Jira Software).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And after the writing - you &lt;strong&gt;discuss&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reach agreement with your teammates regarding non-trivial tasks.&lt;/li&gt;
&lt;li&gt;Educate your teammates if you have a non-complete specification or did not provide all the data sources.&lt;/li&gt;
&lt;li&gt;Negotiate contracts with other teams.&lt;/li&gt;
&lt;li&gt;Demo results of your work as well as promote your solutions within the company.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the end of the day, you might have a couple of hours to make the individual contribution. For me it was something like the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hotfixes. Needed to fix something when the world was about to explode.&lt;/li&gt;
&lt;li&gt;Make a proof of concept for a pull request without writing tests. After that, ask somebody from the team to turn it into the production-grade software.&lt;/li&gt;
&lt;li&gt;Commit database or configuration changes.&lt;/li&gt;
&lt;li&gt;Investigate a weird bug that can be hardly reproduced in the development environment. &lt;/li&gt;
&lt;li&gt;Pull some data from metrics/logging solution to validate an idea of implementation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think that a Tech Lead should have solid practical software engineering experience to be able to make and support reasonable decisions. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;On small teams (up to 3 direct reports) I think that it's still possible to make some good volume of individual contribution. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At the moment of writing, I do not have developed my engineering leadership skill enough to be able to make a sustainable individual contribution on larger teams.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pros and Cons of being a Tech Lead
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You become a subject matter expert in the area of your project.&lt;/li&gt;
&lt;li&gt;You have a complete understanding of how the software system works and how to apply changes into that with minimal risk. You can replicate it to other systems now.&lt;/li&gt;
&lt;li&gt;You become a good communicator because you're responsible for understanding requirements and explaining technical solutions.&lt;/li&gt;
&lt;li&gt;You reach some level of competency (not always very high, though) in various areas of software development:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;System design&lt;/strong&gt; - to architect your software and validate all the risks on early stages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operations&lt;/strong&gt; - to keep your systems up and running.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quality engineering&lt;/strong&gt; - to prevent losses of your company's reputation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Engineering management&lt;/strong&gt; - to delegate implementation to your team or even other teams.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At the end of a workday, you often do not have a feeling of accomplishment. You have generated some new work for your team, resolved some blockers but it does not feel like real work. &lt;/li&gt;
&lt;li&gt;Not enough coding on larger teams.&lt;/li&gt;
&lt;li&gt;You're the entry point for your team. You should be able to accept tasks from multiple sources:

&lt;ul&gt;
&lt;li&gt;Your teammates&lt;/li&gt;
&lt;li&gt;Your management&lt;/li&gt;
&lt;li&gt;Partner teams&lt;/li&gt;
&lt;li&gt;Customer support team&lt;/li&gt;
&lt;li&gt;Other people that have heard about your team&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Sometimes it's stressful because it's a lot of responsibility. Eventually, you should learn how to handle all that. &lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;I think that the position is worth trying and I'm happy that I had the opportunity to serve in the position for years. I'd do it again.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL-starter pack
&lt;/h2&gt;

&lt;p&gt;If you're interested in a Tech Lead position and would like to prepare for that, he's the list of skills that I found valuable in the very beginning of the path:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Practical proficiency in the programming languages&lt;/strong&gt; from your stack - to be able to make good technical choices and do the code review as well. Make the proper start of the project is crucial so your coding skills can help with that dramatically to define the structure and basic components.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Good level of skills related to data stores&lt;/strong&gt; - I think that in the majority of projects you deal with information read or stored from somewhere. Also, the knowledge is a perfect ground for system design competence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Project management&lt;/strong&gt; - for organizing your work in the new multi-tasking environment as well as work of other people.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Communication skills&lt;/strong&gt; - the position is about enabling other people to do technical work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I believe that these 4 skills are enough and the rest of the skills can be built during the project on top of them. I hope that the blog post will help to improve technical leadership in software teams.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S.&lt;/strong&gt; In the blog, when I say "you do something" means "you're responsible for something." As a Tech Lead you can delegate some complex engineering to the experts on your team but be able to verify, approve or correct the solutions. Also, being a decision-maker does not equal to being a dictator and ignoring the voices of other people.   &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.P.S.&lt;/strong&gt; From my perspective, the difference between &lt;strong&gt;Team Lead and Tech Lead&lt;/strong&gt; is in responsibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Team Lead is responsible for people, not project.&lt;/li&gt;
&lt;li&gt;Team Lead does People Management.&lt;/li&gt;
&lt;li&gt;Team Lead is not supposed to make the individual contribution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;P.P.P.S.&lt;/strong&gt; Also, in my opinion, the difference between &lt;strong&gt;Architect and Tech Lead&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Architect has more practical and diverse experience.&lt;/li&gt;
&lt;li&gt;Architect is needed for more extensive and more complex systems.&lt;/li&gt;
&lt;li&gt;Architect position is more about doing the most laborious work instead enabling the rest of the team to do all the work.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>leadership</category>
    </item>
    <item>
      <title>Does Your Engineering Team Help Your Business To Win?</title>
      <dc:creator>Viach Kakovskyi</dc:creator>
      <pubDate>Mon, 26 Mar 2018 13:44:40 +0000</pubDate>
      <link>https://dev.to/backendandbbq/does-your-engineering-team-help-your-business-to-win-47h9</link>
      <guid>https://dev.to/backendandbbq/does-your-engineering-team-help-your-business-to-win-47h9</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on my blog:&lt;/em&gt; &lt;a href="http://allyouneedisbackend.com/blog/2018/03/25/your-engineering-team-helps-your-business-to-win/" rel="noopener noreferrer"&gt;All You Need Is Backend&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fyoq0oqxcsy9y8noszse9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fyoq0oqxcsy9y8noszse9.png" title="Does Your Engineering Team Help Your Business To Win?" alt="Does Your Engineering Team Help Your Business To Win?"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yey, &lt;em&gt;DevOps Book&lt;/em&gt; club was started in the office. I joined since I love DevOps, increasing the productivity of my team, and, of course reading books. I even did not imagine how useful it can be for solving day-to-day organization challenges with my team and my coaching as a tech lead.&lt;/p&gt;

&lt;p&gt;The first book for the club was &lt;strong&gt;&lt;a href="https://itrevolution.com/book/the-phoenix-project/" rel="noopener noreferrer"&gt;The Phoenix Project&lt;/a&gt;&lt;/strong&gt; written by Gene Kim, Kevin Behr, and George Spafford. People call the genre as &lt;em&gt;business fiction&lt;/em&gt; - it's a story about an IT manager (ex-marine) that was unexpectedly promoted to VP of IT Operations.&lt;/p&gt;

&lt;p&gt;In the blog, you can see my thoughts and notes on reading the book &lt;strong&gt;through the prism of my experience working on a team and leading teams&lt;/strong&gt;. Actionable items are provided as usual.&lt;/p&gt;

&lt;p&gt;Note, that we won't be covering the plot of the novel, if you're interested in that - read the book.&lt;/p&gt;

&lt;h2&gt;
  
  
  High-level takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Learn why your business needs you to make every single bit of software&lt;/strong&gt;. If you work on a commercial project, you should know why you're paid. And how the cash for your paycheck is generated. Each code commit should provide additional value to your company.&lt;br&gt;
Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A new feature that attracts new users or makes current users more satisfied with the product. Or even causes customers to buy the premium version of the product.&lt;/li&gt;
&lt;li&gt;A bugfix that makes existing customers happier and retains them with your product instead of making them think about solutions made by competitors.&lt;/li&gt;
&lt;li&gt;An improvement that makes engineering/product/support teams more productive to release their time to do other beneficial work&lt;/li&gt;
&lt;li&gt;Maintenance that prevents future issues or incidents that can lead to loss of trust of your customers. Also, incidents eat your time that should be dedicated to other work.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;I think that in commercial development, each software system is related to some business goal. If you do not know the goal that your team is achieving - ask your management. If there is no objective - question, what's the need for the company to pay you for work?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Breakdown business OKRs or KPIs into engineering deliverables&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Need more users? Learn why you're not gaining MAU and find how your code can add them.&lt;/li&gt;
&lt;li&gt;Need the product to have higher reliability? Invest into that by setting up a special team to do preventive maintenance.&lt;/li&gt;
&lt;li&gt;Need to have more revenue? Pay attention to make paid features more attractive. Make sure that the things that you do and your team does help the organization to achieve at least one of the goals. Otherwise, it's waste of your talent and company's money.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Identify the types of work that your team is doing&lt;/strong&gt;. According to the book, the four types of efforts exist:&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Business Projects&lt;/em&gt; - that's what you're asked to do by product managers/project sponsors. Goals of such project are tight to business objectives. Execution such projects increase MAU, customers' satisfaction, or revenue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Internal Projects&lt;/em&gt; - that's what you need to keep achieving your business goals. Engineering incentives from your team or asks from external teams fall into the category. Results of finishing such projects are not so visible out of the groups of people involved into that. But when such projects are skipped or executed poorly - it impacts business functions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Changes&lt;/em&gt; include actual deployment of deliverables made during the two types of projects listed above. Also, the category covers all small housekeeping work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Unplanned Work&lt;/em&gt; - dealing with incidents, and emergencies. You probably do not have time in your work schedule allocated for that. Doing that distracts you from doing other types of work. That sucks.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Implement change management process&lt;/strong&gt; within your organization. Changes in code or infrastructure that are done by one team can affect another team. You do not want to be surprised when they "upgrade" the version of the company-wide database to the one that does not have your favorite deprecated function. More real case - database schema changes that can be hardly reverted. I know that this can be hard, but you (or your management) should:

&lt;ul&gt;
&lt;li&gt;Build product roadmap for each team at least for one quarter.&lt;/li&gt;
&lt;li&gt;Make it aligned across various teams.&lt;/li&gt;
&lt;li&gt;Communicate about all backward-incompatible changes ahead of time if you have any.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;To succeed in leading your team, you should think outside your team/department or event product. Think, how the significant changes that you're going to bring affect the company as its customers as a whole. Always evaluate the risky changes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Define your development process and find the bottleneck&lt;/strong&gt;. The process might vary from team to team even within one organization. The steps might include the following actions (the list is &lt;em&gt;very&lt;/em&gt; simplified):&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Evaluate customers' feedback. If your customers vote in public Jira for some functionality or open support tickets - you're lucky. Use that as the input.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Identify the real need behind the request to define a feature. Define functional requirements for the software. Prioritize the feature and put it into the product roadmap.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allocate engineering resources within the organization to implement the functionality. Define non-functional requirements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Design how the feature should be implemented. Make work breakdown structure and plan the execution. Communicate with external teams if any assistance is needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write code. Cover the code with tests. Perform peer-to-peer review. Fix comments. Deploy to staging. Perform testing in staging. Find bugs. Fix bugs. Deploy the code to production.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable the feature for the customers. Receive customers' feedback. &lt;strong&gt;GOTO p.1&lt;/strong&gt; :)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each of the steps involves different skills and roles - from support engineers and product managers to software and quality engineers.&lt;br&gt;
&lt;strong&gt;Your goal is to find the constraint - the slowest/busiest chain link and make it faster&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;According to the Eliyahu M. Goldratt’s “Theory of Constraints.”:&lt;/p&gt;

&lt;blockquote&gt;
&lt;h4&gt;
  
  
  Any improvements made anywhere besides the bottleneck are an illusion.
&lt;/h4&gt;
&lt;/blockquote&gt;

&lt;p&gt;Only in that case you will see the improvement in feature delivery and be achieving business goals as a result.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Set limits for Work-In-Progress&lt;/strong&gt;. Having the number of tasks in progress higher than your throughput means the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your organization already paid for something to be done but your customers do not get the value from it.&lt;/li&gt;
&lt;li&gt;Since the work in-queue is waiting for resources that means the money is not used to maximize value for the organization.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;On my team, we limit the number of In Progress tickets to the number of engineers. It's very unlikely that one engineer works on two tasks at the same time. In that case, one of the tickets is probably blocked or waiting on somebody else to provide input.&lt;br&gt;
You should focus on finishing the in-progress work instead of starting work on new tasks.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Standardize the work that your team is doing&lt;/strong&gt;. Hardly ever your squad faces with unique tasks. Common tasks can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Perform database schema change.&lt;/li&gt;
&lt;li&gt;Change infrastructure configuration.&lt;/li&gt;
&lt;li&gt;Add more verbose logging; tracking more metrics and dashboards for them.&lt;/li&gt;
&lt;li&gt;Add an API endpoint.&lt;/li&gt;
&lt;li&gt;Add usage of a new API endpoint provided by an external team.&lt;/li&gt;
&lt;li&gt;Profile and optimize some piece of software.&lt;/li&gt;
&lt;li&gt;Change business rules for data transformation.&lt;/li&gt;
&lt;li&gt;Refactor a module for better maintainability.&lt;/li&gt;
&lt;li&gt;Investigate customers' request.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;The idea is to collect historical data about the way which the tasks are resolved as well as the time needed to implement the changes.&lt;/p&gt;

&lt;p&gt;The information should help you to achieve two objectives: first, train new team members - they can look how similar issues were resolved; second, provide estimates for your business owners.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Do not raise critical players&lt;/strong&gt;. If only one person on a team can perform some tasks, it makes the person extremely busy. And the team becomes exceptionally dependent on the engineer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eventually, jobs are waiting for the person to be free. The engineer becomes constraints for your project. To have sustainable development process, you want to have &lt;em&gt;at least two persons&lt;/em&gt; that can do some task.&lt;/p&gt;

&lt;p&gt;To eliminate bus factor, initiate internal knowledge sharing and invest in automation and documentation for the things that cannot be described as code. It helps you to raise team players. The excuse &lt;em&gt;"it's easier for me to do that than expain"&lt;/em&gt; should never be approved.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Track all work requests that come to your team&lt;/strong&gt;. Product managers and support engineers will be distracting your team. From achieving the goals that they defined for you. Yes, it sounds like a paradox. But it happens. I think that the reason of that: it's hard to evaluate all customers' needs and prioritize them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ideally, you should budget some time for urgent/unplanned work.&lt;/strong&gt; Each request should have a Jira ticket. Asks from external engineering teams should be tracked and prioritized as well. For example, if your service exposes a private API that is used by ten other engineering teams - be ready that some of them will ask you for some customization of non-trivial support. And vice-versa - your vendors inside your company can change the rules of the game because of their needs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enable your business to make experiments&lt;/strong&gt;. Engineering teams should provide the ability to verify product assumptions with minimal investment into implementation or without coding at all.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think that in the quarter our team succeeds in the field: some business was able to do some experiments without distracting the team from achieving other commitments. The way how to do that was not clear to me at the beginning of the journey, but after reading the book and having actual results, I see the full picture.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Make your business accept risk when they do not give you resources/time/budget&lt;/strong&gt;. We as engineers can suggest the priority for some maintenance tasks and preventive actions. Good, if we can provide insights about possible customers' impact. It's &lt;em&gt;always&lt;/em&gt; not enough time to fix all bugs and build all the features. Your business owners should understand trade-off and decide your priorities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Freeze low-priority work&lt;/strong&gt;. It's better to have your team working on a couple of in-flight projects and accomplish them in-time rather than have Work-In-Progress that already consumes resources and does not provide value for the business, customers or your team yet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consider using cloud providers.&lt;/strong&gt; They offer opportunities to think less and lend resources instead of buying them or mastering more complex/efficient algorithms. If processing of some background job takes enormous unacceptable time with your current codebase/ infrastructure  - consider parallelizing that with enabling additional computational resources only for the time of the job.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consider outsourcing.&lt;/strong&gt; Some parts of your business or legacy applications can be given to external vendors. It can reduce cost and release the smartest brains that are on your team. But make sure that the contract includes not only maintenance of the system but also the implementation of the changes needed to support your possible business initiatives. Also, make sure that the outsourcing team is capable of doing the required changes timely.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Other engineering tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Automate installation/provisioning of the environments needed for development, quality assurance, staging, and production.&lt;/strong&gt; Keep the environment as much close to each other as you can - same versions of OS, databases, library. You should be able to access them fast: keep them provisioned and pay for that or make the provisioning fast. Manual instructions should die, and manual changes should never be applied.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remove humans from the deployment process. Maximum involvement should be clicking the &lt;em&gt;Deploy Now&lt;/em&gt; button. Set up of development environment for new teammates should be done within a day or so.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Setup delivery pipeline and measure the throughput&lt;/strong&gt;. Classically, it includes writing code and deploying code to production to deliver value to the end-customers. In my opinion, it also includes identifying a need (business or engineering one) and prioritizing the needing/scheduling the work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Document (even better, automate!) "magic fixes" for all incidents&lt;/strong&gt;. You need to be able to replicate them if the issue occurs again. Keep them in your projects' knowledge base. You cannot rely on the hope that the engineer that solved the problem the last time will always be available to assist. That's it, changes in the systems that you own should be transparent and repeatable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Proactively find all fragile parts of your software&lt;/strong&gt;. If you work on the system that was developed before you joined the team - be ready for surprises. Things can break where you do not expect that. Besides codebase and project documentation (if your team has good enough documentation) your sources to learn that can be: results of load testing, metrics, and logs from production, registry of closed bugs, customer support tickets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stabilize infrastructure to be focused on development, not firefighting.&lt;/strong&gt; It's hard to make reasonable estimates and do not work overtime when you need not only to develop new features but also keep existing buggy software up and running. I will post a separate blog on the topic. Stay tuned.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Include slack time into your business commitments&lt;/strong&gt;. If engineers on your team are 100% loaded according to your plan that means any unplanned work should wait for in-queue (this is bad) or the commitments won't be met. Having some idle time for your engineers is fine since you cannot predict actual time to accomplish work as well as changes in requirements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Avoid handoff of tasks between engineers and cross-teams.&lt;/strong&gt; Context switch kills productivity. Having more than one responsible person enforces corporate ping-pong and makes harder to get things done.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Measure how often your code CAN be deployed to production&lt;/strong&gt;. Do you know how many deployments per day your business needs? How many of them can you do without affecting your routine? You would like to know the answers at least for the case when an incident occurs, and you need to push the hotfix to prevent loss of the company's reputation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Make all code changes accountable and authorized&lt;/strong&gt;. As well as infrastructure changes they should go through version control system, peer-to-peer review process and &lt;em&gt;sometimes&lt;/em&gt; approved by business/budget owners or external teams.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Move your working code to production ASAP&lt;/strong&gt;. Until the code is in production and is enabled for customers - no value is generated from doing product research, creating Jira tickets, design meetings, writing code, and reviewing pull requests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Make faster releases&lt;/strong&gt; and do that in small batches. For me, the ages when we give our customers a new version of backend software that &lt;em&gt;runs on our infrastructure&lt;/em&gt; once per month are over. Every merged pull request should be deployed individually (and rolled back). In that case, you can observe how the change affects your system and find failures fast.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prepare rollback strategy for deployment of all large/risky changes.&lt;/strong&gt; Examples: altering database tables with dozens of records, extreme refactoring, data migrations, switching vendors. If you think that your testing is not enough (or it's expensive to cover all needed cases) - I would invest into that.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Know about your incidents before your customers or business find that.&lt;/strong&gt; First of all, it gives you more time to investigate and fix the issue. Secondary - timely updated status page is the face of your team. It's just caring about feelings of your customers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Build a passionate team that is OK to work late hours and weekends to rescue the business when it's really needed&lt;/strong&gt;. It should be compensated somehow eventually including additional days off to recover and spend time with family or friends. You also can setup on-call rotation to have somebody on duty 24/7 be ready to fix any problems.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm happy that &lt;strong&gt;The Phoenix Project&lt;/strong&gt; book was selected for the DevOps book club. Reading the book, discussions with other engineers and retrospective look back helps me to define the next steps to improve development process in our backend engineering team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's favorite book about DevOps?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>leadership</category>
    </item>
    <item>
      <title>2017 Tech Accomplishments</title>
      <dc:creator>Viach Kakovskyi</dc:creator>
      <pubDate>Mon, 01 Jan 2018 00:00:00 +0000</pubDate>
      <link>https://dev.to/backendandbbq/2017-tech-accomplishments-3n33</link>
      <guid>https://dev.to/backendandbbq/2017-tech-accomplishments-3n33</guid>
      <description>

&lt;p&gt;&lt;em&gt;Originally published on my blog:&lt;/em&gt; &lt;a href="http://allyouneedisbackend.com/blog/2018/01/01/2017-tech-accomplishments/"&gt;All You Need Is Backend&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_k1vmESd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jc8090vevzf186iua539.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_k1vmESd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jc8090vevzf186iua539.png" alt="2017 Tech Accomplishments" title="2017 Tech Accomplishments"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Evaluating accomplishments motivates me and gives a breath of fresh air for the new ones. I believe that it's an essential exercise for goals setting.&lt;/p&gt;

&lt;p&gt;I'm proud to be a part of &lt;a href="http://stride.com"&gt;Atlassian Stride&lt;/a&gt; team in 2017. Working for the company accelerates professional growth gigantically.&lt;/p&gt;

&lt;p&gt;During my vacation, I analyzed the last year of really hard work (the hardest in my career) to make the list of highlights.&lt;/p&gt;

&lt;h2&gt;The list&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Our product, Atlassian Stride is announced!&lt;/strong&gt; It's not a secret anymore. You can apply for &lt;a href="https://signup.stride.com/"&gt;Early Access Program&lt;/a&gt; and use it. We will be inviting Hipchat Cloud customers to &lt;a href="https://www.stride.com/help-center/upgrade-guide"&gt;upgrade to Stride&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;I became a technical leader of a geo-distributed backend team&lt;/strong&gt;; a part of Atlassian Stride product. The transition happened in November 2016 but the first project was delivered by our team (called &lt;strong&gt;Stride Transformers&lt;/strong&gt;) in February 2017. I think that I finally understood the new role when the services started working in production environment serving needs of real people.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The Stride Transformers engineering team grew up from 4 to 8 members&lt;/strong&gt; including myself. Having all the talented and passioned people moving towards common product goals was essential on the road to success. Here's the shortlist of some things that we delivered playing as a team:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;We built asynchronous Python framework to wrap-up existing codebase and reused it for other projects in the same domain.&lt;/strong&gt; It saved us a lot of time, reduced the number of mistakes,  boring tasks, and recruited members of other teams to join us and learn the framework :). By using the framework, we created around 40 Python services for 10 another related projects. All infrastructure for that was defined as code and described with CloudFormation templates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;We built a Python library that generates ... other async Python libraries&lt;/strong&gt; - clients for internal APIs made by other teams. After that breaking-compatibility changes stopped being a nightmare. It's cheap for us to update our codebase.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using the tooling mentioned we successfully built software from scratch&lt;/strong&gt;, delivered the scheduled projects and moved them to production. The "intimate feeling" of enabling the services in production is unforgettable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Besides the planned work, we had some nerd fun.&lt;/strong&gt; Our team won &lt;a href="https://www.atlassian.com/company/shipit"&gt;Atlassian ShipIt&lt;/a&gt; (a quarterly hackathon) this year two times in a row - in June 2017 and in September 2017. Both in Austin's location and in People's Choice nomination (other fellow Atlassians vote for projects). I learned that making software that works in the staging environment is possible within 24 hours. The main thing - the services built for the first project were productized, polished accordingly and are already running in production. Speaking about the latest ShipIt project - it was selected for Stride Award. Looking forward to tackling it to deliver to our customers.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PQChgNhC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://d1vt1c82ljabfd.cloudfront.net/images/shipit1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PQChgNhC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://d1vt1c82ljabfd.cloudfront.net/images/shipit1.png" alt="June 2017 - We Won Atlassian ShipIt in Austin" title="June 2017 - We Won Atlassian ShipIt in Austin"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4qz1E-_8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://d1vt1c82ljabfd.cloudfront.net/images/shipit2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4qz1E-_8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://d1vt1c82ljabfd.cloudfront.net/images/shipit2.jpg" alt="September 2017 - We Won Stride Award in Austin" title="September 2017 - We Won Stride Award in Austin"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;I think that I learned how to do cross-team collaboration in the right way.&lt;/strong&gt; I'm happy that in Software Engineering you can engage talent worldwide. This year I collaborated with the teams located in Texas, Ukraine, Australia, and California. I like the moment when you first time finally meet a person that worked with you for a couple of months. And go for a lunch :)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;I slightly improved my presentation skills&lt;/strong&gt; and gave two public talks for Austin Python Meetup. Also, I gave a company-wide talk about the technology that we built as well as a dozen of demos for different Stride milestones. The slides from publically available talks can found:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="/talks/#austin-python-meetup-2017-2"&gt;How to Stop Worrying and Start a Project with Python 3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/talks/#austin-python-meetup-2017-1"&gt;What's New in Pythons 3.5 and 3.6?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;br&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Started the &lt;a href="http://AllYouNeedIsBackend.com"&gt;All You Need Is Backend&lt;/a&gt; blog&lt;/strong&gt; and published 9 posts. Some of them were featured on HackerNews and were in Top-5 for a couple of days. I found sharing my thoughts very useful for keeping knowledge in order.&lt;/p&gt;&lt;/li&gt;
&lt;br&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Completed 15 technical online courses&lt;/strong&gt;. Primarily on Amazon Web Services, Distributed Systems, and various Data Storages: Kafka, Cassandra, Hadoop, Riak, and CouchDB.&lt;/p&gt;&lt;/li&gt;
&lt;br&gt;
&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Finally, my tech stack from 2017:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.python.org/"&gt;Python&lt;/a&gt;, and it’s only Python 3&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.python.org/3/library/asyncio.html"&gt;Asyncio&lt;/a&gt;, &lt;a href="https://aiohttp.readthedocs.io"&gt;aiohttp&lt;/a&gt;, and other &lt;a href="https://github.com/aio-libs"&gt;aio-libs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.mysql.com/"&gt;MySQL&lt;/a&gt;, &lt;a href="https://www.elastic.co/products/elasticsearch"&gt;Elasticsearch&lt;/a&gt;, and &lt;a href="https://redis.io/"&gt;Redis&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Amazon Web Services: &lt;a href="https://aws.amazon.com/ec2/"&gt;EC2&lt;/a&gt;, &lt;a href="https://aws.amazon.com/s3/"&gt;S3&lt;/a&gt;, &lt;a href="https://aws.amazon.com/sqs/"&gt;SQS&lt;/a&gt;, &lt;a href="https://aws.amazon.com/rds/"&gt;RDS&lt;/a&gt;, &lt;a href="https://aws.amazon.com/elasticache/"&gt;ElastiCache&lt;/a&gt;, &lt;a href="https://aws.amazon.com/cloudformation/"&gt;CloudFormation&lt;/a&gt;, &lt;a href="https://aws.amazon.com/cloudwatch/"&gt;CloudWatch&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Monitoring: &lt;a href="https://www.datadoghq.com/"&gt;Datadog&lt;/a&gt;, &lt;a href="https://www.elastic.co/products"&gt;Elasticsearch/Logstash/Kibana&lt;/a&gt;, &lt;a href="https://elastalert.readthedocs.io"&gt;ElastAlert&lt;/a&gt;, &lt;a href="https://www.splunk.com/"&gt;Splunk&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Atlassian tools: &lt;a href="https://www.stride.com/"&gt;Stride&lt;/a&gt;, &lt;a href="https://www.atlassian.com/software/jira"&gt;Jira&lt;/a&gt;, &lt;a href="https://www.atlassian.com/software/bitbucket"&gt;Bitbucket&lt;/a&gt;, &lt;a href="https://www.atlassian.com/software/bamboo"&gt;Bamboo&lt;/a&gt;, &lt;a href="https://www.atlassian.com/software/confluence"&gt;Confluence&lt;/a&gt;, and &lt;a href="https://www.atlassian.com/software/trello"&gt;Trello&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Writing the list was great, and I really enjoyed that. I am so grateful that the Atlassian company and Stride organization gave me this opportunity to grow. It was hard to achieve all the things, but we're doing the right ones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kudos to my wife Tania&lt;/strong&gt; for her patience when I had late meetings with Sydney teams (we're &lt;em&gt;8 hours ahead&lt;/em&gt; of them) and extremely early collaboration with my teammates in Ukraine after that (Texas is &lt;em&gt;8 hours behind&lt;/em&gt; them).&lt;/p&gt;

&lt;p&gt;I wrote a list of my tech goals for 2018 but will share this with you in a year. We will see what will be accomplished over the time.&lt;/p&gt;

&lt;p&gt;P.S. I also gained 20 pounds eating BBQ and TexMex. Will try to gain more the next year.&lt;/p&gt;


</description>
      <category>leadership</category>
      <category>career</category>
    </item>
    <item>
      <title>No Tests - No Pull Request, Right? Types of Tests that Should Be in Your Codebase</title>
      <dc:creator>Viach Kakovskyi</dc:creator>
      <pubDate>Mon, 09 Oct 2017 00:00:00 +0000</pubDate>
      <link>https://dev.to/backendandbbq/no-tests---no-pull-request-right-types-of-tests-that-should-be-in-your-codebase-b7g</link>
      <guid>https://dev.to/backendandbbq/no-tests---no-pull-request-right-types-of-tests-that-should-be-in-your-codebase-b7g</guid>
      <description>

&lt;p&gt;&lt;em&gt;Originally published on my blog:&lt;/em&gt; &lt;strong&gt;&lt;a href="http://allyouneedisbackend.com/blog/2017/10/09/no-tests-no-pull-request-types-of-automated-tests-in-backend-software/"&gt;All You Need Is Backend&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As the blog post &lt;strong&gt;&lt;a href="http://allyouneedisbackend.com/blog/2017/08/24/pull-requests-good-bad-and-ugly/"&gt;Pull Requests: The Good, The Bad and The Ugly&lt;/a&gt;&lt;/strong&gt; claims:&lt;/p&gt;

&lt;blockquote&gt;
&lt;h4&gt;If you do not have time to write tests today - you will find the time for fixing bugs Friday’s night&lt;/h4&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words, to establish solid reliability in production tomorrow we need to invest our time today. Your need for tests for your current project depends on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Size of the team that maintains to the codebase: &lt;code&gt;return True if team.size &amp;gt; 1 else False&lt;/code&gt;. Having more engineers means more views on the same items. Tests help to document the opinions how a class or function can be used.&lt;/li&gt;
&lt;li&gt;Size of the codebase: &lt;code&gt;return True if project.modules &amp;gt; 1 else False&lt;/code&gt;.  You can't remember the color of socks that you wore two days ago. Can you remember everything in the project?&lt;/li&gt;
&lt;li&gt;Duration of development and maintenance phases of the project. The script that you run only once can perfectly live without a solid test coverage.  If you're building a system for decades - please, prepare a good legacy for the next generations of developers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have a strong feeling that you think that your code needs tests since you're still reading this.&lt;/p&gt;

&lt;p&gt;In the blog post, I will guide you thru types of automated tests that should be implemented by software engineers: &lt;strong&gt;unit&lt;/strong&gt;, &lt;strong&gt;integration&lt;/strong&gt;, &lt;strong&gt;external&lt;/strong&gt;, and &lt;strong&gt;performance&lt;/strong&gt; ones. It does not cover testing efforts by quality engineers, but the article can still be valuable for them.&lt;/p&gt;

&lt;p&gt;You will find code examples that use Python, but you do not have to know the language.&lt;/p&gt;




&lt;h2&gt;What is an automated test?&lt;/h2&gt;

&lt;p&gt;Software test is a thing that consumes the time that can be rationally used for development of unstable features. Always ask your leadership or business owners what's preferred for the product. It helps to define proper priorities.&lt;/p&gt;

&lt;p&gt;Unexperienced software developers often think that testing it's something that should be done exclusively by quality assurance team.  I tend to disagree. Good engineers own their shit.&lt;/p&gt;

&lt;p&gt;In a test, you call a function that is already written and or still does not exists (read more about &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Test-driven_development"&gt;Test-Driven Development&lt;/a&gt;)&lt;/strong&gt;. You pass some parameters and expect the function to return a specific value. If the value is wrong, that means that the test failed and the code is broken. &lt;em&gt;Or the test is implemented poorly.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Some programming languages provide the ability to wrap tests into the documentation as Python does. It's called &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Doctest"&gt;doctests&lt;/a&gt;)&lt;/strong&gt;.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def multiply(s: str, n: int) -&amp;gt; str:
    """Repeats a string multiple times.

    Args:
        s (str): name to repeat.
        n (int): multiplier.

    Examples:
        &amp;gt;&amp;gt;&amp;gt; multiply('Backend', 2)
        'BackendBackend'
        &amp;gt;&amp;gt;&amp;gt; multiply('Omn', 3)
        'OmnOmnOmn'
    """
    return s * n
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It's easier to write good tests if you test a &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Pure_function"&gt;pure function&lt;/a&gt;&lt;/strong&gt;: the output of a function is completely determined by its inputs. Running pure function has no side effects.&lt;/p&gt;

&lt;p&gt;Automated tests do not exist by themselves. They are executed by Continuous Integration servers like &lt;a href="https://www.atlassian.com/software/bamboo"&gt;Bamboo&lt;/a&gt;, &lt;a href="https://www.g2crowd.com/products/jenkins/reviews"&gt;Jenkins&lt;/a&gt;, or &lt;a href="https://travis-ci.org/"&gt;Travis CI&lt;/a&gt;. Usually, the tests are executed for each submitted PR. If the build is green - the branch can be considered to merged into the master branch after code review. Obviously, engineers run tests locally before pushing code. Nobody likes reviewing a priory not working pull requests.&lt;/p&gt;

&lt;p&gt;In the next sections, you can find the overview of tests that I recommend to supply with backend software.&lt;/p&gt;

&lt;h2&gt;Unit tests&lt;/h2&gt;

&lt;p&gt;This type of tests is the most popular and the most known. One of the right questions to ask during a job interview for a new company can be "Does your team write unit tests for new code?".&lt;/p&gt;

&lt;p&gt;Jokes aside, the purpose of a unit test is to ensure that an atomic unit of code works as expected. Usually, the unit of code is a function or a method.&lt;br&gt;
Unit tests must be small, fast, keep everything inside one process that runs a test suite. And do not interact with anything else. The type of tests is a great tool when we need to check the correctness of business rules in your code.&lt;/p&gt;

&lt;p&gt;Here's the example of a unit test for the function &lt;code&gt;parse_fullname&lt;/code&gt; that parses full name of a person to get Firstname and Lastname:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from unittest import TestCase

from utils import parse_fullname

class ParseFullnameTestCase(TestCase):
    def test_parse_fullname(self):
        cases = [
            ('John Doe', ('John', 'Doe'), 'first and last name'),
            ('John David Doe', ('John David', 'Doe'), 'first, middle, last name'),
            ('John David van Eck de la Nova Doe', ('John David van Eck de la Nova', 'Doe'),
                'many name parts'),
            ('John', ('John', 'John'), 'single name'),
            ('John David Doe, Jr.', ('John David', 'Doe Jr'), 'Jr. suffix'),
            ('John Doe II', ('John', 'Doe II'), 'II suffix'),
            ('Mr. John Doe', ('John', 'Doe'), 'Mr. prefix'),
            ('Вячеслав Каковський', ('Вячеслав', 'Каковський'), 'unicode chars')
        ]
        for name, expected_output, description in cases:
            self.assertEqual(parse_fullname(name), expected_output, msg='Failed for {}'.format(description))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The test checks if the returned value matches the expected one for each of the cases and provides the explanation when an assertion is failed.&lt;/p&gt;

&lt;p&gt;Again, it's better if unit tests are fast. For example, execution of hundreds of unittests for production software takes seconds, rarely minutes.&lt;/p&gt;

&lt;p&gt;How to make good unit tests without side effects?&lt;br&gt;
We can use &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Dependency_injection"&gt;Dependency Injection&lt;/a&gt;&lt;/strong&gt; to substitute objects that perform heavy operations with &lt;strong&gt;&lt;a href="https://martinfowler.com/articles/mocksArentStubs.html"&gt;Mocks, Stubs, or Fake objects&lt;/a&gt;&lt;/strong&gt;. Yes, your unit test should not perform I/O operations, like reading/writing data from a database, performing HTTP calls and so on. Check a unit test for the &lt;code&gt;@retry&lt;/code&gt; decorator that tries to reattempt execution if an exception of specified type occurred.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from aiohttp import DisconnectedError
from asynctest import TestCase, CoroutineMock as Mock

from utils import retry

class RetryTest(TestCase):
    async def test_retry(self):
        self._func = Mock(return_value=200, 
                          side_effect=[DisconnectedError, 
                                       DisconnectedError, 200]

        @retry(DisconnectedError)
        async def get_http_status():
            return await self._func()

        res = await get_http_status()
        self.assertEqual(res, 200)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We use &lt;code&gt;Mock&lt;/code&gt; object to introduce a function with the predefined behavior: raising  &lt;code&gt;DisconnectedError&lt;/code&gt; two times and returning status code 200 that means successful HTTP-request. Thankfully to that, we do not have to perform the actual request to some web server and do all slow I/O work. Also, we do not need to perform some tweaks with configuring the server or load balancer to break the connection for each execution of the test.&lt;/p&gt;

&lt;p&gt;I encourage you to read about the &lt;code&gt;retry&lt;/code&gt; function in my another blog post &lt;strong&gt;&lt;a href="http://allyouneedisbackend.com/blog/2017/09/15/how-backend-software-should-retry-on-failures/"&gt;Never Give Up, Retry: How Software Should Deal with Failures&lt;/a&gt;&lt;/strong&gt;. I found the technique very useful during making backend that depends on various other services.&lt;/p&gt;

&lt;p&gt;Examples from real life when a unit test is a good fit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;all types of parsing: messages, documents, arguments, and configuration&lt;/li&gt;
&lt;li&gt;checking business rules and corner cases&lt;/li&gt;
&lt;li&gt;input validation or other verification of chains of complex if-else statements&lt;/li&gt;
&lt;li&gt;calculation of math formulas, like business rules for discounts&lt;/li&gt;
&lt;li&gt;complex data transformations from one format to another&lt;/li&gt;
&lt;li&gt;verification of SQL-queries compiled by ORM (do not mix with execution of the queries against a database)&lt;/li&gt;
&lt;li&gt;when you need to check that invocation of one function leads to a call of another one; I highly recommend to use mocks for that&lt;/li&gt;
&lt;li&gt;verification of firing network operations, but do not forget to replace actual I/O operations with stubs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For most of the modern programming languages, you can find great toolbox for writing good unit tests fast. It might include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;primitives for implementing Mocks, Stubs, and Fake objects&lt;/li&gt;
&lt;li&gt;hooks for running before/after a test in test suite&lt;/li&gt;
&lt;li&gt;utility for running a set of tests from command line&lt;/li&gt;
&lt;li&gt;tools for running tests under various environments, like versions of interpreter/virtual machine.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Integration tests&lt;/h2&gt;

&lt;p&gt;The main purpose of the type of tests - verify cooperation between various modules and components that &lt;em&gt;you develop&lt;/em&gt;. Here you're encouraged to perform I/O operations in your tests, therefore, the test suites might be running slow.&lt;/p&gt;

&lt;p&gt;These tests are focused on API contract on your subsystems as well as integration with the data storages that you use.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h4&gt;The main feature of integration tests for me is that they do not have to run only inside one process: tested code can perform a syscall or execute a query against a real database.&lt;/h4&gt;
&lt;/blockquote&gt;

&lt;p&gt;Check out integration tests for &lt;code&gt;SQLAlchemyEngine&lt;/code&gt; class that  implements database wrappers for the high-level methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;execute&lt;/code&gt;: executes SQLAlchemy query, return the number of affected rows&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fetchone&lt;/code&gt;: shorthand for fetching one DB entry&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fetchall&lt;/code&gt;: shorthand for fetching all DB entries.&lt;/li&gt;
&lt;/ul&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import uuid

from asynctest import TestCase

from database import SQLAlchemyEngine, users
from utils import get_config


class DBEngineTests(TestCase):
    async def setUp(self):
        self._user_data = {'user_id': 100500,
                           'external_id': uuid.uuid4().hex,
                           'name': 'Viach'}
        self._db_engine = self._get_db_engine()
        self._user = await self._create_user(self._user_data)

    async def tearDown(self):
        async with self._db_engine.acquire() as conn:
            await conn.execute(users.delete())

    async def test_fetchone(self):
        fetched_user = await self._db_engine.fetchone(
            users.select(users.c.id == self._user['id']))
        self.assertEqual(fetched_user, self._user_data)

    async def test_execute_delete_user(self):
        rowcount = await self._db_engine.execute(
            users.delete(users.c.id == self._user['id']))
        self.assertEqual(rowcount, 1)

        fetched_user = await self._db_engine.fetchone(
            users.select(users.c.id == self._user['id']))
        self.assertIsNone(fetched_user)

    async def test_fetchone_not_exists(self):
        fetched_user = await self._db_engine.fetchone(
            users.select(users.c.id == self._user['id'] + 1))
        self.assertIsNone(fetched_user)

    async def test_fetchall(self):
        fetched_users = await self._db_engine.fetchall(
            users.select(users.c.id == self._user['id']))
        self.assertLenEqual(fetched_users, 1)
        self.assertEqual(fetched_users[0], self._user_data)

    async def _create_user(self, user_data):
        async with self._db_engine.acquire() as conn:
            await conn.execute(users.insert().values(**user_data))

            result = await conn.execute(users.select().where(
                users.c.id == user_data['id']))
            return result

    async def _get_db_engine(self):
        return await SQLAlchemyEngine.from_config(get_config()['mysql']['userbase'],
                                                  loop=self.loop)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I think that an integration test is a perfect idea when you need to verify database-related code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;embedding a third-party driver for a datastore in your codebase; a smoke test that inserts a record and fetches that is usually enough&lt;/li&gt;
&lt;li&gt;complex queries that depend on the state of database; do not forget to set the state in a pre-test hook&lt;/li&gt;
&lt;li&gt;not-complex queries in the case when you do not use ORM and cannot check compiled statements (using ORM you can do this with unit tests)&lt;/li&gt;
&lt;li&gt;homebrew wrappers/patches of existing database drivers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other possible applications of integration tests from my experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;testing of contracts between your subsystems, like public interfaces between modules&lt;/li&gt;
&lt;li&gt;verification of communications between your services; say, a test that ensures that a service performs a request against another one for some task.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note, that you still can and should use mocks to replace some parts of the software to make the establishing environment for tests easier and execution of tests faster. It helps to keep time for running the type of tests in the range between minutes and few dozens of minutes.&lt;/p&gt;

&lt;p&gt;We reviewed unit and integration tests, the purpose of the first category is to verify that individual components work as expected; the reason to write the second ones - check that combination of the pieces that you implemented plays as a team.&lt;/p&gt;

&lt;p&gt;But what if your product involves the software not written by your team and runs not under control of the organization? Time to look into the next category of tests.&lt;/p&gt;

&lt;h2&gt;External tests&lt;/h2&gt;

&lt;p&gt;You should write external tests when you need to track contracts between your software and third-party services that cannot be controlled by your team. It can be services maintained by other teams inside your company or software that runs on the infrastructure of your vendors, partners, or even competitors.&lt;/p&gt;

&lt;p&gt;Real examples of things to be tested with an external test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API contracts between teams in your company&lt;/li&gt;
&lt;li&gt;usage of services provided by your cloud provider; it's AWS in my case;&lt;/li&gt;
&lt;li&gt;integrations with Developer APIs of services like &lt;a href="https://developer.atlassian.com/cloud/stride/"&gt;Stride&lt;/a&gt;, &lt;a href="https://developer.atlassian.com/hipchat"&gt;Hipchat&lt;/a&gt;, &lt;a href="https://developer.atlassian.com/bitbucket/api/2/reference/"&gt;Bitbucket&lt;/a&gt;, &lt;a href="https://developers.trello.com/v1.0/reference"&gt;Trello&lt;/a&gt;, &lt;a href="https://developer.github.com/"&gt;GitHub&lt;/a&gt;, &lt;a href="https://api.slack.com/"&gt;Slack&lt;/a&gt;, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You might be interested why external tests are in a separate category instead of being a part of integration tests?&lt;/p&gt;

&lt;p&gt;Firstly, not necessary that your team can fix a failure of an external test. If the system is broken on the other end - you can only file a bug report and try to prioritize it.&lt;/p&gt;

&lt;p&gt;Secondary, since you do not control the environment on the other end some failures can be random: issues with availability, poor deployments, etc.&lt;/p&gt;

&lt;p&gt;Check out the example of an external test for verification of code that works with Amazon SQS:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; class SQSTestCase(TestCase):
    async def setUp(self):
        config = get_config()
        self.client = await SQSClient.from_config(config, loop=self.loop)

    def tearDown(self):
        self.client.close()

    async def test_send_and_receive(self):
        msg = {'id': 100500,
               'description': 'some important SQS task'}
        await self.client.send_message(msg)
        result = await self.client.receive_messages()
        self.assertEqual(result, [msg])
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In &lt;em&gt;some cases&lt;/em&gt; it can be okay to ignore failures of external tests to do not block deployments. But it's still required to figure out the reason of red builds.&lt;/p&gt;

&lt;h2&gt;Performance tests&lt;/h2&gt;

&lt;blockquote&gt;
&lt;h4&gt;The purpose of performance testing is to predict when we fu*k production.&lt;/h4&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words, it helps to find out conditions when our algorithms, architecture, or infrastructure cannot handle load properly.&lt;br&gt;
I believe that performance testing is a must for a high load system. I published a short blog &lt;strong&gt;&lt;a href="http://allyouneedisbackend.com/blog/2017/08/30/what-is-highload/"&gt;What Is a Highload Project?&lt;/a&gt;&lt;/strong&gt; about my definition of the term, check out if you're interested.&lt;/p&gt;

&lt;p&gt;Look into the steps to add performance testing into your workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identify&lt;/strong&gt; how the load might grow up. Possible cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More users start using the software that you build.&lt;/li&gt;
&lt;li&gt;More data is sent thru your processing pipeline.&lt;/li&gt;
&lt;li&gt;You need to shrink capacity of your servers because of changes in your budgeting.&lt;/li&gt;
&lt;li&gt;All sorts of unexpected edge cases.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Define&lt;/strong&gt; the most heavy and frequent operations. Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Insertions into data storages.&lt;/li&gt;
&lt;li&gt;Calculations and other CPU-bound tasks.&lt;/li&gt;
&lt;li&gt;Calls to external services.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Identify&lt;/strong&gt; how to trigger the operations above from a user's perspective. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP/XMPP/your-favorite-protocol handlers.&lt;/li&gt;
&lt;li&gt;REST API endpoints.&lt;/li&gt;
&lt;li&gt;Periodic processing of collected data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Setup collecting of product metrics&lt;/strong&gt; for the identified operations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Application metrics can be collected using StatsD. The most often I use counters and timers.&lt;/li&gt;
&lt;li&gt;For per-instance metrics, I can recommend CollectD. Top 5 metrics to look into: Load Average, CPU, RAM, Bytes received/sent, and Free disk.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Create a tool&lt;/strong&gt; that behaves like gazillions customers using your product and triggering the heavy operations. For a web server such actions can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Establishing network connections.&lt;/li&gt;
&lt;li&gt;Making HTTP requests, sending data and retrieving information.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Run the tooling&lt;/strong&gt; in the staging environment with enabled metrics collection. Roll out the load gracefully to investigate the behavior of your system, pay attention to any spike. You also can test autoscaling of the infrastructure if you use any.  &lt;/p&gt;

&lt;p&gt;Possible results of a successful session of performance testing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You know how many requests per second can be served by a particular configuration of infrastructure.&lt;/li&gt;
&lt;li&gt;You know how the system behaves when the limit is exceeded.&lt;/li&gt;
&lt;li&gt;You see the bottlenecks of the platform.&lt;/li&gt;
&lt;li&gt;You understand if some part of the system can be scaled.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://locust.io/"&gt;LocustIO&lt;/a&gt; can be a good thing to start implementation of performance testing. It's written in Python, runs load tests distributed over multiple hosts and support various protocols including &lt;a href="https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol"&gt;HTTP&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/XMPP"&gt;XMPP&lt;/a&gt;, and &lt;a href="https://en.wikipedia.org/wiki/XML-RPC"&gt;XML-RPC&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;In the blog post, we briefly introduced four types of tests. From my experience, the tests should be provided by the engineering teams that are actively involved in the development of your product, not a separate quality engineering team.&lt;/p&gt;

&lt;p&gt;Check out the summary about each kind of tests below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unit tests:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Small and isolated.&lt;/li&gt;
&lt;li&gt;Keep everything within one process, the code in tests should not lead to system calls.&lt;/li&gt;
&lt;li&gt;Extremely fast.&lt;/li&gt;
&lt;li&gt;Good fit for checking business rules.&lt;/li&gt;
&lt;li&gt;Run inside your development environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Integration tests:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The main purpose - verify that various components work well together.&lt;/li&gt;
&lt;li&gt;Can perform I/O operations.&lt;/li&gt;
&lt;li&gt;Slow.&lt;/li&gt;
&lt;li&gt;Execution flow can be distributed across processes.&lt;/li&gt;
&lt;li&gt;Run in your development environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;External tests:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure that reached API contracts are implemented properly.&lt;/li&gt;
&lt;li&gt;Involve calls to software that runs out of your direct control.&lt;/li&gt;
&lt;li&gt;Run between your development environment and third-party. servers.&lt;/li&gt;
&lt;li&gt;Tend to be very slow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Performance tests:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Help to save the reputation of your business if the product can be under high load.&lt;/li&gt;
&lt;li&gt;Require additional preparations but worth it.&lt;/li&gt;
&lt;li&gt;Are executed in the staging environment.&lt;/li&gt;
&lt;li&gt;Very very slow, should be run within scheduled windows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think that each mature programming language has own variation of &lt;a href="https://en.wikipedia.org/wiki/XUnit"&gt;xUnit&lt;/a&gt; - like toolset for writing automated tests for fun and profit.&lt;/p&gt;

&lt;p&gt;I hope you found the practical examples in the blog post useful for your team. During the last three years, our teams invested a lot of resources into providing various types of tests as a part of a pull request. We found this rewarding and valuable for our product.&lt;/p&gt;

&lt;p&gt;The teams feel more healthy working in the environment when we have enough test coverage since we're protected from code regression.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What types of tests do you provide for your code?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much time do you spend dealing with fixing the features that were delivered a while ago?&lt;/strong&gt;&lt;/p&gt;


</description>
      <category>testing</category>
      <category>python</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The SQL I Love. Efficient pagination of a table with 100M records</title>
      <dc:creator>Viach Kakovskyi</dc:creator>
      <pubDate>Sun, 24 Sep 2017 00:00:00 +0000</pubDate>
      <link>https://dev.to/backendandbbq/the-sql-i-love-chapter-one</link>
      <guid>https://dev.to/backendandbbq/the-sql-i-love-chapter-one</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on my blog:&lt;/em&gt; &lt;a href="http://allyouneedisbackend.com/blog/2017/09/24/the-sql-i-love-part-1-scanning-large-table/" rel="noopener noreferrer"&gt;All You Need Is Backend&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9bxt8z38ti40ft78j0l5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9bxt8z38ti40ft78j0l5.jpg" title="The SQL Queries I Loved &amp;lt;3. Chapter One" alt="The SQL Queries I Loved &amp;lt;3. Chapter One" width="355" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am a huge fan of databases. I even wanted to make my own DBMS when I was in university. Now I work both with &lt;a href="https://en.wikipedia.org/wiki/Relational_database_management_system" rel="noopener noreferrer"&gt;RDBMS&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/NoSQL" rel="noopener noreferrer"&gt;NoSQL&lt;/a&gt; solutions, and I am very enthusiastic with that. You know, there's no &lt;a href="https://en.wikipedia.org/wiki/Law_of_the_instrument" rel="noopener noreferrer"&gt;Golden Hammer&lt;/a&gt;, each problem has own solution. Alternatively, a subset of solutions.&lt;/p&gt;

&lt;p&gt;In the series of blog posts &lt;strong&gt;The SQL I Love &amp;lt;3&lt;/strong&gt; I walk you thru some problems solved with SQL which I found particularly interesting. The solutions are tested using a table with more than 100 million records.  All the examples use MySQL, but ideas apply to other relational data stores like PostgreSQL, Oracle and SQL Server.&lt;/p&gt;

&lt;p&gt;This Chapter is focused on efficient scanning a large table using pagination with &lt;code&gt;offset&lt;/code&gt; on the primary key. This is also known as &lt;strong&gt;keyset pagination&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;In the chapter, we use the following database structure for example. The canonical example about users should fit any domain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE `users` (
  `user_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `external_id` varchar(32) NOT NULL,
  `name` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  `metadata` text COLLATE utf8_unicode_ci,
  `date_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`user_id`),
  UNIQUE KEY `uf_uniq_external_id` (`external_id`),
  UNIQUE KEY `uf_uniq_name` (`name`),
  KEY `date_created` (`date_created`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few comments about the structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;external_id&lt;/code&gt; column stores reference to the same user in other system in UUID format&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt; represents &lt;code&gt;Firstname Lastname&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;metadata&lt;/code&gt; column contains JSON blob with all kinds of unstructured data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The table is relatively large and contains around 100 000 000 records. Let's start our learning journey.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scanning a Large Table
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: You need to walk thru the table, extract each record, transform it inside your application's code and insert to another place. We focus on the first stage in the post - &lt;em&gt;scanning the table&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Obvious and wrong solution&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT user_id, external_id, name, metadata, date_created
FROM users;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case with 100 000 000 records, the query is never finished. The DBMS just kills it. Why? Probably, because it led to the attempt to load the whole table into RAM. Before returning data to the client. Another assumption - it took too much time to pre-load the data before sending and the query was timed out.&lt;br&gt;
Anyway, our attempt to get all records in time failed. We need to find some other solution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution #2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We can try to get the data in pages. Since records are not guaranteed to be ordered in a table on physical or logical level - we need to sort them on the DBMS side with &lt;code&gt;ORDER BY&lt;/code&gt; clause.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT user_id, external_id, name, metadata, date_created
FROM users
ORDER BY user_id ASC
LIMIT 0, 10 000;

10 000 rows in set (0.03 sec)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sweet. It worked. We asked the first page of 10 000 records, and it took only &lt;code&gt;0.03&lt;/code&gt; sec to return it. However, how it would work for the 5000th page?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT user_id, external_id, name, metadata, date_created
FROM users
ORDER BY user_id ASC
LIMIT 50 000 000, 10 000; --- 5 000th page * 10 000 page size

10 000 rows in set (40.81 sec)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Indeed, this is very slow. Let's see how much time is needed to get the data for the latest page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT user_id, external_id, name, metadata, date_created
FROM users
ORDER BY user_id ASC
LIMIT 99 990 000, 10 000; --- 9999th page * 10 000 page size

10 000 rows in set (1 min 20.61 sec)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is insane. However, can be OK for solutions that run in the background. One more hidden problem with the approach can be revealed if you try to delete a record from the table in the middle of scanning it. Say, you finished the 10th page (100 000 records are already visited), going to scan the records between 100 001 and 110 000. But records 99 998 and 99 999 are deleted before the next &lt;code&gt;SELECT&lt;/code&gt; execution. In that case, the following query returns the unexpected result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; SELECT user_id, external_id, name, metadata, date_created
 FROM users
 ORDER BY user_id ASC
 LIMIT 100 000, 10 000;

 N, id, ...
 1, 100 003, ...
 2, 100 004, ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the query skipped the records with ids 100 001 and 100 002. They will not be processed by application's code with the approach because after the two delete operations they appear in the first 100 000 records. Therefore, the method is unreliable if the dataset is mutable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution #3 - the final one for today&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The approach is very similar to the previous one because it still uses paging, but now instead of relying on the number of scanned records, we use the &lt;code&gt;user_id&lt;/code&gt; of the latest visited record as the &lt;code&gt;offset&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Simplified algorithm:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We get &lt;code&gt;PAGE_SIZE&lt;/code&gt; number of records from the table. Starting offset value is 0.&lt;/li&gt;
&lt;li&gt;Use the max returned value for &lt;code&gt;user_id&lt;/code&gt; in the batch as the offset for the next page.&lt;/li&gt;
&lt;li&gt;Get the next batch from the records which have &lt;code&gt;user_id&lt;/code&gt; value higher than current &lt;code&gt;offset&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The query in action for 5 000th page, each page contains data about 10 000 users:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT user_id, external_id, name, metadata, date_created
FROM users
WHERE user_id &amp;gt; 51 234 123 --- value of user_id for 50 000 000th record
ORDER BY user_id ASC
LIMIT 10 000;

10 000 rows in set (0.03 sec)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;h4&gt;
  
  
  Wow, it is significantly faster than the previous approach. More than in 1000 times.
&lt;/h4&gt;
&lt;/blockquote&gt;

&lt;p&gt;Note, that the values of &lt;code&gt;user_id&lt;/code&gt; are not sequential and can have gaps like 25 348 is right after 25 345. The solution also works if any records from future pages are deleted - even in that case query does not skip records. Sweet, right?&lt;/p&gt;

&lt;h2&gt;
  
  
  Explaining performance
&lt;/h2&gt;

&lt;p&gt;For further learning, I recommend investigating results of &lt;code&gt;EXPLAIN EXTENDED&lt;/code&gt; for each version of the query to get the next 10 000 records after 50 000 000.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| Solution          | Time      | Type  | Keys       | Rows | Filtered | Extra
------------------------------------------------------------------------------
| 1. Obvious        | Never     | ALL   | NULL       | 100M | 100.00   | NULL
| 2. Offset paging  | 40.81 sec | index | NULL / PRI | 50M  | 200.00   | NULL
| 3. Keyset paging  | 0.03 sec  | range | PRI / PRI  | 50M  | 100.00   | Using where
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's focus on the key difference between execution plans for 2nd and 3rd solutions since the 1st one is not practically useful for large tables.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Join type&lt;/strong&gt;: &lt;code&gt;index&lt;/code&gt; vs &lt;code&gt;range&lt;/code&gt;. The first one means that whole index tree is scanned to find the records. &lt;code&gt;range&lt;/code&gt; type tells us that index is used only to find matching rows within a specified range. So, &lt;code&gt;range&lt;/code&gt; type is faster than &lt;code&gt;index&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Possible keys&lt;/strong&gt;: &lt;code&gt;NULL&lt;/code&gt; vs &lt;code&gt;PRIMARY&lt;/code&gt;. The column shows the keys that can be used by MySQL. BTW, looking into &lt;strong&gt;keys&lt;/strong&gt; column, we can see that eventually &lt;code&gt;PRIMARY&lt;/code&gt; key is used for the both queries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rows&lt;/strong&gt;: &lt;code&gt;50 010 000&lt;/code&gt; vs &lt;code&gt;50 000 000&lt;/code&gt;. The value displays a number of records analyzed before returning the result. For the 2nd query, the value depends on how deep is our scroll. For example, if we try to get the next &lt;code&gt;10 000&lt;/code&gt; records after 9999th page then &lt;code&gt;99 990 000&lt;/code&gt; records are examined. In opposite, the 3rd query has a constant value; it does not matter if we load data for the 1st page of the very last one. It is always half size of the table.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filtered&lt;/strong&gt;: &lt;code&gt;200.00&lt;/code&gt; vs &lt;code&gt;100.00&lt;/code&gt;. The column indicates estimated the percentage of the table to be filtered before processing. Having the higher value is better. The value of &lt;code&gt;100.00&lt;/code&gt; means that the query looks thru the whole table. For the 2nd query, the value is not constant and depends on the page number: if we ask 1st page the value of filtered column would be &lt;code&gt;1000000.00&lt;/code&gt;. For the very last page, it would be &lt;code&gt;100.00&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extra&lt;/strong&gt;: &lt;code&gt;NULL&lt;/code&gt; vs &lt;code&gt;Using where&lt;/code&gt;. Provides additional information about how MySQL resolves the query. Usage of &lt;code&gt;WHERE&lt;/code&gt; on &lt;code&gt;PRIMARY&lt;/code&gt; key make the query execution faster.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I suspect that &lt;strong&gt;join type&lt;/strong&gt; is the parameter of the query that made the largest contribution to performance to make the 3rd query faster. Another important thing is that the 2nd query is extremely dependent on the number of the page to scroll. More deep pagination is slower in that case.&lt;/p&gt;

&lt;p&gt;More guidance about understaing output for &lt;code&gt;EXPLAIN&lt;/code&gt; command can be found in &lt;a href="https://dev.mysql.com/doc/refman/5.6/en/explain-output.html" rel="noopener noreferrer"&gt;the official documentation for your RDBMS&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;The main topic for the blog post was related to scanning a large table with 100 000 000 records using &lt;code&gt;offset&lt;/code&gt; with a primary key (keyset pagination). Overall, 3 different approaches were reviewed and tested on the corresponding dataset. I recommend only one of them if you need to scan a mutable large table.&lt;/p&gt;

&lt;p&gt;Also, we revised usage of &lt;code&gt;EXPLAIN EXTENDED&lt;/code&gt; command to analyze execution plan of MySQL queries. I am sure that other RDBMS have analogs for the functionality.&lt;/p&gt;

&lt;p&gt;In the next chapter, we will pay attention to data aggregation and storage optimization. Stay tuned!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's your method of scanning large tables?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you remember any other purpose of using offset on the primary key?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>sql</category>
      <category>database</category>
    </item>
    <item>
      <title>Never Give Up, Retry: How Software Should Deal with Failures</title>
      <dc:creator>Viach Kakovskyi</dc:creator>
      <pubDate>Fri, 15 Sep 2017 00:00:00 +0000</pubDate>
      <link>https://dev.to/backendandbbq/never-give-up-retry-how-software-should-deal-with-failures</link>
      <guid>https://dev.to/backendandbbq/never-give-up-retry-how-software-should-deal-with-failures</guid>
      <description>

</description>
      <category>webdev</category>
      <category>python</category>
    </item>
    <item>
      <title>What Is a Highload Project?</title>
      <dc:creator>Viach Kakovskyi</dc:creator>
      <pubDate>Wed, 30 Aug 2017 00:00:00 +0000</pubDate>
      <link>https://dev.to/backendandbbq/what-is-a-highload-project</link>
      <guid>https://dev.to/backendandbbq/what-is-a-highload-project</guid>
      <description>

</description>
      <category>highload</category>
      <category>career</category>
      <category>programming</category>
    </item>
    <item>
      <title>Pull Requests: The Good, The Bad and The Ugly</title>
      <dc:creator>Viach Kakovskyi</dc:creator>
      <pubDate>Fri, 25 Aug 2017 00:00:00 +0000</pubDate>
      <link>https://dev.to/backendandbbq/pull-requests-the-good-the-bad-and-the-ugly</link>
      <guid>https://dev.to/backendandbbq/pull-requests-the-good-the-bad-and-the-ugly</guid>
      <description>

</description>
      <category>python</category>
      <category>career</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>🌮 Tacos Delivery Over HTTP/2</title>
      <dc:creator>Viach Kakovskyi</dc:creator>
      <pubDate>Wed, 23 Aug 2017 00:00:00 +0000</pubDate>
      <link>https://dev.to/backendandbbq/-tacos-delivery-over-http2</link>
      <guid>https://dev.to/backendandbbq/-tacos-delivery-over-http2</guid>
      <description>

</description>
      <category>http</category>
      <category>tacos</category>
    </item>
    <item>
      <title>How To Choose a Technology For a Commercial Project. Harmful Advice</title>
      <dc:creator>Viach Kakovskyi</dc:creator>
      <pubDate>Sun, 20 Aug 2017 00:00:00 +0000</pubDate>
      <link>https://dev.to/backendandbbq/how-to-choose-a-technology-for-a-commercial-project-harmful-advice</link>
      <guid>https://dev.to/backendandbbq/how-to-choose-a-technology-for-a-commercial-project-harmful-advice</guid>
      <description>

</description>
      <category>leadership</category>
      <category>harmfuladvice</category>
      <category>career</category>
      <category>management</category>
    </item>
  </channel>
</rss>
