Blogroll

Good Strategy vs Bad Strategy

In the fast-paced world of software, the strategy can be the difference between success and failure. Yet, bad strategy or a lack of strategy is common. From mistaking goals for a plan to those drowning in slide decks full of vision and mission, without actionable steps, the pitfalls are everywhere. In this fascinating podcast with Lenny, Richard Rumelt highlights these critical errors, providing insight into why many organizations struggle. This summary of their podcast will delve into what are common examples of a bad strategy and provide tips on crafting good strategies.

Introduction to Strategy 

Strategy is a cohesive response designed to address significant challenges. Effective strategy entails addressing identified high-stakes challenges through a coherent mix of policy and action. It starts with a precise diagnosis of the biggest challenge faced, is followed by a guiding policy that outlines solutions, and culminates in coherent actions aimed at overcoming the challenge. So, if this defines a good strategy, one might wonder, what does a bad strategy look like?

Bad Strategy

Richard’s Good Strategy/Bad Strategy book is perhaps better known for its examples of what not to do in strategy than for its good strategic insights. Many readers find these examples strikingly relevant to their own organizational struggles. Below is a list of common strategic missteps highlighted in his work:

  1. Failure to Face the Challenge: Strategies that fail to clearly identify or address the core challenges facing the organization often lead to vague objectives without actionable plans.

  2. Ignoring Obstacles: Strategies that overlook significant barriers or challenges that could derail the plan often lead to unrealistic expectations and strategic failures.

  3. Mistaking Goals for Strategy: Setting high-level goals, such as profit targets or market share increases, without outlining specific actions or policies to achieve these goals, confuses outcomes with strategic plans.

  4. Fluff: Using jargon or buzzwords might sound impressive but often lacks clear, practical implications or actionable content. This fluff tends to obscure the absence of substantive strategy. An extension of this is the misuse of vision and mission statements as substitutes for actual strategic planning, where they are presented as strategy without underpinning actions.

  5. Template-Style Strategy: Adopting generic strategies not tailored to the company’s specific circumstances can lead to misaligned efforts and wasted resources.

  6. No Coherent Action Plan: Strategies that list desired outcomes without linking them to coherent, coordinated actions that can realistically achieve these outcomes.

  7. The Laundry List: Crafting a strategy composed of a long list of unrelated tasks or initiatives, which lacks focus and dilutes resources, thereby making it difficult to achieve significant results in any area.

  8. Neglecting Organizational Dynamics: Crafting strategies that are incompatible with the company's culture or poorly communicated, leading to resistance and misalignment.

  9. Misjudging Resources and Competition: Planning based on unrealistic assumptions about resource availability and underestimating the strength and strategies of competitors.

  10. Short-termism: Focusing solely on short-term gains at the expense of long-term sustainability.


Effective strategy requires a clear understanding of the competitive landscape, internal capabilities, and adaptable objectives that can respond to changing circumstances. So what is a good strategy?

Components of a Good Strategy

Diagnosis. Guiding policy. And coherent actions.


Diagnosis involves understanding the nature of the challenge that needs to be addressed. It's about pinpointing the key issue and deciding what aspects of reality to focus on to develop a strategic response. For example, a company may identify that its primary challenge is declining market share due to intensified competition from tech-savvy newcomers.


The guiding policy is the approach chosen to navigate the challenge identified during the diagnosis. It dictates how the challenge will be managed and establishes a framework for subsequent actions. A firm might decide to differentiate its product line through advanced technology and superior customer service as a policy to regain market share.


Coherent actions are the specific steps taken to implement the guiding policy and directly address the challenge identified in the diagnosis. Actions must be well-coordinated and logically consistent to be effective. An example would be developing a new series of tech-enhanced products, training customer service teams to provide exceptional service, and launching a targeted marketing campaign to highlight the unique features of these products.

The Magnifying Glass Approach

This analogy effectively illustrates the essence of strategy, especially in early startups. Imagine you are trying to light up fire using a magnifying glass. This is similar to bootstrapping a startup with initial customers.


The Magnifying Glass Analogy for Strategy


  1. Power (The Sun):

    • In strategy, the source of power refers to the organization's unique strengths or advantages that can be leveraged to address the challenge. This might be a technological edge, a strong brand reputation, or exclusive access to certain resources. 

  2. Focus (The Magnifying Glass):

    • The magnifying glass symbolizes the guiding policy within a strategy. Just as a magnifying glass focuses sunlight into a concentrated beam, the guiding policy focuses organizational resources and efforts towards a specific path. This focus ensures that all actions are aligned and aimed precisely at the challenge.

  3. Target (The Black Thread Burned):

    • The target in strategy is the challenge or problem identified in the diagnosis. It's the specific issue that the strategy aims to resolve or the opportunity it seeks to exploit. Just as the focused sunlight can ignite a black string faster than a huge wooden log, a well-crafted strategy directs organizational efforts to change or influence the target area effectively.


The magnifying glass analogy powerfully illustrates the critical alignment necessary in planning, emphasizing the need to synchronize power, focus, and target to effectively drive desired changes or outcomes. This analogy is particularly resonant in the context of a startup, where resources (or "power") are often limited. In such environments, directing a team's efforts towards highly specific and impactful activities can significantly amplify the effect of these limited resources, much like focusing sunlight through a magnifying glass to burn a thread rather than attempting to set ablaze a large wooden log. Similarly, in a startup, identifying and engaging the right initial user base and concentrating team efforts effectively can accelerate early growth and set the foundation for future success. 

Distinguishing Goals from Strategy

Goals such as key performance indicators (KPIs), financial targets, or personal ambitions are not strategies because they describe desired outcomes rather than defining the specific means of achieving them. In the interview, Richard provides a personal anecdote to illustrate the difference between ambitions and strategy. He mentions a list of ambitions he had when he was younger, which included desires like wanting to become a top business school professor, drive a Morgan Drophead Plus 4, learn to fly an aircraft, and marry a beautiful woman, among other things. This example highlights that while these are all valid personal ambitions, they do not constitute a strategy because they lack a clear plan for achievement that addresses specific challenges or opportunities.


Here’s why goals alone do not constitute a strategy:

  • Goals do not provide a diagnosis of the underlying issues or challenges that need to be addressed. A strategy begins with a thorough understanding of the problem, which helps in crafting a focused and effective response. Without this, goals can be misaligned with the actual needs or challenges of the organization.

  • Goals often state what an organization hopes to achieve (e.g., "increase revenue by 20%" or "expand market share") but do not specify the actions required to reach these outcomes. Without a clear plan detailing how these objectives will be achieved, goals remain aspirational and directionless.A strategy not only outlines what needs to be achieved but also prioritizes and sequences specific, coherent actions that are required to meet the goals within the context of the guiding policy.

  • A guiding policy provides a coherent approach to overcoming the identified challenges, acting as a bridge between the diagnosis and the actions. Goals without a guiding policy lack a strategic framework to direct decision-making and resource allocation.

  • Goals do not usually consider the constraints or limitations within which an organization operates. Strategies are developed by taking into account both the opportunities and the constraints, ensuring that the plans are realistic and executable.

While goals are necessary for setting direction and measuring performance, strategy is about how to get there.

Identifying and Addressing Key Problems

An effective strategy focuses on problems that are significant to the organization's success and within its capacity to address, rather than focusing on obvious-looking goals. Here what that is composed of.


Important Problems: These are challenges that have significant impact on the organization's performance or strategic direction. They are critical in that solving them would lead to substantial improvements or advantages for the organization. Importance is determined by the potential impact on the organization's objectives, such as improving market position, enhancing operational efficiency, or driving innovation.


Addressable Problems: These are challenges that the organization has the capabilities to solve or at least make significant progress on. Addressability involves having or being able to develop the necessary resources, technologies, and competencies to tackle the problem effectively. Unlike setting goals, which often describe desired end states (like "increase market share by 10%"), focusing on important and addressable problems involves a dynamic process of understanding and acting on core challenges. It's about diagnosing and then strategically responding to these challenges with coherent actions that directly tackle the issues at hand. This approach ensures that strategy is not just about hitting targets or milestones but is fundamentally about changing the conditions or dynamics that limit the organization's success.


Strategy is not about listing everything you want to accomplish; rather, it's about identifying the most pressing challenges that are blocking the path to these ambitions, and then formulating a coherent plan of action to overcome these obstacles. This requires diagnosing the real issues at hand, setting a guiding policy that addresses these issues, and then executing coherent actions that directly tackle the identified problems.


Final Thoughts

Good strategy is not easy, and bad strategy is prevalent. A well-formulated strategy is key for navigating challenges. It requires a clear understanding of the issues at hand, a well-defined guiding policy, and precise actions that are directly linked to overcoming these challenges. Just as the magnifying glass analogy teaches us to focus our power precisely on the target, so must our strategic efforts be sharply focused on the goal. To learn more about avoiding these common pitfalls and crafting effective strategies, explore Richard’s Good Strategy/Bad Strategy book.


Product-Market Fit Framework for B2B Startups

Finding product-market fit (PMF) is arguably the most critical challenge faced by startups. Navigating the path to PMF can often feel like moving through a labyrinth, with each turn posing potential setbacks or breakthroughs. The PMF framework is designed to guide startups through the various stages of validating and scaling their product in the market. It helps founders identify where they are in the product-market fit journey, what their immediate focus should be, and how to recognize if they are on the right track or if adjustments are needed. The PMF framework is divided into four distinct levels, each representing a stage in a startup's lifecycle:


  1. Nascent: Focus on identifying a critical problem and delivering a solution that is deeply satisfying to a small group of customers.

  2. Developing: Transition from initial traction to a scalable business model by increasing the customer base and establishing reliable demand generation processes.

  3. Strong: Scale business operations efficiently while maintaining product quality that meets market demands.

  4. Extreme: Achieve widespread market acceptance, continuously optimize the product offerings, and explore new market opportunities for further expansion.


The table below provides a look at each level, featuring key characteristics such as company and financial metrics, primary focus areas, benchmarks for measuring progress, and danger signals that might indicate potential issues.


Product-Market Fit Framework Summary (click to enlarge)

Product-Market Fit Framework Summary (click to enlarge)


Navigating it means you've successfully developed a product that meets a substantial market demand and is capable of sustaining growth. Achieving PMF is not a one-time activity but an ongoing process that involves three dimensions: Satisfaction, Demand, and Efficiency. These dimensions evolve over the lifetime of a startup, each taking precedence at different stages of the company's growth. 

  • Satisfaction: In the early stages, ensuring customer satisfaction is paramount. Founders must concentrate on solving a critical problem that is important and urgent for a select group of customers. This involves creating a product or service that not only addresses the problem effectively but also delivers a superior experience compared to existing solutions. As startups move to higher levels of PMF, maintaining satisfaction remains crucial but becomes part of a broader strategy that includes scaling and optimizing operations
  • Demand: As a startup transitions from the nascent to the developing stage, the focus shifts towards generating and scaling demand. At this point, the product or service has been validated with an initial customer base, and the challenge becomes attracting a larger audience. This involves fine-tuning marketing strategies, diversifying channels, and increasing market outreach to capture a broader segment of potential customers. Successful demand generation is marked by an increasing customer base and the establishment of repeatable sales processes.
  • Efficiency: In the later stages of PMF, particularly when a startup reaches strong and extreme levels, efficiency becomes a critical focus. At these stages, the startup must optimize its operations to handle the scaling business effectively. This includes streamlining processes, reducing costs, improving operational throughput, and leveraging technology to enhance productivity. Efficiency gains are crucial for sustaining growth at scale, managing large teams, and expanding to new markets without compromising on quality or customer satisfaction.

Focus areas during the stage in a startup's lifecycle (click to enlarge)


The PMF framework is not a roadmap; it's a diagnostic tool that helps founders make strategic decisions and pivot when necessary, ensuring they stay aligned with market needs and business objectives. Through these evolving focus areas, the PMF framework not only helps startups understand what is required at each stage but also prepares them to anticipate changes in focus as they grow.


This amazing framework was thoroughly outlined by Todd Jackson during a session on Lenny's Product Growth Podcast. Impressed by the depth and practicality of the discussion, I felt compelled to distill and document the key points to better understand and apply these principles. For a comprehensive exploration of the PMF Method and to hear from Todd Jackson himself, visit Lenny's Newsletter for the full episode. Todd's expertise and clarity in presenting this framework make it an extremely useful resource for any startup looking to navigate the complex journey to market fit.

Top 20 Must-Read Software Trends Reports for 2023

In the rapidly evolving software industry, keeping up with new trends, tools, and best practices can be time-consuming. With so much information available, where do you start, and what sources can you trust? I've curated a list of reports that I follow to stay informed and ahead of the curve. These provide insights into everything from programming languages to DevOps, cloud strategy, and security. If you're interested in the latest trends and fascinating posts I come across, follow me or check out my latest writing on industry trends over at the Diagrid blog. I share anything I find insightful and worth reading in the world of cloud and distributed systems. 

Here are the top 20 reports for 2023 I came across so far:

ReportPublisher
Programming Community Index for June 2023TIOBE
Programming Language Rankings - January 2023RedMonk
Developer Survey 2023Stack Overflow
DevOps and Cloud Trends Report – July 2023InfoQ
Software Architecture & Design Trends 2023InfoQ
State of the API Report 2023Postman
State of Application Security Report 2023DataDog
Technology Radar Vol 28Thoughtworks
Radar Trends to Watch: June 2023O'Reilly
State of Cloud Strategy Survey 2023HashiCorp
State of Kubernetes Security Report 2023Red Hat
The State of Platform Engineering ReportPuppetLabs
State of Kubernetes 2023Vmware
The State of Edge Functions 2023Deno
State of Data 2023AirByte
State of Data + AI 2023Databricks
The State of Open Source Software 2022Github
State of APIs 2022RapidAPI
CNCF Annual Survey 2022CNCF
State of DevOps Report 2022Google

While these reports offer valuable insights, it's important to keep in mind that they can be opinionated. The key to effectively leveraging these resources lies in cross-verifying trends from multiple sources and using them only as a guide for direction rather than absolute truths.

Are there any reports that should be on this list? Tag me on Twitter and I'll include them, subject to my checks I'm always keen to explore new sources! Found this list helpful? Go ahead, Share it.

Call to action: Are you a Dapr user? Your experience is valuable! Contribute your insights and shape the State of Dapr Report.


Updates:


Life in First Principles

Let's express life through its finite ingredients. There are three resources in life that everything else depends on. Every time you waste any of them, they're gone forever. These are time, energy, and focus.

Time

Time is the one variable that nobody has any control over. There are 24 hours in a day, 365 days in a year. Time offers the same equal consistency to everybody, but at different lengths. We are born, we live, and we die. All you can do is maximise the other variables in the time given to you, in a way meaningful to you.

Energy

Being alive is a prerequisite, but not sufficient to reach happiness. Given a lifetime, to maximise your purpose and happiness, depends on your energy levels. Energy is the ability to do things, physically or mentally. Having a body sufficiently healthy that will enable you to pursue your purpose. For some, this can be a physically strong body, having a good sleep, healthy diet, and regular exercise. For others, it can be sufficient to be able to get up from the bed and hold a pen. And for some even the ability to express your thoughts through a computer device (such as Stephen Hawking). Energy levels vary from person to person, but so are the energy needs. Energy is not a "have or have not" constant like life is, it is rather a variable that tends that changes every moment, and tends to go down with age. Energy is the multiplier that lets you get the best out of the time given to you.

Focus

Being lucky to be alive, and having sufficient energy, gives the optionality to spend your attention in many ways. Focus is about how we use our time and energy in a directed way. It is the ability to concentrate our attention in a direction that makes us happy, or spread and waste in the universe in a way benefiting others or nobody.


Focus is the variable that we have most control over, and the variable that has the biggest power to change our life. Used in a purposeful way, even in short lifespan and limited energy levels, it has led to personal fulfilments, or human achievements that are remembered throughout millennials. Used purposelessly, can lead to wasted long life full of energy, and many regrets in a death bed.

The happiness formula

If time is a yes/no constant, and the energy level is a multiplier for every moment, then focus is the exponent of all. Every moment, we are alive, we have a certain energy level that we can use for something purposeful or waste for nothing. Then we have recharge again. Every moment we have the ability to focus our energy to things that matter to us, or waste it aimlessly. Life happiness is the sum of all moments we had, with sufficient energy to help us focus on things that makes us happy.

The happiness formula
Happiness is the sum of all finite moments where
we focus our energy towards our purpose

Every time we waste these finite resources, they're gone forever. Make sure you are alive first, healthy and energised second, and also focused on what makes you happy. These variables build on top of each other and require a delicate balance. Focus too much on one thing, and you may lose your life in an instant. Ignore your health, and your energy levels will suffer hindering the ability to focus. Do everything right, and still a meteor can hit you and end it all. There is no guarantee, or fairness in any of these, only the awareness of its working. This formula is re presentation of how these finite resources can be transformed into happiness in the equation called life.

How does Knative project compare to Dapr?

How does Knative project compare to Dapr?

Both Dapr and Knative projects help create and run cloud-native applications on Kubernetes, but differ in important aspects. I thought I'd quickly share where these projects overlap and complement each other from a user point of view. If you prefer, you can read this post as a twitter thread too.

Dapr vs Knative

Dapr vs Knative

TLDR:
Knative extends Kubernetes with serverless containers (scaling to and from 0) and helps you connect applications declaratively. Dapr helps developers implement reliable connected distributed applications quickly. 

Community

Knative originated from Google, whereas Dapr from Microsoft. Today both projects are incubating at CNCF. Both projects have growing communities and are within top 20 active CNCF projects (Dapr #10 and Knative #17)

Knative vs Dapr community statistics
Community statistics

See the full CNCF project statistics here.

Primary focus area

➤Knative extends Kubernetes with serverless containers by taking care of runtine networking (sync/async), autoscaling (to/from zero), and app revision tracking.

➤Dapr helps developers create reliable connected distributed applications quickly. It doesn’t manage the lifecycle of the application, instead it runs next to the applications.

Target user

➤Knative serving can be used by Ops to auto-scale and release apps (with traffic splitting). Knative eventing and functions can be used by devs to build, deploy apps, and connect external systems and event-driven containers. 

➤Dapr is toolkit designed primarily for developers. Developers use APIs & SDKs to interact with Dapr and offload responsibilities such as: pub/sub, state access, stateful service invocation, resiliency, etc. There are design time and runtime benefits for architects and operations teams respectively as described here.

Supported platforms

➤Knative runs only on top of Kubernetes and a network layer such as Kourier, Istio, Contour.

➤Dapr can run on Kubernetes, as well as on-premises and edge devices (such as the International Space Station).

For local dev, Knative requires Kubernetes, whereas Dapr can also run on Docker, or as a single binary only.

Deployment model

Both projects have operator, helm chats, CLI that help with installation and operating the control planes on Kubernetes. 

➤On the data plane side, Dapr is a sidecar that gets injected into the application pod. The application interacts with Dapr over well-defined APIs...

➤Knative dictates how the application is defined and run on Kubernetes by creating deployments, pods, configmaps, and networking configurations. It injects a transparent sidecar into every pod to measure network activity. And has an activator to hold off requests while scaling from zero.

Developer experience

➤Knative uses Kubernetes CRDs for defining an app (called Knative Service) composed of container, configuration, revision. It also offers CRDs that can define how events (CloudEvents) flow between these services, subscribe to a broker. And functions-centric CLI.

➤Dapr offers HTTP and gRPC APIs for Service invocation, Pub/Sub, State, Workflows, Bindings, Configuration, Secrets, Distributed lock, called building blocks. Devs use an HTTP/gRPC client, or SDKs for 8+ languages to interact with the above APIs.

Operational experience

➤Knative serving helps Ops with releasing, auto-scaling, configuring services. Knative eventing with abstracting the broker. 

➤Dapr helps Ops with monitoring, securing, and increasing resiliency of services, as well as cloud infrastructure abstraction.

Top features

➤Knative Scale to 0 Autoscaling Traffic splitting App definition Pub/sub Connectors Function CLI

➤Dapr Pub/sub Service-to-service interaction with resiliency, key/value access, Actors, Connectors, Security (mTLS, Auth), Config/Secrets, Workflows, Distributed Lock APIs.

Feature overlap

The primary overlap is around pub/sub capabilities. Both projects offer async interactions between applications by abstracting the broker & using CloudEvents format. Both projects have connectors and ability to subscribe apps to the broker. 

➤Knative defines these w/ CRDs & over HTTP. 

➤Dapr supports HTTP/gRPC, using CRDs and code.

Sweet spot

➤Knative: autoscaling containers (to and from zero).
➤Dapr: event-driven and stateful service interactions.

Upcoming hot feature: 

➤Knative: function development. 
➤Dapr: workflows based orchestration.

Summary

Those are the key differences between Dapr and Knative I'm aware of.  If you know other differences, share those on the twitter thread. We @diagridio are actively working on both projects and exploring how they complement each other and integrate with the greater CNCF ecosystem.

Apache Kafka Landscape

Before joining Diagrid to work on the Dapr project, I was a product manager at Red Hat. At Red Hat, I had the opportunity to with with exceptional teams on projects such as Debezium, Data Virtualization, Apicurio, Apache Camel, and Strimzi, and helped build Red Hat's Managed Kafka Service. Kafka is more than just a fast message broker, it is a comprehensive ecosystem of various complementary management and development tools and managed services. Through my learning, writing, and exploration of the vast Apache Kafka Ecosystem, I compiled a list of over 120 active Kafka projects I encountered. Here is a sneak peek some of these projects, with the full data set available in the provided spreadsheet.

Apache Kafka landscape projects
Apache Kafka landscape projects

The projects are organized into main categories of the Kafka ecosystem, including Kafka distributions, stream processors, client libraries, connectors, schema registry, replicator, rest proxy, and management tools. Each project includes information on its license, programming language, and deployment types. Additionally, statistics such as GitHub stars or downloads are provided too, but it should be noted that these might have become outdated. A simple report generated from the list is available for reference.

Apache Kafka project stats
Apache Kafka project stats

Discovering other active projects within the Apache Kafka ecosystem can be time-consuming. However, the data provided here is available for you to explore and use as you desire, saving you time and effort. If you wish to add any additional projects, tools, or services related to Apache Kafka, use the provided self-service form.

If you found this content useful, share and help spread this list to others in the Kafka universe. I hope to see you at Kafka Summit London this year. If my talk is accepted 🤞, I will be discussing the topic of creating "Polyglot Microservices with Dapr and Kafka" in more detail.

Unbundling: The Natural Evolution of Tech Stacks

As the field of IT continually evolves, there is a constant stream of new software architectures, development techniques, and tools. Some examples of these include microservices, micro frontends, zero trust, service mesh, and data mesh, you mesh it. Despite the apparent diversity of these technologies and approaches, they are all connected by a common trend: the unbundling of technology stacks and teams. This trend involves breaking down systems into smaller, independent components and organizing work into smaller, more focused teams in order to achieve greater flexibility, and modularity.


The unbundling of the tech stack
The unbundling of the tech stack


How come each of these represent unbundling?
  • Microservices emerged as a response to the limitations of monolithic architecture, which can be inflexible and difficult to scale and maintain as an application grows. By breaking a monolithic application into smaller, independent services, it becomes possible to develop, deploy, and scale each part of the application independently, leading to faster development cycles and greater flexibility.
  • Hexagonal architecture was developed to improve the flexibility and maintainability of 3-tier applications by decoupling components and providing standardized interfaces for interacting with them.
  • Domain-driven design (DDD) is a software development approach that can help break down a monolithic application into smaller, loosely-coupled modules that represent different business domains or contexts.
  • Micro frontends architecture is a design approach in which a large, monolithic frontend application is broken down into smaller, independent modules that can be developed and deployed separately. 
  • JAMstack decouples the frontend and backend of an application by separating the HTML, CSS, and JavaScript that make up the user interface from the server-side code and databases that power the application, allowing easier maintenance as changes to one part of the system do not necessarily require changes to the other.
  • A service mesh decouples the networking responsibilities of a distributed application, such as routing, load balancing, and service discovery, from the application itself, allowing developers to focus on building business logic and features without worrying about the underlying network infrastructure.
  • Similar to microservices, data mesh involves decomposing a large, complex system into smaller, independent components. It decomposes data governance and management practices into smaller, independent components that can be implemented and enforced consistently across different data sources and systems.
  • The 2 pizza team model is a strategy for organizing teams and work in organizations that advocates for smaller teams able to respond to changes more quickly, have better communication and collaboration, can make faster decisions and solve problems more efficiently.
The end result of every tech trend is unbundling. Unbundling of technology stacks into independent components and teams into smaller, more focused teams likely to spread into all other areas. After frontend, data, networking, security, what do you think is the next area of unbundling? Join me in working on Dapr and unbundling integration. Also follow me at @bibryam and shout out with any thoughts and comments on the topic of unbundling.

First Steps with Dapr

I recently left Red Hat to join Diagrid and work on the Dapr project. I spoke about Dapr when it was initially announced by Microsoft, but hadn’t looked into it since it joined CNCF. Two years later, during my onboarding into the new role, I spent some time looking into it and here are the steps I took in the journey and my impressions so far.

What is Dapr?

TL;DR: Dapr is a distributed systems toolkit in a box. It addresses the peripheral integration concerns of applications and lets developers focus on the business logic. If you are familiar with Apache Camel, Spring Framework in the Java world, or other distributed systems frameworks, you will find a lot of similarities with Dapr. Here are a few parallels with other frameworks:

  • Similar to Camel, Dapr has connectors (called bindings) that let you connect to various external systems.
  • Similar to HashiCorp Consul, Dapr offers services discovery which can be backed by Consul.
  • Similar to Spring Integration, Spring Cloud, (remember Netflix Hystrix?) and many other frameworks, Dapr has error handling capabilities with retries, timeouts, circuit breakers which are called resiliency policies.
  • Similar to Spring Data KeyValue, Dapr offers Key/Value-based state abstractions.
  • Similar to Kafka, Dapr offers pub/sub-based service interactions.
  • Similar to ActiveMQ clients, Dapr offers DLQs, but these are not specific to a messaging technology, which means they can be used even with things such as AWS SQS or Redis for example.
  • Similar to Spring Cloud Config, Dapr offers configuration and secret management
  • Similar to Zookeeper or Redis clients, Dapr offers distributed locks
  • Similar to a Service Mesh, Dapr offers mTLS and additional security between your application and the sidecar.
  • Similar to Envoy, Dapr offers enhanced observability through automatic metrics, tracing and log collection.
The primary difference between all of these frameworks and Dapr is that the latter offers its capabilities not as a library within your application, but as a sidecar running next to your application. These capabilities are exposed behind well-defined HTTP and gRPC APIs (very creatively called building blocks) where the implementations (called components) can be swapped w/o affecting your application code.


High-level Dapr architecture

You could say, Dapr is a collection of stable APIs exposed through a sidecar and swappable implementations running somewhere else. It is the cloudnative incarnation of integration technologies that makes integration capabilities previously available only in a few languages, available to everybody, and portable everywhere: Kubernetes, on-premise, or literally on the International Space Station (I mean the edge).

Getting started

The project is surprisingly easy to get up and running regardless of your developer background and language of choice. I was able to follow the getting started guides and run various quickstarts in no time on my MacOS. Here are roughly the steps I followed.

Install Dapr CLI

Dapr CLI is the main tool for performing Dapr-related tasks such as running an application with Dapr, seeing the logs, running Dapr dashboard, or deploying all to Kubernetes.

brew install dapr/tap/dapr-cli

With the CLI installed, we have a few different options for installing and running Dapr. I’ll start from the least demanding and flexible option and progress from there.

Option 1: Install Dapr without Docker

This is the lightest but not the most useful way to run Dapr.

dapr init --slim

In this slim mode only daprd and placement binaries are installed on the machine which is sufficient for running Dapr sidecars locally.


Run a Dapr sidecar

The following command will start a Dapr sidecar called no-app listening on HTTP port 3500 and a random gRPC port.


dapr run --app-id no-app --dapr-http-port 3500

Congratulations, you have your first Dapr sidecar running. You can see the sidecar instance through this command:

dapr list

or query its health status:

curl -i http://localhost:3500/v1.0/healthz

Dapr sidecars are supposed to run next to an application and not on their own. Let’s stop this instance and run it with an application.

dapr stop --app-id no-app

Run a simple app with a Dapr sidecar

For this demonstration we will use a simple NodeJS application:

git clone https://github.com/dapr/samples.git

cd samples/hello-dapr-slim

npm install

This is a Hello World the Dapr way and here is the gist of it:

app.post('/neworder', bodyParser.json(), (req, res) => {

const data = req.body.data;

const orderId = data.orderId;

res.status(200).send("Got a new order! Order ID: " + orderId); });


The application has one /neworder endpoint listening on port 3000. We can run this application and the sidecar with the following command:

dapr run --app-id nodeapp --app-port 3000 --dapr-http-port 3500 node app.js

The command starts the NodeJS application on port 3000 and Dapr HTTP endpoint on 3500. Once you see in the logs that the app has started successfully, we can poke it. But rather than hitting the /neworder endpoint directly on port 3000, we will instead interact with the application through the sidecar. We do that using Dapr CLI like this:

dapr invoke --verb POST --app-id nodeapp --method neworder --data '{"data": { "orderId": "41" } }'

And see the response from the app. If you noticed, the CLI only needs the app-id (instead of host and port) to locate where the service is running. The CLI is just a handy way to interact with your service. It that seems like too much magic, we can use bare-bones curl command too:

curl -XPOST -d @sample.json -H "Content-Type:application/json" http://localhost:3500/v1.0/invoke/nodeapp/method/neworder

This command uses the service Dapr’s invocation API to synchronously interact with the application. Here is a visual representation of what just happened:

Invoking an endpoint through Dapr sidecar

Now, with Dapr on the request path, we get the Daprized service invocation benefits such as resiliency policies such as retries, timeouts, circuit breakers, concurrency control; observability enhancements such as: metrics, tracing, logs; security enhancements such as mTLS, allow lists, etc. At this point, you can try out metadata, metrics endpoints, play with the configuration options, or see your single microservice in Dapr dashboard.

dapr dashboard

The slim mode we are running on is good for the Hello World scenario, but not the best setup for local development purposes as it lacks state store, pub/sub, metric server, etc. Let’s stop the nodeapp using the command from earlier (or CTL +C), and remove the slim Dapr binary:

dapr uninstall

One thing to keep in mind is that this command will not remove the default configuration and component specification files usually located in: ~/.dapr folder. We didn’t create any files in the steps so far, but if you follow other tutorials and change those files, they will remain and get applied with every dapr run command in the future (unless overridden). This caused me some confusion, keep it in mind.

Option 2: Install Dapr with Docker

This is the preferred way for running Dapr locally for development purposes but it requires Docker. Let’s set it up:

dapr init

The command will download and run 3 containers

  • Dapr placement container used with actors(I wish this was an optional feature)
  • Zipkin for collecting tracing information from our sidecars
  • And a single node Redis container used for state store, pub/sub, distributed-lock implementations.
You can verify when these containers are running and you are ready to go.
docker ps

Run the Quickstarts

My next step from here was to try out the quickstarts that demonstrate the building blocks for service invocation, pub/sub, state store, bindings, etc. The awesome thing about these quickstarts is that they demonstrate the same example in multiple ways:
  • With Dapr SDK and w/o any dependency to Dapr SDK i.e. using HTTP only.
  • In multiple languages: Java, Javascript, .Net, Go, Python, etc.
You can mix and match different languages and interaction methods (SDK or native) for the same example which demonstrates Dapr’s polyglot nature.

Option 3: Install Dapr on Kubernetes

If you have come this far, you should have a good high-level understanding of what Dapr can do for you. The next step would be to deploy Dapr on Kubernetes where most of the Dapr functionalities are available and closest to a production deployment. For this purpose, I used minikube locally with default settings and no custom tuning.
dapr init --kubernetes --wait

If successful, this command will start the following pods in dapr-system namespace:
  • dapr-operator: manages all components for state store, pub/sub, configuration, etc
  • dapr-sidecar-injector: injects dapr sidecars into annotated deployment pods
  • dapr-placement: required with actors only.
  • dapr-sentry: manages mTLS between services and acts as a certificate authority.
  • dapr-dashboard: a simple webapp to explore what is running within a Dapr cluster
These Pods collectively represent the Dapr control plane.

Injecting a sidecar

From here on, adding a Dapr sidecar to an application (this would be Dapr dataplane) is as easy as adding the following annotations to your Kubernetes Deployments:

 annotations:

   dapr.io/enabled: "true"

   dapr.io/app-id: "nodeapp"

   dapr.io/app-port: "3000"


The dapr-sidecar-injector service watches for new Pods with the dapr.io/enabled annotation and injects a container with the daprd process within the pod. It also adds DAPR_HTTP_PORT and DAPR_GRPC_PORT environment variables to your container so that it can easily communicate with Dapr without hard-coding Dapr port values.

To deploy a complete application on Kubernetes I suggest this step-by-step example. It has a provider and consumer services and it worked the first time for me.

Transparent vs explicit proxy

Notice Dapr sidecar injection is less intrusive than a typical service mesh with a transparent sidecar such as Istio’s Envoy. To inject a transparent proxy, typically the Pods also get injected with an init-container that runs at the start of the Pod and re-configures the Pods networking rules so that all ingress and egress traffic or your application container goes through the sidecar. With Dapr, that is not the case. There is a sidecar injected, but your application is in control of when and how to interact with Dapr over its well-defined explicit (non-transparent) APIs. Transparent service mesh proxies operate at lower network layers typically used by operations teams, whereas Dapr provides application layer primitives needed by developers. If you are interested in this topic, here is a good explanation of the differences and overlaps of Dapr with services meshes.

Summary

And finally, here are some closing thoughts with what I so far liked more and what less from Dapr.

Liked more

  • I love the fact that Dapr is one of the few CNCF projects targeting developers creating applications, and not only operations team who are running these applications. We need more cloudnative tools for implementing applications.
  • I love the non-intrusive nature of Dapr where capabilities are exposed over clear APIs and not through some black magic. I prefer transparent actions for instrumentation, observability, and general application insight, but not for altering application behavior.
  • I loved the polyglot nature of Dapr offering its capabilities to all programming languages and runtimes. This is what attracted me to Kubernetes and cloudnative in the first place.
  • I loved how easy it is to get started with Dapr and the many permutations of each quickstart. There is something for everyone regardless of where you are coming from into Dapr.
  • I’m excited about WASM modules and remote components features coming into Dapr. These will open new surface areas for more contributions and integrations.

Liked less

  • I haven’t used actors before and it feels odd to have a specific programming model included in a generic distributed systems toolkit. Luckily you don’t have to use it if you don’t want to.
  • The documentation is organized, but too sparse into multiple short pages. Learning a topic will require navigating a lot of pages multiple times, and it is still hard to find what you are looking for.
Follow me at @bibryam to join my journey of learning and using Dapr and shout out with any thoughts and comments.

About Me