Sunday, March 16, 2025

Lean Software Delivery: Empowering the Team

From my experience, a truly empowered software development team is one that has the ability to impact the entire Value Stream from start to finish. This team, starting from an idea or the identification of a problem (even discovering the problem alongside its users), takes responsibility for delivering value to those customers. This value is not limited to creating new features but also includes protecting what has already been built, minimizing the cost of unnecessary developments, and fostering capabilities that help achieve business objectives efficiently and effectively. End-to-end responsibility involves evolving, operating, and continuously maintaining what they have built, taking full ownership of their development.


https://blackswanfarming.com/value-a-framework-for-thinking/

Value streams can be directed both to external customers and to other teams or departments within a company. At Alea Soluciones, my team was responsible for the value stream for the end customer (management/telephony/TV/internet software for telecommunications operators) as well as the value stream for tools that accelerated and assisted another department in charge of network deployments and physical network operations. At The Motion, our value stream was for the end user of our product. And both at Nextail and currently at Clarity AI, my teams (team topologies: platform teams) are responsible for internal Value Streams aimed at accelerating/enabling other teams responsible for Value Streams to our end customers (team topologies: Stream Aligned teams).

Therefore, this empowerment—from idea to delivery and maintenance of value—always takes place within a value stream, whether internal or external. In companies, there is usually a combination of both types of value streams.

As John Cutler aptly describes, these are the so-called Product Teams.


https://amplitude.com/blog/journey-to-product-teams-infographic


Product Engineers / Impact-Oriented Approach

The mindset and culture I have always tried to promote align with what now seems to be in vogue: the "Product Engineers" way of thinking. That is, forming teams that do not merely execute tasks assigned by a manager or the Product area, but instead become true opportunity seekers, problem solvers, and value generators. These teams work by identifying problems—or even discovering which problems need to be solved—then offering the best possible solution, progressively evolving it through user and system feedback. This is always done with the end customer in mind, considering both the short and long term. Focusing solely on the short term can lead to neglecting the ability to continuously deliver value through new evolutions of the delivered software.

To give some practical examples, at Alea Soluciones, the entire team rotated through customer interactions, support roles, and meetings with the CEO and department heads. We all got involved in understanding why we did things, what impact we were aiming for, and with that knowledge, we were able to develop solutions iteratively, adapting them to the desired impact. This allowed us to learn more about our business and continuously provide better solutions.

At Clarity AI, within the Platform teams, we have conducted numerous interviews with internal users, used surveys, collaborated with interested teams on joint developments, and implemented beta tester and champion programs when developing new internal products. We also rotate support responsibilities so that everyone remains connected to customer needs and usage.

How to Foster This Mindset

Ultimately, it’s about shaping the team’s culture—something that sounds easy when put into words but is, in my experience, one of the hardest things to achieve (enough to fill entire books).

As we’ve been exploring in this series of articles, Lean Software Development is geared toward fostering this kind of culture—one that maximizes value (from the customer’s perspective), minimizes waste, and naturally aligns with customer needs.

What has worked for me in the past to help build this type of culture includes:

  • Prioritizing it in hiring, by asking specific questions about product impact and past contributions. I try to assess whether candidates see software as a means to an end or as the end itself.
  • Evaluating user empathy and a focus on quality and testing in the hiring process, as I believe these aspects are closely tied to the mindset of delivering sustainable value.
  • Ensuring a critical mass of team members who already have this mindset so that it can spread. In some cases, this has meant temporarily bringing in experienced individuals or hiring external experts to help establish that foundation.
  • Providing training on vertical slicing, product topics, and Domain-Driven Design (DDD), emphasizing ubiquitous language, domains, etc.
  • Technical coaching, training, and collaborations with professionals who embody this mindset (I’ve been fortunate to do this with Carlos Ble, Modesto San Juan, Alfredo Casado, Xavi Gost, Aitor Sanz, Codium, etc.). I also keep certain companies on my radar—those I know can bring this mindset in case an opportunity for collaboration arises (Codium, 540, Leanmind, Code Sherpas, Codesai, tech93, etc.).
  • And finally, what some consider my superpower: Being an absolute pain in the ass—constantly repeating the same message about user focus, sustainable quality, impact-driven development, and so on. 😆

Empowered Teams, Balance, and Trust

For a team to be truly empowered, it must have the ability to decide what to work on and how to approach it—while always staying aligned with the organization’s needs. This means properly balancing short-, medium-, and long-term priorities, as well as finding the right mix between behavioral changes (new features) and structural changes (design improvements or architectural changes).

If the team lacks this decision-making power and an external entity dictates what they should work on at all times—without real discussion—several common problems tend to arise:
  • An imbalance in priorities, which over time slows the team down.
  • The accumulation of technical debt or a decline in code quality.
  • The addition of new features without the necessary evolution of the system’s architecture.
https://x.com/johncutlefish/status/1622093852969680896

How to Enable Teams to Make These Decisions

In my experience, ensuring that the team can take ownership of these decisions requires:
  • Earning the organization’s trust by working responsibly and staying aligned with business needs.
  • Delivering quickly and in small steps, making it much easier to continuously blend small behavioral changes with structural improvements. This ensures a continuous flow of user value while maintaining the system’s evolution and sustainability.
Following Lean Software Development and Extreme Programming (XP), which naturally guide us toward this way of working—small steps, maximizing value.

Ultimately, Lean Software Development aims to create positive feedback loops, where:
  • Small, incremental impacts build trust within the organization.
  • That trust leads to greater autonomy for the team.
  • Autonomy enables better decision-making, driving continuous improvement (Kaizen).
If the team is not initially truly empowered, it is up to us to analyze the situation and propose or implement small changes to improve it. The most crucial aspect of this process is earning the organization’s trust, as this is what accelerates the shift toward empowerment. After all, no one will grant more autonomy unless the team consistently demonstrates, step by step, that it is responsible and systematically strives to achieve a positive impact.

Just as Lean creates a positive reinforcement loop, where:
  • We gain more autonomy, which allows us to have a greater impact, and
  • That impact generates even more autonomy for the team,
there is also a negative reinforcement loop:
  • If the team fails to deliver frequently or with the necessary quality, the organization trusts it less.
  • That lack of trust reduces the team’s ability to make decisions, limiting its autonomy.
  • In turn, this reduces opportunities to improve delivery frequency and quality, perpetuating the negative cycle.

Empowerment and Architecture


As we’ve discussed, an empowered team is one that has end-to-end responsibility, from idea to production deployment and operation of the solutions they develop. For this to happen effectively, the following conditions must be met:
  • Minimizing (or eliminating) dependencies on other teams. When dependencies do exist, there should be clear interfaces and rules to coordinate work, minimizing bottlenecks.
  • Working in an environment and on a platform that allows the team to autonomously deploy and operate their solutions in production.
Of course, we all know that these conditions are not simply given to us—we must continuously and consciously invest effort in:
  • Eliminating dependencies with other teams and designing our solutions to avoid creating new ones.
  • Continuously improving and strengthening our development, deployment, and operations platform. This can be seen as making our "workplace" habitable, recognizing that without ongoing investment, it will inevitably degrade.

Concrete Practices That Have Worked for Me in Different Teams

  • Maintaining a sustainable pace (Extreme Programming) and allowing time for continuous improvement and experimentation. It’s critical to avoid operating at full capacity all the time, ensuring enough slack to address internal improvements and explore new ideas.
  • Applying "Bounded Contexts" from Domain-Driven Design (DDD) to structure architecture based on business/domain criteria rather than technical components.
  • Avoiding separate QA teams and assigning quality responsibility to the development team itself. While specialized quality profiles may exist, ownership of quality should be shared by the entire team.
  • Embracing the "You build it, You run it" principle, eliminating the need for a separate operations team. This encourages the team to take responsibility not only for building the solution but also for running it in production.
  • Investing in observability and monitoring, both from a product perspective and a technical standpoint, to gain a better understanding of performance and potential issues.
  • Absorbing work from other teams when it helps eliminate dependencies. This should be done strategically, considering knowledge requirements and workload, but in many cases, it’s more efficient to acquire the necessary expertise and automate certain tasks rather than remain dependent on another team.
  • Working in small increments (vertical slicing, deployment pipeline automation/optimization, exhaustive testing, etc.) to enable continuous delivery and reduce risk with each change.

Non-Empowered Teams

In some cases, the biggest obstacle to team empowerment is the organization itself or the company culture. The most common scenarios I’ve encountered include:
  • Division by specialties and functions: When the organization is structured into separate areas such as frontend, backend, operations, QA, etc., making collaboration and team empowerment difficult.
  • Teams as "feature factories": Even when cross-functional teams exist to some extent, they are often treated as mere executors of solutions decided by Product or Business, with no real decision-making autonomy.
  • Cross-functional teams with technical responsibilities: Sometimes, organizations attempt to create cross-functional teams, but their responsibilities are assigned based on technical components rather than business domains. This means that delivering any functionality requires coordination across multiple teams, limiting agility and autonomy.
If these approaches define the status quo in our organization, there’s no alternative: change is necessary. Fortunately, our industry already offers extensive material on team organization, the pros and cons of different structures, the relationship between software architecture and team organization, and team management. Some valuable concepts in this area include Team Topologies, strategic patterns from Domain-Driven Design (DDD), Conway’s Law, Kotter’s change model, Systems Thinking, and socio-technical systems.

From experience, I can tell you that waiting for changes to happen magically (spoiler: they won’t) is a bad strategy. When I’ve seen the need for change, I’ve taken the initiative to drive it myself. You’d be surprised how much can be done without asking for permission.

Examples and Experiences

Alea Soluciones

At Alea Soluciones, we had almost complete autonomy—not only in deciding what to work on but also in how to implement our solutions. We coordinated directly with the CEO and key department heads, and all product and organizational decisions were made by our team. Our starting point was always the company's overall strategy, integrating continuous feedback from both internal and external customers. Additionally, our working methodology was entirely our own, evolving constantly through a process of continuous improvement. We even had the freedom to make hiring decisions, as long as we stayed within the agreed budget.

This autonomy and empowerment were deliberately pursued, and to achieve it, we focused on:
  • Gradually earning the company's trust by delivering high-quality solutions with a significant impact.
  • Taking on work from other departments to eliminate dependencies.
  • Encouraging multidisciplinary skills within the team to avoid silos.


The Motion

At The Motion, while we had a high level of empowerment, initially, the product and design/UX functions were separate and worked several months ahead of the rest of the team. This model, focused mainly on backend-driven video ad generation, worked well at first and didn’t create friction. However, as the product evolved and required configuration and administration interfaces, this gap started to cause problems.

As the organization evolved, we brought in team members with frontend and layout skills who also had a strong sense of product development and visual design. We also added a designer with experience in web layout, which facilitated a gradual design evolution. In most cases, we worked in pairing between the designer and a frontend developer, allowing us to progress in small increments and eliminate the initial delays. This shift gave us greater autonomy and better synchronization between design and development.

Clarity AI

The teams I’ve built at Clarity AI were designed from the start with end-to-end responsibility, allowing me to enjoy the benefits of empowered teams from day one.

When I joined in 2020, there was already a transition underway to create cross-functional teams, although reporting lines were still structured by specialization (frontend, backend, data engineering, and cloud/systems). This shift toward cross-functional teams aligned with my vision, so I joined the tech leadership team to accelerate the transformation using Team Topologies principles. Over the following months, we adjusted reporting structures, redefined guild functions to operate as communities of practice, and adapted the engineering career framework to fit the new structure.

This new way of working enabled us to support rapid growth, creating both stream-aligned cross-functional teams and platform teams.

Today, after much effort, the teams are highly autonomous, with near-complete end-to-end responsibility. In Clarity AI, some teams require specialized knowledge of sustainability, and we’re working on integrating this expertise in the best way possible to further enhance their empowerment.

Additionally, we've embedded key engineering principles that reinforce end-to-end responsibility within teams:
  • "You Build It, You Run It"
  • "Squad Autonomy Over Standardization"
  • "Flow-Driven Product Delivery"

Applying Lean Principles


Empowering teams is not just an effective organizational strategy—it embodies the core of Lean principles. By reducing unnecessary approvals and handoffs, we eliminate waste, allowing the team to focus on what truly matters and accelerate their work without bureaucratic obstacles. This approach reinforces continuous learning, as the team can experiment and adapt quickly, developing a deep and shared understanding of their own processes and outcomes.

At the same time, autonomy enables faster decision-making, removing bottlenecks that typically slow down development and allowing us to deliver value more efficiently. Quality becomes a shared responsibility, embedded within the team, giving them the confidence to uphold high standards without relying on external reviews.

By applying these Lean principles, we create a more efficient, adaptable, and innovative software development environment. This not only speeds up value delivery but also naturally aligns with small, incremental steps, making continuous improvement and technical excellence an inherent part of the team’s daily work.


References and related links

Special Thanks:

This article has been improved with feedback from:

Sunday, March 09, 2025

Lean Software Development: Deliver as Fast as Possible

One of the fundamental principles of Lean Software Development is to deliver value as quickly as possible. However, this does not simply mean increasing the pace of work but rather optimizing the flow of value—delivering frequently, obtaining feedback, and using it to constantly adapt, thereby improving efficiency in value delivery. 

Let's explore how to achieve this by adjusting processes to move efficiently and confidently. 

Speed and Direction: It’s Not Just About Developing Faster

Being more efficient is not about building more (see The Building Fallacy) or always staying busy (resource efficiency, see The Resource Utilization Trap). Speed, in physical terms, has a direction, and moving fast in the wrong direction is the greatest waste we can have (see Eliminating Waste in Development). To move in the right direction, we need: 
  • Continuous Deployment: To obtain frequent feedback.
  • Humility: To accept that we do not always know what the customer needs or what the best technical solution is.
  • Adaptation: Constantly adjusting our technical and product direction based on the feedback we receive.
Developing quickly without acting or deciding based on feedback is like running in circles. We exhaust ourselves but make no real progress. In fact, it’s even worse because we accumulate Basal Cost without any benefit (see The Basal Cost of Software).

How Fast is Fast?

From a practical perspective, moving fast means:
This allows us to deploy multiple times a day. Deploying this frequently requires doing so on demand, safely, and quickly. In an ideal world, these deliveries would be directly to the end customer. However, depending on the context, direct deployment to customers may not always be possible, or it may only be feasible for certain users (e.g., in embedded systems development or operating system components). These cases should be the exception (see Jocelyn Goldfein’s Model).

About 15 years ago, at Alea Soluciones, we deployed to production between three and five times per week, which was reasonable considering we were working with systems installed in our customers' data centers. Later, at companies like The Motion, Nextail, and ClarityAI—cloud-based multi-tenant environments—the teams I worked with achieved multiple deployments per day.

In all these cases, we reached this delivery speed using Trunk-Based Development, TDD, Continuous Integration, and pairing/mob programming, applying practices from eXtreme Programming (XP).

Control and Speed: The Right Balance

As Canadian Formula 1 driver Gilles Villeneuve said: "If everything seems under control, you’re not going fast enough." ;)



Having everything under control may seem ideal, but in reality, it’s a sign that you could be moving faster. How much faster? Until you start noticing some failures. This idea is key when developing software at high speed.

In my experience, when working with TBD, TDD, and Continuous Delivery, confidence in the process grows, and you start accelerating—delivering faster and faster. Inevitably, a mistake will happen. However, by working in small increments, the risk is low, and fixing the issue is usually quick. After correcting the error, it’s common for the team to slightly reduce speed.

This cycle of accelerating, learning, and adjusting is normal and, in my opinion, is a sign of a healthy team that continuously improves while maintaining a high delivery pace.

The Need for Robust Deployment Pipelines

In Lean, the flow of value begins with an idea or experiment we want to implement or validate and ends when we have delivered the increment, obtained feedback, and are ready to evaluate and decide on the next steps.

While Lean Manufacturing promotes reducing variability to standardize and optimize flow, in Lean Product Development or Lean Software Development, not all phases require low variability. For example:
  • At the beginning of the value stream, experimentation and creativity are needed to generate diverse ideas and approaches.
  • At the end of the cycle, we analyze feedback to decide what adjustments to make.
However, in the systematic process of deploying to production, we must minimize variability. This phase should be fast, solid, and reliable—something we can trust completely.

The goal is for deployments to be boring, a routine task that runs on autopilot.

To achieve this, deployment pipelines should have the following characteristics:
  • Fast (<10 minutes) and reliable.
  • Provide a high level of confidence in the solution through good automated tests.
  • No flaky tests—unstable tests should not exist.
This is only possible if we treat deployment pipelines as first-class citizens in our system, developing and maintaining them with the same level of quality as the rest of the system.

Continuous Deployment: The Most Efficient Method

Ideally, the changes we make should be deployed to production individually, one after another. This allows us to obtain feedback quickly and deliver continuous value increments. As mentioned in this article and previous ones, this way of working provides major benefits:
  • We continuously adjust course based on feedback.
  • Mistakes have a low impact since they involve small changes and are easy to roll back.
  • Understanding errors is simpler because the changes causing them are more limited in scope.
However, deploying is not free—it has an associated cost. It requires investment in:
  • Developing automated deployment pipelines.
  • Wait time every time we run the pipeline.
This cost is called the “transaction cost,” and when it is high, it limits how fast we can deliver.

Keeping Transaction Costs Low

Lean Software Development recommends keeping transaction costs as low as possible. To achieve this, it is essential to:
  • Invest in automated deployment pipelines.
  • Use automated tests that allow us to go directly to production if they pass.
This provides the confidence needed to deploy without manual intervention and ensures quality in every production release.

In the teams I have worked with, our default approach is Continuous Deployment. This means that any change committed to the main branch goes directly to production. To achieve this, we separate deployment from release using feature toggles, allowing us to roll out new features in a controlled manner, without making them immediately visible to end users.



Additionally, we have kept our deployment pipeline execution times between 10 and 15 minutes, ensuring that the delivery cycle remains agile and does not disrupt the workflow. If something fails, we typically implement an automatic rollback when post-deployment smoke tests detect an issue. This minimizes impact and ensures we can quickly regain control.



As Jez Humble, Joanne Molesky, and Barry O'Reilly highlight in Lean Enterprise:
"The goal of continuous delivery is to make it safe and economic to work in small batches. This in turn leads to shorter lead times, higher quality, and lower costs."
This approach allows us to confidently make small changes, accelerate delivery times, and reduce risk and error costs.

Conclusions

To deliver value quickly in Lean Software Development, it is crucial to optimize the workflow without compromising quality. Speed does not mean working faster without control but rather continuously adjusting based on feedback, allowing for constant adaptation. Teams following this philosophy achieve continuous and secure deliveries, minimizing risks and maximizing value.

Key Principles:
  • Small, frequent steps: Delivering in small increments reduces risk and makes error correction easier.
  • Low transaction costs: Investing in fast, reliable deployment pipelines maintains speed without affecting quality.
  • Continuous feedback: Rapid delivery enables constant feedback, improving and adapting the product.
  • Confidence in quality: With automated testing and a solid delivery flow, teams can be sure that each iteration releases a robust product.
In summary, this approach not only optimizes value delivery but also allows teams to operate sustainably, with fast adjustments and minimal error impact.

Related Resources

Sunday, March 02, 2025

Good talks/podcasts (March I)

These are the best podcasts/talks I've seen/listened to recently:
  • Acceptance Testing Is the FUTURE of Programming (Dave Farley) [AI, Generative AI, testing] [Duration: 00:16] (⭐⭐⭐⭐⭐) This talk explores a radical idea that acceptance testing, rather than being just a way to verify software, may be the next step in the evolution of how we program computers, using AI to generate code from detailed specifications
  • 5 Things That Waste Time & Money On A Software Project (Dave Farley) [Agile, Teams, testing] [Duration: 00:15] (⭐⭐⭐⭐⭐) This interesting video identifies common pitfalls in software development, such as not building what users want, using big teams, delaying feedback, chasing features over quality, and relying on manual regression testing, and advises optimizing for learning, fast feedback, and automated testing to improve productivity and reduce waste
  • Marty Cagan - Transformed: Moving to the Product Operating Model at just product 2023 (Marty Cagan) [Generative AI, Product Strategy, Product Team] [Duration: 01:05] This presentation explains the product operating model with its three dimensions (how to build, how to solve problems, and how to decide which problems to solve), four competencies, five product concepts, and underlying principles to help companies transform and work like the best product companies
  • Kent Beck on why software development is an exercise in human relationships (Kent Beck, Jack Hannah) [Engineering Culture, Teams, leadership] [Duration: 00:50] (⭐⭐⭐⭐⭐) Kent Beck discusses how software development is fundamentally an exercise in human relationships, and how creating a safe, supportive environment (a "forest") leads to better results than a resource-scarce, high-pressure one (a "desert"). He also touches on remote work, generational teaching, and test-driven development. An interview full of interesting insights.
  • The Software Industry's Evolution, Complex Architecture & Problem-Solving At Scale | Michael Nygard In The Engineering Room Ep. 35 (Michael T. Nygard, Dave Farley) [Architecture, Data Engineering, Platform, Platform engineering] [Duration: 00:44] A discussion between two experts on incremental design and architecture, including data mesh solutions, managing complexity, platform engineering, and the challenges of balancing innovation with stability
  • DuckDB and Python: Ducks and Snakes living together (Alex Monahan) [Data Engineering, Data Science, Python] [Duration: 01:02] This Talk Python episode explores DuckDB, a fast, in-process analytical database, and its cloud companion MotherDuck, highlighting their capabilities and use cases in Python and data science workflows.
Reminder: All of these talks are interesting, even just listening to them.

The talks and podcasts that I have rated as five stars are also available on the following website:
Related: