Common bottlenecks that impact developer productivity

Common bottlenecks that impact developer productivity

So you want to improve developer productivity? This is what really works

Through my work at Gitpod, I’ve engaged with developers from a diverse range of companies and industries. This experience has provided me with a unique perspective into the factors that impact developer’s productivity, both individually or as part of a team. Instead of going through your typical theoretical frameworks to measure productivity like DORA and SPACE instead today, I want to get really practical and go over the most common challenges for developer productivity I encountered and go over actionable ways to overcome them.

We’ll cover everything from improving your own individual developer flow state with time blocking, increasing your developer feedback loops with tools like hot reloading and why it’s important to standardize to reduce cognitive load.

Individual developer's challenges

Productivity

There are productivity challenges that any developer will encounter - even if they are working solo:

1. Interruptions and flow state

Developers often work best when in a 'flow state', delivering quality work quickly. In this state, they're deeply focused and highly productive. But frequent interruptions can break this flow, hurting both quality and quantity of work.

Hot fixes:

  • Edit your status: turn off Slack notifications and add a status indicating you are in flow state. Pro tip: leverage something like Clockwise which can automatically slot focus time in your calendar and automatically mute your Slack notifications and change your Slack status for you.

  • Snooze: turn off all notifications on your Apple devices via the do not disturb feature

  • Leverage social pressure: get a meeting room or jump on a call with one or more trusted colleagues. Set a fixed time for how long you want to concentrate on a specific task, and share the outcomes each of you wants to achieve. Then collectively work on your tasks, and at the end of that time share which outcomes you were able to accomplish. Because you committed to doing something publicly, you are more likely to follow-through and shut down interruptions. And because you are in a shared room or environment, it reduces the tendency to procrastinate

  • Centralize interruptions: find a way to centralize interruptions, such that only one person takes the brunt of interruptions and others are free to focus. For example, if there are constant interruptions to engineers due to customer or product questions, have the on-call person be the first responder to all of these. This way, the load is still shared as the on-call person changes, but everyone else gets more focus time. Practically, this can be done via an “ask team X” Slack workflow that pings the current on-call person from that team.

2. Iteration speed (slow inner loop)

The speed at which a developer can change, build, and test code is crucial for productivity. Quicker builds allow for more changes in a single day. Slow builds aren't just inconvenient—they can greatly impede progress. Consider a scenario where a change-build-test cycle takes 10 minutes, with half that time dedicated to building. If you work undisturbed for 5 hours, you can do 30 cycles a day. Reducing build times by just two minutes saves an hour each day or adds 7 additional cycles. That's 21 hours saved per engineer every month!

(Not so) Hot fixes:

  • More power: opt for larger machines or switch to cloud development environments (CDEs) that offer more resources

  • Hot-reloading: can you use hot-reloading to instantly reflect code changes in a running service or application? This could nearly eliminate build times!

3. Cognitive load

Developers need to keep a mental map of their code's structure, dependencies, bugs, and more. This mental effort can slow progress, especially with complex projects. If a codebase has unclear boundaries, many interacting components, or confusing names, the mental load further increases.

Hot fixes:

  • Standardize the development environment: switching to CDEs can result in a lower cognitive load to manage a complex development environment - because the environment is codified. This means that one person can set this up, and others can “just” use it. In their day to day, they only need to think about code changes, not the environment where these changes are made in. Of course, this will not fix all problems that come with a very complex and interrelated architecture - but it does help reduce some of the cognitive load.

4. Developer environment maintenance

A developer's environment isn't static. Operating systems update, tools evolve and sometimes clash. Maintaining this takes time—time not spent writing code.

(Not so) Hot fixes:

  • Leverage CDEs: Switching to CDEs means that the developer environment is now standardized and is set up to work every time. That means that once set up, developers can focus on writing code, not updating dependencies. Switching between branches or projects is simplified to starting a new workspace, eliminating the need for constant updates to local dependencies and toolchains. Furthermore, updates to dependencies and tools can be managed centrally, ensuring that every new development environment is automatically up-to-date, streamlining the workflow and enhancing overall efficiency.

Team-level challenges

Productivity

When developers collaborate and share work a new set of challenges emerge:

5. Slow feedback loops (slow outer loop)

When more than one developer is involved, collaboration is essential. They co-own the codebase and need feedback. However, slow feedback loops, whether from a sluggish outer loop (i.e. CI/CD) or lengthy PR reviews, can hamper progress and lower spirits.

Hot fixes:

  • Unblock before doing your own work: schedule fixed time every morning for developers to do PR reviews before they start their own work.

6. Environment inconsistencies

When multiple developers are involved, different development environments come into play. These can vary based on machine setup, OS, developer preferences, and update frequency. This can lead to a code change working on one machine but not another— the "it works on my machine" problem. \

Additionally, there are CI and production environments to consider. These can differ greatly, especially when developers use Windows or Mac, and production runs on Linux containers. This mismatch can reduce productivity, as what works in the development environment might break in production.

Hot fixes:

  • Standardize your development environments: by codifying your development environments via a gitpod.yml or devcontianer.json file you can make sure that every developer gets the same environment every time and, when running the environment in a container, “dev” matches “production”. No more “works on my machine” problems.

7. Onboarding onto unfamiliar codebases

A lone developer knows all their code - they wrote it. But in a team or a large company, developers often encounter unfamiliar code. Contributing to an unfamiliar codebase is costly - not just because of the learning curve to understand the code, but also to have the right tools and dependencies set up. An outdated readme.md file usually guides this setup. This initial hurdle of setting up not only hampers productivity, but also discourages developers from contributing to other code bases hurting cross-team collaboration and hampering any inner-source initiative before it takes off.

Hot fixes:

  • Ask each first-time-user to improve the readme.md of the repo: The repo’s readme.md file usually explains how to set up your development environment. Keeping it up to date can be a burden and is often neglected due to other priorities. Make it a thing for developers onboarding onto a repo for the first time to fix any inconsistencies in the readme.md that they find - e.g. with a CTA at the top. Let’s be honest: This is unlikely to do much, but it is better than nothing :)

  • Codify the readme.md by using CDEs: CDEs are effectively a codified version of your readme.md environment setup guide. They describe the expected development environment as code once, and then each instance (or workspace) of that environment will behave exactly the same. Someone unfamiliar with a code base will have the same exact experience as someone that has worked on it for years - all by just pressing a single button. Any changes made to the development environment are automatically picked up by any new instance of it.

8. Costly context switches

Reviewing a PR or “quickly” switching from feature work to fixing a bug means switching context - not just mentally, but also in the development environment. You need to checkout a different code branch, build it, and install dependencies. This can take time, especially with large codebases and varied tool requirements. It's time spent waiting, not coding.

Hot fixes:

  • Find ways to reduce the number of “switches”: if you do PR reviews in the morning only, you might be able to reduce the number of times you switch contexts because you do not need to switch back and forth as often, and can review PRs that require similar environments all at once.

  • (again) Leverage CDEs: with CDEs, you can easily do a PR review without having to make any changes to the environment you are working in. Instead, just spin up an entirely new environment just for that other branch or PR you want to check out, do what you need to do, and then switch back.

Conclusion

The role of the developer, whether working individually or as part of a team, is marked by challenges that extend beyond simply writing effective code. The challenges that arise compound when developers need to collaborate with others. Cloud Development Environments (CDEs), where a developers environment is standardized and readily available in the cloud, are a holistic solution to all of the challenges listed above. CDEs are worth a deeper look if you can identify with the challenges listed - find out more by downloading our white paper.