Secrets for becoming a better developer in 2022

Yearly I share my new tricks to become a better developer. This year I am bringing some concepts from other fields and applying them to my day-to-day as a developer. I divided the tips into two categories Technical and Productivity. I understand to be a better developer, you will eventually need to go beyond coding well, and being more productive will play an important role in it.

Technical tips

1. Always go home with a broken build

chart

Imagine starting every day knowing exactly what to do, with all the context needed, and ready to start typing code and fixing the next problem. This is what this tip may bring you.

In the book Continuous Delivery[1], there is a chapter called “Never go home on a broken build”; where the authors express that when you go back to work the next day, it “would take significantly longer to understand the problem and fix it.”

In reality, it is precisely the opposite. When you have a broken build pending in a Pull Request (not master/main branch, of course) you left on the last day, you will know where to start. If you leave no broken build behind, you will wonder what to do next, and you may lose momentum to start your day. The idea is to build immediate momentum the following day using yesterday’s energy.

I borrowed this idea from the book “Building a Second Brain,” which is called “The Hemingway bridge”[2]. Hemingway was a writer and Nobel Prize in Literature in 1954 [3]. His idea was to build himself a bridge from yesterday to today and get immediately in flow. Hemingway always left a few sentences of the next chapter before finishing the day, so he would jump right into the writing flow on the following day instead of starting from a blank page.


Building your Hemingway bridge

Perfect working or finished software is as hard for Developers as a blank page for writers because it is hard to decide what to do next.

How to ensure you will know exactly where to start the next day?

At the end of a successful task or day, use the success momentum to build your “Hemingway bridge” for the next day, implementing the first test for the next task; it can be a simple test (researchers have shown that simple tests can prevent most critical failures[4]). Push it, open a Draft or WIP pull request, leave it broken, and go for your leisure time. The next day, there will be no doubt about where to start. Fixing the test will pump success into your day and help you get into flow right away.

For example, in my project Nun-db, it is not rare to find PRs that will run for months with commits separated by weeks from each other in the Nun-db repository. Like the one in the image here, the PR 65 runs for over 30 days. Another example is the one I am working on now, the PR 74. That one is a significant change that has been going on for the previous three months. It would be nearly impossible to conclude it if I didn’t have a way to get into flow quickly.

In case you are investigating something or doing data analyses, a good way to build your bridge is to add one event to the first hour of your calendar with a title to get your attention and a few lines of text to put you back in the context.

Moreover, In a past post, “How not to burnout when working on hard problems as a developer”, I give some other tips that can be complementary to this one.


2. Use napkin math to do estimations

Don’t be surprised too late

Napkin math is the act of estimating results, usually quick estimations.

Let’s say you need to migrate files from servers in East to West deployments, and you know you have 100GiB to transfer. Instead of waiting for the last day to discover how long it is going to take, you can quickly estimate that time and save a lot of headaches later. In this case, for example, let’s suppose you know that the latency between East and West is ~60ms, and to transfer 1GiB will take about 40s; if you need to move 100GiB no way you can do it in less than 4000s.

How does one know that? There is this excellent repo where you can find useful data to perform this kind of estimation napkin-math repo.

The point here is not what we know but why we do that in the first place. The goal of the napkin estimations is not to be precise, nor to cover every possibility of change, but rather to find if some task is viable quickly in the first place and to set expectations correctly.

I was recently asked to help on a project by the customer I am consulting. They needed to transfer ~1Pbs from one cloud provider to another. Also, to sync files that have changed since the last synchronization. The team has decided to use a “Storage Transfer Service” provided by one of the providers. At my first look at the last execution of the tests, they have made with ~30G taking 3 minutes to run even if no files needed to be transferred.

In this case, I did not even need more data to calculate that this Job would take +60 days to run every single time at total capacity. The team ran with that assumption for months, and it would have been catastrophic to find out only when the actual data was being transferred.

Use napkin math any time you have the chance ** do not avoid estimations**. There is a fantastic podcast on the subject “Estimating systems with napkin math” that is a must-listen.

3. Learn a little data analysis and statistics (R or python)

chart The things you know shape the way you think about problems. Learning data-science will give you a new approach. I learned R a few years ago while working towards my master’s degree, and it became a new tool that assists me every once in a while when debugging some problem or exploring data to find patterns.

Statistics will help you understand challenges differently, like why “mean” is not a good indication of performance in many cases. When analyzing latency or performance, other stats like p50th or p95th are probably more well-suited. Sometimes analyzing the outliers is much more important than looking at the mean. In the book “Designing Data-Intensive Applications The Big Ideas Behind Reliable, Scalable, and Maintainable Systems,” the author makes a case for why, when developing Databases, it is more important to analyze the outliers than the average time of the operations.

Practical example: How is the query time in Nun-db central cluster behaving at the moment?

  1. Nun-db has a log that looks like the following :
kubectl logs -n nun-db nun-db-0 | grep "Server processed message" | grep "ms"
# result
[2022-09-17T20:00:53.762732436Z nun_db::lib::process_request] [140052877585184] Server processed message 'unwatch-all' in 1.43553ms
[2022-09-17T20:01:04.728929219Z nun_db::lib::process_request] [140052873366304] Server processed message 'keys' in 6.380791ms
[2022-09-17T20:01:04.976895062Z nun_db::lib::process_request] [140052875475744] Server processed message 'replicate-snapshot data-analysis-demo' in 24.995429ms
[2022-09-17T20:01:46.599021078Z nun_db::lib::process_request] [140052883925792] Server processed message 'unwatch-all' in 88.650531ms
[2022-09-17T20:02:36.880030988Z nun_db::lib::process_request] [140052873366304] Server processed message 'unwatch-all' in 1.341609ms
[2022-09-17T20:03:54.604792578Z nun_db::lib::process_request] [140052883925792] Server processed message 'unwatch-all' in 413.140681ms
  1. Well, now I need to clean it up. Since I only want the last value in that text, for that, I will use the awk command to select only the last item on the list.
kubectl logs -n nun-db nun-db-0 | grep "Server processed message" | grep "ms" | awk ' { print $NF }'
# Result
119.083925ms
95.040448ms
26.294053ms
1.43553ms
6.380791ms
24.995429ms
88.650531ms
1.341609ms
413.140681ms
  1. Now, I need to make it only numbers. So to clean the ms I will use the sed command to replace ms for nothing.
kubectl logs -n nun-db nun-db-0 | grep "ms" | awk ' { print $(NF)}' | sed -e 's/ms//g'
# Results
26.294053
1.43553
6.380791
24.995429
88.650531
1.341609
413.140681
1.287629
86.588362
98.915579
1.728519
89.525347
  1. Finally, I will use R to analyze the stats I need.
kubectl logs -n nun-db nun-db-0 | grep "ms" | awk ' { print $(NF)}' | sed -e 's/ms//g' | R --slave -e 'a <- scan(file="stdin", quiet=TRUE); quantile(a,  prob=c(.25,.5,.95,.99));'
# Results
       25%        50%        95%        99%
  1.567813  15.688110 118.309786 238.888461

Those are very simple operations to perform in R, yet very powerful to find insides and analyze data.

In the example, I use one simple function or R reading from a command line streaming from K8s logs. All of those are trivial commands, but when combined, they become a superpower for those who can leverage these simple steps to come up with solutions. The idea is not to become a data engineer but to have new tools under your belt so you become creative when the opportunities come.

4. Plan projects using up, down the hill analogy

Developing software is many times unpredictable. As much as we try to predict how long it will take to implement something, we often fail because there are always unknowns, things we think we understand, and things we do not account for.

To solve that, I like the approach of “Hill Charts”[5]; the analogy is when you are climbing a hill, you never know how much you will need to walk to go down the other side of the hill. First, you need to hit the top of the hill. Then, you can see your path down and estimate how long it will take to go all the way down. We divide any project into two kinds of tasks. The first one for “discovery” is going up the hill. Then, as you discover new work, you create the tasks down the hill, meaning, the tasks needed to complete the project. Once you hit confidence that you have seen everything for that project you call, you are on the top of the hill, and from there, you should be able to tell the way down more precisely.

I like to use pictures to show this analogy in my presentations and demos, so others can see the picture I am trying to show. It is impressive how easily people catch the analogy.

Using this analogy will give the correct view to management, and you will be able to show more precisely when you think you have hitch confidence that you understand how much more you need to work to deliver something. This will bring confidence from management and other coworkers, and they will trust you more because of that.

5. Learn from incidents

chart “Never let a good crisis go to waste,” Winston Churchill. Neither must an outage go to waste. Every outage brings great opportunities for learning, often in multiple areas.

We project systems to never go down, for when outages happen, it is always disruptive for the users using the application and engineers developing it.

Nevertheless, outages are great for learning but very bad for the organization. I wish you have as few outages as possible. But when they happen, I want/expect to learn the most from them. For that, I created a separate kind of note on my note-taking system called “The outage record.”

The outage record

Every time the system is down, as soon I put it back running, I go back to notes and write what happened. Then, I try to come up with a few causes of the problem and how to prevent it next time.

Here is my checklist you can use to drive your learning too.

  • Timeline: Build a timeline of events, from getting notified until resolution.

  • How was it detected?? Take notes of what triggered the alerts. If no alerts were not trigged, describe why and how you can pick it up earlier.

  • How was I notified? Note how you were added to the call or outage; why did you get invited if you were not on call?

  • Is there a metric that can show precisely when the outage started and was fixed? Look for the best metric to show you when the problem started and when it was fixed. For example, maybe the number of successes/errors of a giving API or the number of messages pending on a given queue. If there is none, this is a problem you should probably follow up on.

  • How could the infra have prevented the outage? Despite being a human error or application crash or how can our infra be changed to avoid this outage in the future? Even if it is not viable, it is worth noting what changes would bring more stability.

  • How could the application have prevented the outage? Now, here is the opposite event if the infra underneath the application is failing, how could the application have survived it?

  • List of relevant prints with noted data: As you progress over the resolution and investigation of the outage, collect raw prints. Once it is fixed, take time to note them, point to the most relevant information, and paste all this information into your outage record.

You should not spend more than 30 minutes on this checklist if you have all the necessary information.

On the other hand, If you don’t understand what happened, use this checklist to guide your learning and spend as much time as needed to figure it out. Note that I use the “Hows” here more than the normal “Whys” we use in the post-mortem. I do that on purpose because I like to drive my learning by solving the problems rather than just understanding “why” and the “whos” behind the problem.

To validate your learning, once you are done taking notes, call a coworker and explain the outage to them; that will help you organize your thoughts better and bring you a second view of the same problems. Not rarely, when talking to someone, I changed drastically my view of what happened and how we could have prevented it.

I keep most of these notes to myself; nevertheless, they help so much when we finally go to post-mortem calls. You will show up as a well-informed person, and that will bring others confidence in your judgment.

Productivity tips

1. Keep a list of problems that need to be solved and don’t have a solution yet

There will always be unsolved problems in the organizations you work for or in your projects. Some of them may be that there is no tech or priority or way to solve them. The idea is to keep a list of problems you would like to solve but do not have a solution yet, ideally a short list.

Every new information you get, a new blog post you read, a new book, a new friend you meet, the new person you hire, test those problems against it, every once in a while, there will be a match, and you will bring progress for some of those problems, even more, unexpected advancement.

For example, in my list of problems for Nun-db, I had one problem: “How to detect that the primary node is not responsive?”. It was an important but not urgent problem. And one day, while talking to a close friend, he gave me an idea he had read in a blog post about CockroachDb and gave a very simple idea on how to implement it without changing how my sync protocol works. It was an informal conversation on a virtual coffee break, and I solved a problem on my list for months.

Create notebooks of how you would approach other running projects in your organization

Every company will have multiple projects running at the same time. You will never have the opportunity to work on all projects you want. Nevertheless, you may be pulled later to help or work on these projects late if they are not going well or if your current project is done.

This secret will help you hit the ground running if/when the time comes.

I keep a notebook for every important project I would like to work on in the near future. If the opportunity arrives, I will be ready to help and have my own ideas to share and maybe hit the ground running.

This will give the other people in your company or team the impression your level of awareness is high. So many leaders from different projects nowadays come to me and ask, “What would you do in this project?”. Because they know I often have things to share. Many times opinions given like that promoted changes in other projects. This works in your favor, and you can increase your influence even when not working directly on that project.

Jason Warner, former GitHub CTO, told in a Podcast he has similar citrate but for companies[7]. He tells there how this habit helped him to get his CTO position a GitHub.

Often if my opinion is not asked or needed, these notebooks go to waste, but they are still useful to me; once the projects are over, I compare what the team did and what I would have done and note if went well and bad, comparing with my notes and analyzing if they would have helped or not.

2. Take personal time on a daily bases

In many of my posts, I mention the importance of taking personal time and taking days off to recharge. This year I realize we need to take time off on a daily bases. One person close to me, an Engineer Manager of a big Fintech in Brazil, has had a serious mental breakdown. We always exchange information about productivity and career. Even though she takes time off with regularity, it does not save her from burnout. We may think pushing one extra hour or sacrificing our health for a while will be worth it. But having a burnout crisis will damage you and your career much more than you can imagine and much more than a few hours off a week.

I was lucky to have had my burnout crisis at the beginning of my career and learned from them. The most impacting one happened while I was writing my final graduation paper, where I pushed so hard to finish the implementation that I ate poorly and slept only a few hours for several weeks. After that crisis, for over a week, I could not even look at my code or text. I risk failing or even losing my passion for keeping doing what I love doing.

After reflecting on the incident with my friend for a long time, I came to realize that taking days off every once in a while is not enough, and what maybe have saved me from burnout all these years is my habit of taking time off every day.

I have lots of activities out of work, for example, going to the gym three times a week, writing this blog, making Youtube videos, running my farm fishing business, reading consistently, and running my own SaaS and Open-source projects. Those are all self-imposed restrictions to get out of work on time and put my mind and body into different activities. Every day, I do something out of work for at least 2 hours, and I restrict work for the time it needs to be restricted. Once I started doing that, my productivity increased drastically even tho I started working fewer hours.

Worth noting that all my other activities outside of work are not time-sensitive, which means I can do them when I have time, and if I need more dedication for something, I can easily make it fit into my agenda. For that, I use the 2 days rule (I am allowed to skip any of that activity once but not twice in a row). This is important because having a hard agenda can increase your chances of burnout. The only hard activity I have in my schedule is to work 8 hours 5 days a week. The others I can move to best fit my needs that week.

Have a daily “Hour of something.”

Having a personal routine helps you achieve goals out of work on a daily bases. I recently introduced two new routines in my day.

  1. One hour of cleaning where every day. For this hour, I will clean or organize something in my house. This one hour helps my digital detox and cleans my mind. I liked the cleaning because it is practical and infinity and it gives me a sense of compliment, as a side effect my house is cleaner and neater.

  2. The next, I am still incorporating, but I call the “hours of reading,” and it is 30 minutes at the moment. After lunch, I take 30 minutes to read a book instead of jumping back to work. This moment is when I calmly sit in the middle of the day and turn off my mind not to think about work; with that, I can keep up with my reading and learn something new.

These two routines grantees me at least 1:30 hours a day of not working and gets my mind and body back to a normal state. I usually do my “cleaning hour” after work, so I use it as the commute back home time. Since I work from home, it takes me 30 seconds to disconnect from work, and I do not want to bring to my personal life any stress I collect over my day of work.

3. Learn to find the diminishing return point of a task or meeting

Diminishing return is a principle used in economics to express the idea that, eventually, increasing the investments into producing a product will not result in better quality [9].

That also applies to meetings, investigations, and even features you are building.

Finding diminishing returns in meetings

Recently I learned how to identify these points in conversations. It is usually when no new information is showing up, or there is no disagreement. A good way to identify diminishing returns in meetings is when people only repeat and agree with each other.

Finding diminishing in debugging

Debugging is a special case because there is no option to stop depending on the case. The tip here is to create branches of investigation. When you notice the branch you are working on is not leading to the correct fix or new information, do the following:

  • Take notes regarding the current branch. Note essential links, a conclusion, and why you are stopping that investigation. This is important because abandoned branches may become the main investigation again with new information.
  • Create a new theory with the new information you have, create a new theory, and start a new branch of investigation.

When performing long debugging investigation, use the end of your working day as the diminishing return. When we feel we are getting close to a solution or finding out a problem, we tend to try to push the last mile and sometimes overwork, afraid we may lose flow of the moment. Don’t do that; use notes to build your “Hemingway bridge” to start the next day and leave on time. The next day you will have a strong chance of finding out the root cause you are after.

Never try to push too hard after long hours of investigation; when tied, you fall into rabbit roles much more often and waste your company’s money and your time. Come back the next day with a fresh mind, and you will be much more productive.

However, don’t give up too quickly. Every complex investigation requires deed research, and if you are discovering new information in a branch of investigation, it is probably worth it to do the next step on it.

4. Organize your work

“The only thing worst than failure is passing by accident.” - Abril Lopez.

When working disorganized, we can succeed; it happens often. But can we repeat the success? It is possible we don’t observe our system, and they still perform well, but can we trust it will improve or even keep performing in the future if we do not observe them? No.

Why do we think we can improve our work if we don’t observe and organize our day-to-day artifacts?

Organizing your work will give make your life easier. But it can be hard, and organizing may take too much time to be worth it. Can one spend two days organizing notes, readme, and documents after finishing a two weeks project? That is not practical.

The book “Everything in Its Place” the concept of Miss-en-place is used in kitchens worldwide. I developed a system for professional kitchens a few years ago, and it is impressive how well organized they are at the end of an insanely busy work shift.

The idea of Mise-en-place is as soon as you use something, you return it to its place, ready to be used again.

In coding, that means once I am done with a task, all my PR notes will be ready to be copied and pasted, and all my open questions will be commented out where they need to be. The risks will be mapped out and noted in the PR and in the code, test, and documentation.

If you keep your environment, notes, and code organized, you will need a little extra time at the end of each task to document and organize them.

I use a few checklists to help me keep organized. I like checklists because I have a terrible memory, and sometimes I will be in a rush when starting or closing a task, and they help me not to forget important steps.

Starting the task checklist

  • Create a note file related to the task
  • Create a breach to the task

End of the working session checklist

  • Commit all changes in code as WIP
  • Take notes of relevant information for tomorrow’s context(The Hemingway bridge)
  • Commit the notes
  • Do you have a broken build? Good!

Fishing code task checklist

  • Re-organize commits in the code/infra repositories (git reset workflow)
  • Close all browser tabs and move URLs you want to remember later to the notes
  • Clean up desktop prints screens
  • Commit notes related to the task

At the end of a task, you will have no browser tabs open, no lost print on your desktop, no fear of missing notes for your next project, and your commits will look like you knew what you were doing all the time during the coding.

5. Use your notes as a personal database of information

If you follow some or all of my tips, you will collect a large number of notes; these notes are not meant to be only collected but rather used when the time comes. I like to use as simple an approach as possible and make my notes as portable as possible. As I wrote in a previous post, I take notes with Vim and version them in a private Git repository. I use AG to search them and have a few tricks to link and tag them as pure markdown text files.

I think my workflow to collect and process notes deserve a separate post, so I will save you from the details, but the core idea here is to search your notes and make them part of your day-to-day information discovery.

6. Have a meeting after the meetings, even if it is with yourself

Separate time to process the information acquired during the meeting

The meetings are not always fun, but you can learn to enjoy them more if you approach them correctly. Firsts, if you agree with what is said in a meeting, rarely will you need t say anything.

On the other hand, it is crucial to speak up if you disagree with something. Disagreement leads to learning and will make you are meeting more fun. This is a tip from the book “Death by Meeting” [8]. This book changed my relationship with meetings forever.

Then after the meeting, take time to understand what happened and capture important notes bout the meetings.

I usually do this with a friend; we immediately jump into a call after a meeting and debate the more controversial ideas discussed. Great learning can come from these debates. I use the following checklist to guide my learning after each meeting, and I try to answer those questions in the after-meeting at least.

For project plan meetings, Checklists

  • What will go wrong with that plan?
  • Are the guestimates realistic?
  • Do they have all the information they need? What information is missing?
  • What would you do differently from the decisions?

This information can now go to your notes for that project, and you can use it later if needed.

Conclusion

The obvious ways to be better at coding are vast on the internet. Yet, how you manage the load of information, you receive as a developer, consistently deliver results, and have a predictable successful outcome in the projects you engage with are not easily findable. With these posts, I want to document what I am doing and change my strategies. Moreover, I have read books from other fields this year and incorporated some tips into my workflow. A few of them resulted in a significant improvement in the quality of my work.

Finally, I advise, to be a better developer; you should document what you doing and experimenting analyse if it is working, change what is not working, and try new things; that is the best way forward.

Please check my posts form 2020 and 2021.

References

  • [1] Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation
  • [2] Building a Second Brain: A Proven Method to Organise Your Digital Life and Unlock Your Creative Potential Kindle Edition
  • [3] https://www.nobelprize.org/prizes/literature/1954/summary/
  • [4] https://www.usenix.org/system/files/conference/osdi14/osdi14-paper-yuan.pdf
  • [5] Hill Charts: see where projects really stand. https://basecamp.com/features/hill-charts
  • [6] Shape Up: Stop Running in Circles and Ship Work that Matters https://basecamp.com/shapeup
  • [7] https://changelog.com/podcast/395
  • [8] Death by Meeting - https://www.amazon.com.br/Death-Meeting-Leadership-Solving-Business/dp/0787968056
  • [9] - https://en.wikipedia.org/wiki/Diminishing_returns
Written on October 15, 2022