<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Questionably Functional]]></title><description><![CDATA[We live in a world of questionably functional systems. Let's make them better.]]></description><link>https://www.questionablyfunctional.net</link><image><url>https://substackcdn.com/image/fetch/$s_!wqlQ!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b8fe46c-5f65-475c-82d7-6fe68799e137_512x512.png</url><title>Questionably Functional</title><link>https://www.questionablyfunctional.net</link></image><generator>Substack</generator><lastBuildDate>Fri, 03 Apr 2026 20:15:30 GMT</lastBuildDate><atom:link href="https://www.questionablyfunctional.net/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Matthew Shea]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[questionablyfunctional@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[questionablyfunctional@substack.com]]></itunes:email><itunes:name><![CDATA[Matthew Shea]]></itunes:name></itunes:owner><itunes:author><![CDATA[Matthew Shea]]></itunes:author><googleplay:owner><![CDATA[questionablyfunctional@substack.com]]></googleplay:owner><googleplay:email><![CDATA[questionablyfunctional@substack.com]]></googleplay:email><googleplay:author><![CDATA[Matthew Shea]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Remote Works, Async Doesn't]]></title><description><![CDATA[I essentially grew up on the Internet.]]></description><link>https://www.questionablyfunctional.net/p/remote-works-async-doesnt</link><guid isPermaLink="false">https://www.questionablyfunctional.net/p/remote-works-async-doesnt</guid><dc:creator><![CDATA[Matthew Shea]]></dc:creator><pubDate>Sat, 12 Jul 2025 23:04:40 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/82104470-3e38-4d16-a72e-ab227128fa7b_6000x4000.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I essentially grew up on the Internet. I spent most of my teens playing games online, chatting in forums, or programming, or even all three at once. I hosted my own Mumble server for my friends, spent 8+ hours doing Molten Core every Saturday, and getting banned from Second Life servers because my Linden Scripting Language scripts crashed peoples&#8217; servers. Hopping into a Mumble channel and working on a script with a friend was second nature. Working through World of Warcraft raids one excruciating weekly reset at a time with 40 people of all stripes, from teens to single moms to retirees, was old hat. It turns out that getting 40 people to work together towards a common goal is actually difficult, even when they&#8217;re being paid. But we did it. This was an era of remote &#8220;work&#8221; for me, I just didn&#8217;t know it at the time. </p><p>It turns out that corporate America was trying to do the same thing. Offshoring was in full swing. Companies were hiring on the other side of the world to save some of those almighty dollars, and it didn&#8217;t take long for them to realize that this came with some challenges. It turns out that communicating with people on the other side of the world is hard, even with email and telephone.</p><p>What made the ragtag band of gamers able to organize 40 people over months to finally knock down the final boss of Molten Core, but corporations struggle with even simple development workflows? Was it that the problems were more complex? Maybe, but after 13 years in the industry now, I don&#8217;t think so. Finishing these raids took 20-40 people executing mechanisms perfectly for hours on end, not to mention the time preparing and practicing. Different problems, certainly, but I&#8217;m not sure I&#8217;d buy an argument that they were more or less complex.</p><p>I think the biggest differentiating factor was being present at the same time, focused on the same goal, and communicating in real time.</p><h2>The state of the industry</h2><p>Looking at my time in the industry so far, I&#8217;ve seen this again and again. When I worked in Japan, we had offshore developers and operations staff in India. These were some incredibly talented people, and we still struggled even with that separation. Where we shined was on incident calls, when things were broken and we were all on a WebEx bridge at the same time, working on the same goal, and communicating in real time.</p><p>In 2020, when every office job went remote by force of circumstance, I saw a lot of people struggling, but my team mostly carried on almost as if nothing was happening. We had adapted quickly to the new situation despite hiding in our apartments. We had an existing culture and trust that allowed us to stay engaged and communicate in real time.</p><p>I&#8217;ve also worked on a remote team that is more than just remote, it is asynchronous. People worked when they want. Teams were split across the world. Our cycle time was slow and we had to accommodate this. Sometimes I needed PR reviews from someone when it&#8217;s 3AM their time. Sometimes, people were just not present unannounced or just didn&#8217;t answer messages for days.</p><p>All of this experience has led me to a conclusion that the industry needs to discuss more seriously: <em>Remote work is not the same thing as asynchronous work.</em> These are distinct modes of operating that are being conflated which muddies the discussion we desperately need to have. </p><div class="pullquote"><p><em>Remote work is not the same thing as asynchronous work.</em> </p></div><h2>What is remote and async work?</h2><p>We will define remote work with a fairly simple definition: your team does not work in the same <em>physical space</em>. Employees are free to work from wherever, so long as they have a stable internet connection and are able to complete their work. </p><p>There are a lot of benefits to this. </p><p>Employees can choose where to live based on their needs. They may want to live near family instead of in the city. Maybe they need to be near certain medical specialists. Maybe they just like being able to sit on the beach while writing. They&#8217;re able to setup their work environment to suit them, be that ergonomics or accessibility needs. Remote workers are able to focus more without the distraction of an open office layout. Their commute involves walking to their home office, which is better for both their mental health and the environment.</p><p>The benefits extend to employers as well. You get a larger hiring pool since you can attract candidates with constraints that might otherwise keep them out. Turnover is lower since employees are happier. Perhaps the biggest advantage is facilities cost. No office leases, supplies, printers, chairs, desks, air conditioning, on-tap kombucha, etc. It&#8217;s just cheaper to run a remote business.</p><p>There are, of course, drawbacks as well. Your managers lose the direct visibility of seeing who is in the office and what they&#8217;re doing. Spontaneous collaboration is lower, since you&#8217;re not going to run into people at the water cooler or be able to pop into a conference room. Employees lose social connections, which for many are the only social connections they have. Mentoring and learning by osmosis is more difficult.</p><p>These drawbacks can be addressed, which we&#8217;ll get to later, but for now, let&#8217;s take a look at asynchronous work.</p><p>We&#8217;ll define asynchronous work as not working at the same <em>time</em>. For the sake of drawing this distinction, let&#8217;s imagine an office that is open 24/7 and employees are welcome to come in and work at any time they wish as it fits their schedule. Your night owls show up at 3 in the afternoon and work until midnight. The parents take off to drop the kids off and pick them up from school, then come back to the office after.</p><p>The benefits of this are clear. For employees, it allows work to fit around their schedule, which in modern adult life is often incredibly busy and complex to navigate, even more so if you have children. Employees are able to set aside time for deep work whenever they have it instead of forcing a day of shallow highly interrupted work. For employers, you can access a larger hiring pool, perhaps even global.</p><p>The drawbacks, though, are high. All communication has to be done via writing, recorded videos, or through meetings awkwardly shoved into time overlaps. Immediate feedback loops are completely gone, replaced by long feedback cycles of a day or more. You lose pretty much all capacity for high bandwidth communication and coordination. Brainstorming and collaborative creative work are drawn out for weeks instead of a good afternoon session. Process gets introduced to address this, and overhead increases. </p><p>And this is the crux of the issue. The problems we are seeing in modern remote organizations have very little to do with them being remote. They have to do with them being asynchronous. Asynchronous work has been conflated with remote work.</p><div class="pullquote"><p><strong>The problems we are seeing in modern remote organizations have very little to do with them being remote. They have to do with them being asynchronous.</strong></p></div><p>If your work is the type where you have long feedback cycles anyway, like journalism or other forms or writing, this is probably fine. As much as we try to pretend otherwise, software is a highly collaborative endeavor. It&#8217;s the rare piece of software that can actually be built and fully owned by a single person, and that takes an exceptionally isolated use-case and an exceptionally talented engineer to pull off.</p><p>The drawbacks of asynchronous work are intrinsic and incredibly difficult to mitigate, at least for the time being. To fix these issues, we need to solve for the need to collaborate with others entirely, which we are nowhere near accomplishing. Asynchronous work is simply a nonstarter right now. People need to be working at the same time on the same problem to support the high bandwidth communication needed. Period.</p><p>The drawbacks of remote work, however, are fixable. </p><h2>Addressing the drawbacks of remote work</h2><p>The things we lose from not being in the same physical space can be addressed with tooling, but more importantly culture. We need to bring the spontaneity in and encourage active collaboration. There is a tendency to self-isolate and over-focus on deep work when working remotely and we need to take active steps to counter that.</p><p>In a physical office, I can walk over to someone&#8217;s desk if I need an immediate response from them. On my team, we&#8217;re co-located, so I can just ask them immediately. This needs to be supported and encouraged on a remote team. When someone messages you during working hours, treat it as if they walked up to your desk. You wouldn&#8217;t ignore someone standing next to you for an hour, so why do it when they send you a message? You&#8217;re introducing asynchronous work patterns where they don&#8217;t need to exist. Odds are, your lack of a response is blocking someone else. Conversely, treat sending a message as walking up to their desk. You&#8217;re likely interrupting their deep work, so make sure the interruption is worth it.</p><p>On the topic of deep work, it&#8217;s undeniably critical, but we shouldn&#8217;t pretend like communication, mentorship, and guidance aren&#8217;t their own form of valuable work when done correctly. When you need dedicated time for deep work, schedule it and communicate it in advance so others can plan for your absence. Otherwise, you should accept that a large part of your work is communication. I would even argue that it&#8217;s the most important part, especially as you reach senior and principal levels.</p><p>Another drawback we can address is the real-time collaboration that a simple whiteboard brings. There&#8217;s some real collaborative magic that comes from being in a room with others and a whiteboard. Being able to draw, debate, and redraw strongly supports the rapid iteration loops that are needed. Fortunately, we have plenty of tooling solutions for this as well. Tools like Figma and Miro have become the defacto whiteboarding tools anyway, even when in the same physical space. They take the whiteboard experience and enhance it. Multiple times, I&#8217;ve been in physical meetings now where we are all at the same table, working on the same Figma. The whiteboard on the wall is just decoration.</p><p>The last big drawback is in management. One of the most common concerns I hear from managers about remote work is that they can't tell if people are actually doing work without being able to see them at their desks. Here&#8217;s the thing, though. If you are relying on visually ensuring butts are in seats to manage, you aren&#8217;t really managing at all. Truly great managers do their work by setting objectives, measuring outcomes, and ensuring their teams are able to operate without your constant guidance. They focus on building and maintaining the organizational substrate on which the team operates. The best manager I&#8217;ve ever had was able to disappear for three weeks and the team barely noticed, because he made sure we were self-sufficient and motivated. He didn&#8217;t &#8220;manage&#8221; us so much as keep the road we were traveling on clean. The worst manager I&#8217;ve ever had checked that butts were in seats, and if you were so much as going to the bathroom when he did his check, you&#8217;d get an earful.</p><h2>The future</h2><p>Remote work is here to stay in some capacity. For those of us who strongly believe in it, we need to admit the downsides that come with it and work to fix them. By far, the biggest downside the tendency for remote work to slowly morph into asynchronous work. They are not the same, and we cannot allow the slow feedback loops and destruction of collaboration that asynchronous work brings tarnish remote work as a concept.</p><p>Remote teams should expect members to be at the keys at the same time, most of the time.  Setting core hours where people have to be available is the easiest approach. Obviously, there are exceptions for the basic life stuff like doctor appointments, but in general, we should be working at the same time. We are working together on the same problem, so we need to be working at the same time. This brings back the spontaneity and high bandwidth communication that allows for rapid innovation and progress.</p><p>We cannot allow a culture of asynchronous work to take over and damage the reputation of remote work as a whole. </p><p>More importantly, though, we need to have discussions about remote work that are free of the baggage of asynchronous work. The executives and managers aren&#8217;t wrong about &#8220;remote&#8221; work being slower -  it is - but only because it has come hand-in hand with asynchronous work. Remote work could be a game changer for not just the employee, but employers, and we need to interrogate it as a solution honestly and precisely, which we are currently failing at spectacularly.</p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.questionablyfunctional.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">To receive new posts and support my work, consider becoming a subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Microservices are not Architecture]]></title><description><![CDATA[Uncle Bob posted a bathrobe rant on Xitter today and I really don&#8217;t know what to make of it.]]></description><link>https://www.questionablyfunctional.net/p/microservices-are-not-architecture</link><guid isPermaLink="false">https://www.questionablyfunctional.net/p/microservices-are-not-architecture</guid><dc:creator><![CDATA[Matthew Shea]]></dc:creator><pubDate>Mon, 12 May 2025 21:41:26 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/2cb060e7-5dc1-495a-bee3-816c2b45836e_4215x2811.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Uncle Bob posted <a href="https://x.com/unclebobmartin/status/1921895270322786438">a bathrobe rant on Xitter</a> today and I really don&#8217;t know what to make of it. For those uninitiated, Uncle Bob Martin is one of the titans of the software industry, having written more software and seminal books than any of us could dream of. I&#8217;ve learned a lot from him though his writing that has made me a better engineer. In the rant, he makes the argument that microservices are not architecture. It&#8217;s an argument he&#8217;s made before in <em>Clean Architecture,</em> but here he does it with the clarity and flavor of spoiled milk. That said, I think he&#8217;s right. So, in a bout of personal arrogance, I&#8217;m going to try to make his case for him.</p><p>Before we start, let&#8217;s get a shared understanding of what a microservice is, though. We&#8217;ll define a microservice as a small independently-deployable unit of software. The exact implementation doesn&#8217;t really matter at all. The exact scale of &#8220;small&#8221; varies. I&#8217;ve seen some &#8220;microservices&#8221; that are a single AWS Lambda function and I&#8217;ve seen some &#8220;microservices&#8221; with half-a-million lines of code. This ambiguity in size is the first part of his argument. <em>They&#8217;re not &#8220;microservices&#8221; they are just &#8220;services&#8221;</em> and they come in a variety of sizes. There&#8217;s nothing about the definition that makes them &#8220;micro&#8221; just they are independently deployable.</p><p>We&#8217;ve been taught that microservices are where your architecture lives. When we draw out architecture diagrams on the whiteboard, our boxes are microservices with cute names like <a href="https://www.youtube.com/watch?v=y8OnoxKotPQ&amp;pp=ygUUbWljcm9zZXJ2aWNlcyBrcmF6YW0%3D">Galactus</a>. This is <em>deeply</em> ingrained in the industry at this point and we&#8217;ve forgotten what software architecture actually is. Your architecture lies not in the microservices, but in the seams you define in your software. </p><p>Seams are the places where different pieces of software are joined together - clear integration points with defined contracts and behavior expectations. This concept goes by a few other names like &#8220;interfaces&#8221; and &#8220;ports&#8221; but they are all the same thing. Well-defined seams must be severable - I can take the software on each side of the seam and utilize it independently. Notice that we are still really abstract here. We&#8217;ve not talked about services, deployments, processes, or anything else. Just the abstract concept of a boundary between units of software.</p><p>Monolithic software has seams, operating systems have seams, embedded software has seams. A great example is in file systems. Linux can run on a variety of file systems because they all implement the same interface to the kernel (VFS). Do you need a basic fast file system? EXT4. Do you need high data integrity? ZFS. The seam allows you to choose the right tool for the job. As long as you abide by the behavior contract in the seam.</p><div class="pullquote"><p>The abstractions you use as seams are your software architecture.</p></div><p>Well-defined seams offer you a really neat opportunity: you can split along them in a variety of ways that each confer different advantages and introduce different downsides.</p><p>You could simply split the seam as code packages. Create a different maven or npm module to keep the code isolated to prevent anyone from breaking the abstraction. The code still compiles into the same binary, but you get some measure of isolation without sacrificing performance.</p><p>You could split as individual processes on the same host using inter-process communication protocols. This allows you to have different modules in different runtimes or languages, with different OS-level configurations.</p><p>You could split as individual containers composed together as a single unit, using REST APIs to communicate between containers, commonly called sidecars. This enables each piece of the software to run independently to take advantage of differing container needs.</p><p>You could split as completely different services behind distinct load balancers, using REST APIs to communicate. This allows for independent scaling of each component, but incurs overhead in network transit time and request serialization/deserialization.</p><p>Regardless of how you split it, the seam is there. The contract is maintained.</p><p>A &#8220;microservice&#8221; is really just the last one. You&#8217;ve decided to split a seam using the highest level of separation you could: completely different services. This comes at a cost, but confers advantages. </p><p>In a high scale system, being able to independently scale different pieces of your software up or down is invaluable. Load is often inconsistent and unpredictable. Some pieces may be more popular in the morning, but less popular in the evening and vise-versa. It allows very clear boundaries on fault containers - you don&#8217;t have to worry about a botched process deployment killing a different process. You get memory and compute isolation - no more greedy processes taking all the host&#8217;s memory and CPU time.</p><p>But network traversal takes time, as does serializing your requests to and from JSON, as does the load balancer. It&#8217;s not a <em>huge</em> amount of time nowadays, but it&#8217;s still time. It also makes the seam behavior harder to enforce since there is no compile-time testing that the contract is being followed correctly. You have to deploy and pray or write massive suites of &#8220;contract tests&#8221; that assert the behavior at deploy-time. I&#8217;ve worked on teams with literally <em>thousands</em> of deploy-time tests to assert the behavior of a single microservice.</p><p>Microservices became popular because they solve a lot of the software challenges that come with monolithic single or multi-process software, but they do so at the cost of latency and contract enforcement. They have their place still, but they are not the one solution to rule them all. They are a tool by which you can split seams, but they are not your architecture. Your architecture is the seams.</p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.questionablyfunctional.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Questionably Functional is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[The Hidden Debt of Partial Understanding]]></title><description><![CDATA[Stop sacrificing long-term value for the illusion of efficiency]]></description><link>https://www.questionablyfunctional.net/p/the-hidden-debt-of-partial-understanding</link><guid isPermaLink="false">https://www.questionablyfunctional.net/p/the-hidden-debt-of-partial-understanding</guid><dc:creator><![CDATA[Matthew Shea]]></dc:creator><pubDate>Wed, 29 Jan 2025 21:51:46 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/1a75bb3a-b4f8-4c0c-a241-cb7a0a516085_5652x3768.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Stop Pretending to Read Documents</h2><p>We've all been in that meeting. Someone sends out a lengthy technical document or proposal beforehand. The meeting starts, and everyone nods along, occasionally offering vague comments that could apply to almost any document. "Interesting approach" or "I have some concerns about scale." Eventually, someone admits they "only had time to skim it," and like dominoes, others follow with similar confessions.</p><p>This theater of partial reading is toxic to organizations. We're normalizing a culture of incomplete understanding while pretending we're being transparent about it. "I skimmed it" has become an acceptable excuse, as if reading 10% of something gives you 90% of the understanding. It doesn't.</p><h2>The Ownership Problem</h2><p>Reading and understanding a document isn't some checkbox activity - it's a core part of owning a decision or contributing meaningfully to a discussion. When you say "I don't have time to read this properly," what you're really saying is "I don't have time to participate in this decision properly." That's fine, but we need to be honest about it.</p><p>AI summarization tools have made this worse, not better. They've given us a technological fig leaf to hide behind. "Oh, I had GPT summarize it for me" is the new "I skimmed it." Both are ways of pretending to have knowledge we don't actually possess. The AI doesn't understand your organization's context, history, or needs. It's giving you a book report without any of the insight that comes from truly engaging with the material.</p><h2>Time Management is Risk Management</h2><p>"No time to read" really means "no time to make an informed decision." We're sacrificing long-term value for short-term gain. Every time we make a decision based on partial information, we're taking on risk. The problem compounds because we often don't discover these risks until much later, when the context is forgotten and the original decision-makers may have moved on.</p><p>This pattern creates a form of hidden technical and organizational debt. Much like poor code documentation or insufficient testing, partial understanding creates gaps that someone will eventually have to pay for. The cost might come in the form of rework, missed requirements, or decisions that have to be revisited and reversed.</p><p>What makes this particularly insidious is that we rarely track or measure these costs. When issues surface months or years later, we treat them as new problems rather than connecting them back to their root cause: decisions made without full understanding of the available information.</p><h2>Proper Delegation</h2><p>There is a solution, but it requires us to be honest with ourselves and our organizations. If you don't have time to fully read and understand a document, you need to fully delegate it to someone who does. Not "skim it and give me the highlights" delegation, but real delegation with authority and ownership.</p><p>This means finding someone who:</p><p>Has the technical background to understand the content</p><p>Has the context to know what matters to your organization</p><p>Has the time to actually do the reading</p><p>Has your trust to make or recommend decisions</p><p>Most importantly, you need to actually listen to them. If you've delegated the deep understanding to them, you need to respect that understanding. Otherwise, you're just creating extra steps in the "pretending to read" theater.</p><h2>Changing the Culture</h2><p>This requires a cultural shift away from the idea that everyone needs to know everything about everything. We need to normalize saying "This isn't my area of expertise, and I don't have time to develop that expertise right now. I'm delegating this fully to Alice, and I'll trust her judgment."</p><p>This isn't a weakness - it's good organizational hygiene. It creates clear ownership, clear accountability, and better decisions. It also makes space for people to develop real expertise instead of spreading themselves thin trying to maintain surface-level knowledge of everything.</p><p>The next time you're tempted to skim a complex document or run it through ChatGPT, stop and ask yourself: Should I take the time to really understand this, or should I delegate it to someone who can? There's no wrong answer, but pretending to understand is always the wrong approach.</p><p>Your organization's decisions are only as good as the understanding behind them. Stop pretending to read documents. Either read them properly or delegate them properly. Anything else is just organizational theater, and the cost of admission is far higher than you think.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.questionablyfunctional.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Questionably Functional is a reader-supported publication. To receive new posts and support my work, consider becoming a subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Building Software for The Infinite Game]]></title><description><![CDATA[The Infinite Game]]></description><link>https://www.questionablyfunctional.net/p/building-software-for-the-infinite</link><guid isPermaLink="false">https://www.questionablyfunctional.net/p/building-software-for-the-infinite</guid><dc:creator><![CDATA[Matthew Shea]]></dc:creator><pubDate>Tue, 21 Nov 2023 19:00:26 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/cc869fc8-0766-49fb-9972-5e43c5c28e63_5472x3648.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>The Infinite Game</h2><p>Simon Sinek, an author and speaker on business leadership, advocates for playing the infinite game in business. Finite games are played to win. These are things like Chess, Football, Cricket, and so on. Infinite games are played to continue playing. You need to use the right mindset for the right situation, and Sinek argues that Business is an infinite game, not a finite one. After all, what do you &#8220;win&#8221; in business? Where is the &#8220;end&#8221;? It doesn&#8217;t exist. You can only keep playing or not. Sinek is very critical of the finite mindset, and for good reason.</p><p>The technology industry, and American business as a whole, is rife with finite thinking. These companies are concerned about their next investment round or quarterly report. &#8220;Winning&#8221; is having a good investment round or beating your quarterly estimates. It&#8217;s shipping your project and marking it done. This finite mindset has its place in business, but it&#8217;s when things are dire. &#8220;Winning&#8221; is survival. If you&#8217;re a startup trying to get investment, you are laser focused on doing what&#8217;s needed to get that investment. Drive user aquisition and sales, no matter the cost. You are in an existential fight for survival, and thus have a finite goal.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.questionablyfunctional.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Questionably Functional is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>The trap I see businesses and teams fall into quite often is not knowing when they&#8217;ve transitioned from a finite game to an infinite game and thus keep using a finite mindset to play an infinite game. This is the sickness at the heart of American business. We&#8217;re all playing the game like it&#8217;ll have a winner. This infects all levels of business, from CEOs to individual contributors. </p><p>My personal rule of thumb for recognizing when this transition has occurred is reaching profitability. Profitability indicates that you are self-sufficient. You are no longer reliant on investment capital to run the business. Your expenses to keep the business running are less than your income. You&#8217;ve won the fight for survival, now you need to keep playing.</p><h2>Finite Mindset in Software Development</h2><p>The Finite Mindset manifests in software development most commonly by overindexing on delivery versus quality. When you&#8217;re fighting for your life, delivering features is key, since each one could attract or retain customers (and thus investors). This is a process of rapid iteration and experimentation to find the right mix of features that your target customers will pay for. It&#8217;s natural that quality will suffer during this process, because quality isn&#8217;t the point. Who cares if the code is sloppy as long as customers (and thus investors) like it?</p><p>The answer to that question is: the team working on it five years from now. Each sacrifice in quality incurs technical debt and that debt will build up over time. Like financial debt, technical debt can completely cripple you. You may use a credit card to fund your way through an emergency, but eventually the banks will come calling for their payments. Software is much the same, as poor code quality can make the system brittle and difficult to modify. It can introduce weird edge cases and bugs that damage the customer experience. You <em>will</em> pay for those tradeoffs in one way or another. Thinking otherwise is a symptom of the finite mindset. You&#8217;re playing to win, not to keep playing.</p><p>Your customers will also notice this finite mindset in the features. You probably have some failed experiments in the product and some awkward or sharp edges in core features. For instance, maybe you don&#8217;t allow customers to rename a resource because you&#8217;re using the display name as the canonical identifier.</p><h2>Making the Transition</h2><p>Playing infinitely means building a sustainable organization system that balances delivery and quality. Once you&#8217;ve identified that you&#8217;re starting to play infinitely (that is, profitable or shortly thereafter), you should do two things: 1) polish core features and 2) pay off some of that technical debt.</p><p>Many companies reward larger features over smaller features, which builds products with many large pieces of functionality that kind-of sort-of work. Google, whose promotion process is contingent on large feature delivery, is infamous for this approach, producing a huge quantity of underwhelming products that no one will buy into and will eventually be deprecated. This only works because <a href="https://www.doofinder.com/en/statistics/google-revenue-breakdown">80.2% of Google&#8217;s revenue is from advertising</a>. Google&#8217;s core feature set as a company is advertising, not Gmail or even Search. Those are just vehicles by which to deliver the core feature. Their core product is extremely polished and effective. This is what you need to do as well. </p><p>Now that you&#8217;ve done that hard iteration process and found a feature set that works for a customer base, identify those core features and polish them to an unnatural shine. Identify any awkward issues that diminish your customers&#8217; experience and fix them. As Ron Swanson puts it, &#8220;Don&#8217;t half-ass two things. Whole-ass one thing.&#8221;</p><p>The approach to clearing technical debt is well-understood, but many businesses hesitate to actually execute on it because of the aforementioned obsession with large feature delivery. The people who know your tech debt best are the engineers who built the software system. Allocate more time for them to work on this and <em>let them decide the priority</em>. You will probably want a high-allocation phase where major issues are fixed, then decrease allocation to a maintenance level.</p><p>By the time this transition is done, you&#8217;ll have a stable software system that delights customers and can continue making money into the immediate future.</p><h2>Building for Infinity</h2><p>Now, the true transition to playing the infinite game happens. At this point, your product teams should start looking at features that build on the core offering and you should be in a fairly stable technical state. The question becomes how to maintain this.</p><p>Many companies and teams will get a set of requirements and ask themselves, &#8220;What is the minimum amount of work needed to achieve these requirements?&#8221; This question sets you up for failure, because you&#8217;re looking for the bare minimum in terms of quality and feature set for every given deliverable. Over time, your product will thus be bare minimums built on top of bare minimums with an endless collection of technical debt and quirky behavior along the way. You are starting with a low bar and raising it just high enough to pass.</p><p>Instead, ask a different question: <strong>&#8220;What is the idealized solution for these requirements?&#8221;</strong> When answering this, dream big. Imagine you had all the money and time behind you to do this. What would you build? What would really <em>delight</em> customers? Go deep on requirements. Build the ideal architecture. Write it all down like you&#8217;re actually going to do it. Explore the edge cases in the features and the software design. Look around as many doors and corners as you can for anything waiting to get you.</p><p>Once that&#8217;s done and you have consensus on the idealized solution, start applying the constraints of reality to it. What features are high-cost and low-value? What features are low-cost and high-value? Where can you draw clean subdivisions of the product for incremental delivery? As you do this process, you&#8217;ll produce a roadmap for the next 1-2 years. You&#8217;ll have a clear vision of what you&#8217;re building and why, but it will be broken down into smaller steps and pieces. You can make conscious choices about the technical debt you&#8217;ll accept instead of letting it happen accidentally. Start with a high bar and gradually lower it until you can jump over it.</p><p>This may sound very waterfall-y and thus scare off any of you who are Agile&#8482;. It&#8217;s not, though. You aren&#8217;t committed to delivering this long-term vision, nor are you planning every little piece of it up front. The vision is just that, a vision. It&#8217;s a guiding light. A direction to unify everyone in the organization. It provides a critical reference point for making decisions.</p><p>If your environment changes or new business needs arise, you can adapt. This approach will leave you with clean places to cut off the product and software architecture. Just do the exercise again for your changed environment and keep going.</p><p>The key benefit of this approach is agency. Rather than let technical debt or shaky product decisions pile up accidentally, you are choosing what sacrifices to make. In a later post, I&#8217;ll go into how to build a decision-making framework that allows you to make such decisions wisely.</p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.questionablyfunctional.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Questionably Functional is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Why Service Teams are the answer to your DevOps woes]]></title><description><![CDATA[Operations is the lifeblood of any software-as-a-service team, yet is frequently treated as a second-rate consideration.]]></description><link>https://www.questionablyfunctional.net/p/why-service-teams-are-the-answer</link><guid isPermaLink="false">https://www.questionablyfunctional.net/p/why-service-teams-are-the-answer</guid><dc:creator><![CDATA[Matthew Shea]]></dc:creator><pubDate>Wed, 11 Oct 2023 19:03:03 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/e03be399-f849-484b-a4c1-1ac3969a434a_6000x4000.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Operations is the lifeblood of any software-as-a-service team, yet is frequently treated as a second-rate consideration. Software developers focus on building features, then punt the work of actually supporting those features to a &#8220;DevOps&#8221; team. This is an antiquated model from the era when software was distributed on floppy disks. Once the disks were produced, the developers were done. It&#8217;s a customer service or ops problem now.</p><p>I use &#8220;DevOps&#8221; in quotes for a reason. Consultants have warped and twisted what was once a simple concept for the purposes of selling naive leaders tools and products. There are as many definitions of &#8220;DevOps&#8221; as there are consultants wanting to sell you something. I won&#8217;t be using this term except to refer to that vague nonsense.</p><p>In the modern world, for the vast majority of cases, software is now a service that requires ongoing development, maintenance, and support. Operating software is no longer a different concern, it&#8217;s part and parcel of the job of developing.</p><h2>Throwing Things Over the Fence</h2><p>Early in my career, I worked on an operations team where developers would throw their code over the fence. Predictably, these systems broke often and we built hours-long manual testing processes after every release to try to catch things. These ran well into the morning hours, with the operations and product team getting to bed around 2 or 3 AM. Even with all that testing, we still had bad code changes make it to production, and the developers would always complain when we had to pull them off of coding work to handle Incidents and fix their shoddy work.</p><p>This attitude was largely based in a feeling of developer supremacy - that developers are &#8220;too good&#8221; to be oncall or be paged. That&#8217;s for someone else, paid less, usually offshore, with a more limited skillset. Operations staff were warm bodies to throw at the soul-sucking task of Operations.</p><p>This was draining in a way I cannot describe in words. We were on the hook for someone else&#8217;s decision making with no real way of influencing those decisions. I&#8217;ve never been so stressed in my life as during those years. Turnover was high, morale was low.</p><p>This model simply does not work. It encourages a lack of ownership over your work, sets the wrong incentive structures, breaks key feedback loops, and grinds your organization to a halt.</p><h2>Service Team</h2><p>There is a better way, which I call the Service Team model. In this model, developers are responsible for designing and developing features, managing infrastructure, maintaining the long-term health of the system, handling customer requests, responding to Incidents, and maintaining a continuous improvement process. The buck stops with the service team. They own the software top-to-bottom, inside-and-out. I&#8217;ve been working under this model for years now with great success. We own everything related to our services. We are responsible for the victories and defeats. These are <strong>service teams</strong>, not development teams or operations teams.</p><p>This model is possible largely because of modern technologies that have lowered the technical breadth required to run a high performance software service, such as public clouds and containerization. No longer do you need an intricate knowledge of servers, load balancers, hypervisors, storage arrays, and networking to run a software service. These are now themselves software services provided by public clouds. Even if you are on-prem, a simple Kubernetes cluster abstracts almost all of this away from your service teams.</p><h2>Feeling The Pain</h2><p>Your development process directly dictates your operations pain. Missing edge cases, poorly-performing code, memory leaks, and insufficient logging and metrics all contribute to operations pain. If you&#8217;re throwing your code over the fence to an operations team, they are on the receiving end of this pain, but they have no tools to influence improvement here.</p><p>Some organizations try to build processes to resolve this gap. I&#8217;ve been in an organization where they tried allocating dev time every sprint for operations work prioritized by the ops team. That work was always the first to be deprioritized once someone demanded a new feature. I&#8217;ve been in an organization where the operations team was just cutting tickets into a blackhole, never seeing the improvements they needed actually get built. In another organization, operations teams were permitted to develop and submit PRs for their own needs, but those PRs often went ignored because they didn&#8217;t contribute towards any development team metrics and took forever because the operations team wasn&#8217;t familiar with the code-base.</p><p>The Service Team model embeds this feedback loop into the team itself. Developers are <em>far</em> more conscientious of their changes when they&#8217;ll be the ones woken up at 2AM when things go wrong and they have poor logging and no metrics to actually diagnose and fix the issue. It&#8217;s in the service team&#8217;s self-interest to address operational concerns as they are shipping code. This effect is so strong that I often see service teams pushing back on management and product teams that are trying to push them to launch without sufficient operational controls in place.</p><h2>A Systems Frame</h2><p>Developers being responsible for code, compute, and other infrastructure forces them to look at their software from a systems frame. They cannot afford to ignore the impact specific load balancer configurations may have on their service. They cannot live in a world of &#8220;worked on my machine.&#8221; They must face the reality that their software is a complex system that they must understand.</p><p>Working in high-scale cloud software, almost every scaling issue I&#8217;ve encountered is due to some odd interplay between system pieces. It&#8217;s very rarely <em>just</em> code or <em>just</em> infrastructure. Building a deep understanding of the whole system, not just the code or infrastructure, is what enabled us to find and fix these issues.</p><h2>Implementation</h2><p>Now that we&#8217;ve established why this model works better, let&#8217;s look at implementation. There are a few key considerations that need to be addressed:</p><ul><li><p>On-Call Rotation</p></li><li><p>Ticketing Process</p></li><li><p>Time Allocation for Ops Work</p></li><li><p>Initial Investments</p></li></ul><h3>On-Call Rotation</h3><p>All members of the service team should be in the on-call rotation, from juniors to seniors. Juniors or new hires who are too inexperienced to be on their own should be shadowing more experienced engineers. A rotation time of one week works very well for this and you should have a minimum of 5 engineers on the rotation to prevent burnout. During the rotation, the on-call is expected to respond to production incidents within a timely manner.</p><p>During this time, the engineer on-call has one priority: resolve Incidents. Everything else is secondary to that task. If they have no Incidents, should be working the operations backlog, not the feature backlog. This strict separation prevents operational issues from impacting feature capacity, leading to a more predictable feature development pace.</p><h3>Ticketing Process</h3><p>I&#8217;ll write a longer post on operations concepts and tickets, but at its core, the team needs a ticketing process that allows for three things:</p><p><em><strong>Requests</strong></em> are customer tickets or tickets from other teams asking for support or some other help.</p><p><em><strong>Incidents</strong></em> track instances service degradations. Outages, performance issues, and so on. An Incident is a single occurrence of this degradation. Incidents have different severities, with some being minor and some needing immediate attention.</p><p><em><strong>Problems</strong></em> track ongoing issues with the service. For instance, a memory leak in the service code that occasionally causes Incidents where hosts run out of memory. Incidents and Problems are linked together to enable tracking the impact of a Problem over time, which aids in prioritization.</p><p>You need some ticketing system that can handle these three types of operational tickets. Ideally, this system should integrate with a paging tool that can contact the on-call automatically if an Incident of sufficient severity is opened.</p><h3>Time Allocation for Ops Work</h3><p>A portion of the regular sprint (or similar) capacity should be dedicated to working a ticket backlog fully owned by the service team. Product managers, team managers, and so on have no power here. The stakeholder is the service team and they get to decide what work needs done in what order. This is where tasks such as logging or metrics improvements, code refactors and cleanup, automated testing, automation work, and so on go. </p><p>Some points of caution:</p><ul><li><p>Do not put feature bug fixes in this backlog. Otherwise, the product teams are incentivized to drive shipping features with bugs and the ops backlog will eventually be inundated with the consequences of that behavior and turn into a bug backlog, choking out actual operational improvements.</p></li><li><p>Do not save up for operations-dedicated sprints. Progress is best made slowly and steadily. Deferring operations capacity for shipping a feature will eventually result in the operations work never being done.</p></li></ul><p>This backlog closes the loop between operational pain and impovement. It dedicates time for the team experiencing the pain to actually address it and generates a flywheel effect driving towards operational stability both for the team and the customer.</p><p>I recommend starting with 33% capacity dedicated to this work. That sounds like a lot, but you probably have more work here than you realize. As you continue this process, your needs may die down and there not be a need for this much capacity. This is a good opportunity for allowing your service team to experiment. They may even decide to pickup a feature with this time, at their discretion. It&#8217;s the service team&#8217;s time to do with what they want.</p><h3>Initial Investments</h3><p>Most organizations without a strong feedback loop are drowning, whether they realize it or not. Your initial goal is get your head above water and then to start swimming.</p><h4>Phase I: Stop Drowning</h4><p>Phase I focuses on two key types of work: improving observability and reducing Incidents.</p><p>By &#8220;observability&#8221; I&#8217;m not talking about the consultant-speak o11y where you have to buy a bunch of expensive tools. I&#8217;m specifically saying &#8220;do you even know what your application is doing?&#8221; The vendor tools have some great features and can definitely be used to great effect, but often times they are haphazardly implemented as an after-thought and end up being enormous piles of noise. If you&#8217;re so early in your operations journey that you don&#8217;t understand how your system works, you can&#8217;t possibly hope to utilize these tools effectively and they are not worth the financial investment, which tends to be substantial.</p><p>Logging and basic metrics can get you most of the way there. You should be able to trace a specific piece of work (request or message) through your system with some kind of unique identifier. Include that identifier in every log message and aggregate your logs in a single place. Congratuations, you now have distributed tracing. You can see what your application is doing. As your team goes through the service to implement logging and metrics, they will need to analyze the application code and infrastructure to understand what&#8217;s <em>actually</em> happening, what logging is useful, and what isn&#8217;t. This exercise is just as important as the logging itself and is the main reason the vendor tools fail. They promise that you don&#8217;t have to do the hard work of understanding, but the understanding is what makes the tooling functional in the first place.</p><p>At the same time, you should be reducing Incidents by driving root cause resolution. If you have a memory leak, you need to ruthlessly pursue it and eliminate it, not just write a script to bounce hosts every so often. Dive into root causes and fix them. The increased understanding granted by the logging and metrics work will help you drive these fixes, reducing the on-call burden and freeing up time for your service team to focus on the work in Phase II, which keeps you from drowning again.</p><h4>Phase II: Start Swimming</h4><p>Now that you&#8217;re not drowning, you need to invest in operational work that improves efficiency and reduces regressions. This is done by investing in Continuous Integration / Continuous Deployment (CI-CD) processes.</p><p>I have a whole post planned on CI-CD, but the short version here is to invest in automated deployment and testing. You should be able to merge a commit and have it in production within a few hours. </p><p>Automated deployment is trivial, especially in a cloud environment. Use Terraform or CDK to manage your infrastructure and code deployment processes and simply trigger them from a CI-CD pipeline tool such as Jenkins or GitLab.</p><p>Almost all testing can be automated nowadays, so there&#8217;s not really a reason to do major releases or gate your deployments based on a QA team. Instead, invest in automated tests using a testing framework of your choice and run those tests against a copy of your production environment. If the tests pass there, you&#8217;ll most likely be good in production.</p><p>Over time, you&#8217;ll find gaps in your CI-CD process that will enter the backlog and you&#8217;ll iteratively improve to the point you have almost no deployment failures or production regressions.</p><h2>Making the Change</h2><p>If you currently have a split development and operations team and want to make this change, there will be friction. Your developers are probably not used to being oncall and your operations team may feel threatened. You&#8217;ll need to address both of these concerns.</p><p>I recommend spreading the operations team across development teams and investing in them as developers. This was my career path and it worked out great for myself and my team. Having someone who had specialized in operations processes embedded in the team will help mentor the developers on good operations practices and enable sharing of their experience. Your operations personnel have valuable knowledge and shouldn&#8217;t be cast aside. Inversely, dedicated operations staff will be a dying breed in the coming years, so giving them the opportunity to learn software development and engineering will provide them with a career path.</p><p>Developers may be more problematic depending on the culture within the team. </p><p>If the developers are already accustomed to being involved in operations issues, you can leverage the rotation as a selling point. On-call rotations give your service team a break and a clear understanding of when they need to be engaged with work. They&#8217;re allowed to properly disconnect when they are not on-call, which goes a long way towards improving mental health and morale.</p><p>If the developers are <em>not</em> accustomed to being involved, you&#8217;re effectively asking them to do more work for the same pay. You can immediately solve this by giving an oncall stipend or some additional pay to account for the increase in responsibility. It&#8217;ll cost more up front, but will payoff in the long-run as the system becomes more stable and the team is able to automate their manual work, improving their efficiency. Ultimately, though, you&#8217;ll need to hire people with expectation that they own their service.</p><div><hr></div><p>Questionably Functional is a reader-supported publication. If you found this article helpful and would like more, please subscribe below.</p><p>Some employers may allow you to expense subscriptions to industry newsletters under their Education or Development budgets. Click <a href="https://www.questionablyfunctional.net/p/expensing-questionably-functional">here</a> for more information.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.questionablyfunctional.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.questionablyfunctional.net/subscribe?"><span>Subscribe now</span></a></p><p>If you have a question or topic that&#8217;s been on your mind, and you&#8217;d like my opinion on it, you can submit a question using the link in the navigation bar. Thank you!</p>]]></content:encoded></item><item><title><![CDATA[So you got your first software engineering job...]]></title><description><![CDATA[You&#8217;ve just graduated college or finished a bootcamp and landed your first job.]]></description><link>https://www.questionablyfunctional.net/p/so-you-got-your-first-software-engineering</link><guid isPermaLink="false">https://www.questionablyfunctional.net/p/so-you-got-your-first-software-engineering</guid><dc:creator><![CDATA[Matthew Shea]]></dc:creator><pubDate>Wed, 04 Oct 2023 19:36:18 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/4c624542-f1c3-4f80-adcd-d4fe43da5e05_6144x4069.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You&#8217;ve just graduated college or finished a bootcamp and landed your first job. You&#8217;re walking into a situation unlike anything you&#8217;ve ever known. How do you succeed?</p><p>Having been a junior myself and now having had several on my teams, I have some suggestions on what skills you can cultivate to help you succeed in your early career.</p><h2>Abandon Your Absolutes</h2><p>There are no absolutes. There is no &#8220;correct&#8221; code style. There is no &#8220;correct&#8221; editor or IDE. There is no &#8220;correct&#8221; language or framework. Reality is messy and everything is a tradeoff. Sometimes you may need to use a language or framework that you don&#8217;t really like because it has the best support internally at your company. Sometimes you need to scope down a project to deliver some pieces faster because customers need it. Sometimes you need to accept inefficiency in your code because your time is more valuable elsewhere.</p><p>This is likely a consequence of both the education system, which encourages thinking about things in terms of &#8220;right&#8221; and &#8220;wrong,&#8221; as well as pop culture around software development. People enter the industry parroting claims they&#8217;ve heard on social media because they don&#8217;t have enough experience or context to understand why opposing viewpoints are valid as well. Professors are notorious for this as well. Many have never written a line of production code in their life and they&#8217;re going to try to tell you what is and isn&#8217;t &#8220;correct.&#8221;</p><p>If you find yourself thinking or speaking in absolutes, stop and think it through. How do you <em>know</em> your claim is &#8220;correct?&#8221; Do you have evidence? As you dig in, you&#8217;ll start to find tradeoffs and nuance that you were previously glossing over. This process is recognizing and challenging your own claims is vital to developing a more nuanced understanding of things.</p><h2>Avoid Seeking Perfection</h2><p>You can spend months optimizing your code performance and design, seeking an ever more-perfect version. This is a trap that will lead you to poor productivity.</p><p>Learning how to see when something is &#8220;good enough&#8221; is a critical skill. Yes, your algorithm may not be fully optimized, but given the traffic needs, compute environment, and cost tradeoffs, is it &#8220;good enough?&#8221; Let&#8217;s say you&#8217;re able to manage a 2% performance improvement in an algorithm by spending two weeks on it. Are you <em>actually</em> going to save enough compute cost for that to be worth the cost of labor and opportunity cost of you working on something else? Often times, getting 80% or 90% of the way there is good enough, and it&#8217;s time to move on.</p><p>This is something I struggled with for years and frankly still do from time to time. I want to build something perfectly and can fall into a hole where I&#8217;m fussing over details that are ultimately unimportant. Recognizing when you&#8217;re doing this and allowing yourself to step away and say &#8220;This is good enough&#8221; will serve you well.</p><h2>Learn to Self-Direct</h2><p>Coming out of college, you&#8217;re probably used to the exact opposite of self-direction. Classes give you an assignment with a clear scope and a clear deadline. You do the work, you turn it in. Rinse and repeat for four years until you get the piece of paper. This situation is incredibly rare in the industry, and you should throw away any expectation of clear requirements and clear deadlines, even as a junior. We as seniors often try to give well-scoped tickets to juniors, but there&#8217;s a tradeoff for us as well. In the time it would take me to write up a precise spec for a junior, I could probably do the work myself. It also doesn&#8217;t push you to learn if you&#8217;re just a Written-Word-To-Code-Translator.</p><p>In reality, you will get vague requirements and vague deadlines. It&#8217;s up to you to figure out exactly how to solve the problem at hand and estimate how long it&#8217;s going to take you. Practice decomposing problems into smaller pieces. I use work breakdown structures for this, where I just create a bullet outline of the work as if I were writing a paper. It helps me identify the big pieces. Dive deep into each of those and work out any edge cases or odd behavior.</p><p>Once you have that done, send it along to someone to sanity check your work. Iterate until you&#8217;ve got it.</p><h2>Recognize the Difference between Experimenting and Grinding</h2><p>You&#8217;re given a task that&#8217;s beyond your current experience. You don&#8217;t already know how to solve it, so you go exploring. Reading documentation, trying different approaches, reading StackOverflow, and so on. You&#8217;ll find a lead and follow it. Maybe it works, maybe it doesn&#8217;t. If not, move to the next lead. This is experimentation and is a critical part of learning. You need to be able to explore an unknown space and try different things on your own as part of being self-directed.</p><p>The fatal mistake is doing this for too long. Once you&#8217;ve exhausted the leads you have  and start trying random things, you&#8217;re no longer experimenting. You&#8217;re grinding. Grinding away at work will lead to burnout very quickly. This is when you should escalate to a more senior engineer for help.</p><p>It&#8217;s a bit of a meme in software that juniors ask senior engineers for help and get one of two answers: &#8220;Why are you bothering me with this?&#8221; or &#8220;Why didn&#8217;t you ask me sooner?&#8221; These answers depend on when you&#8217;re escalating. If you&#8217;ve spent 10 minutes on a problem, give up, and then message me, you&#8217;re likely to get a &#8220;Did you actually do anything?&#8221; kind of answer. If you wait two weeks, grinding away while your soul slowly disintegrates, then ask, you&#8217;re going to get a &#8220;Why didn&#8217;t you ask sooner?&#8221;</p><p>Here&#8217;s the trick to do this correctly:</p><ol><li><p>Read any related documentation or training</p></li><li><p>Look for existing solutions if available by searching repositories, internal or external</p></li><li><p>Walk through the system and understand it. Reverse engineer if needed.</p></li><li><p>Once you&#8217;ve run out of leads, escalate.</p></li></ol><p>I just used this process <em>yesterday</em> when trying to do something kind of unnatural with an internal Amazon library. I read the documents, found nothing. Asked in a couple slack channels and no one had tried this before. Started reverse engineering the library and found a specific Factory class that look encouraging. Worked to see if I could customize the Factory. Found someone else who had done it by searching the code repositories. A couple of hours of experimenting latter, I had a working solution.</p><p>If you&#8217;ve done all that and still run into a dead end, escalate. Use this template:</p><blockquote><p>Hi &lt;Senior Engineer&gt;,</p><p>I&#8217;m trying to solve Task X, but I&#8217;ve hit a dead end. I&#8217;ve tried the following:</p><ul><li><p>A ended up not working because E</p></li><li><p>B was giving me an error F that I couldn&#8217;t root cause</p></li><li><p>C would be unsupported by the library vendor according to the documentation</p></li></ul><p>Can you point me in the right direction?</p></blockquote><p>By demonstrating that you&#8217;ve already done some things and are just at a dead end, you&#8217;re more likely to get helpful answers because we don&#8217;t have to walk you through the basics. We can also take a look at issues E and F to see if we can find a solution.</p><h2>Beware the XY Problem</h2><p><a href="https://xyproblem.info/">XY Problems</a> are the bane of anyone asking for or giving help. XY Problems occur when the asker is trying to solve Problem X, does some exploring, and runs into Problem Y which prevents them from solving X.</p><p>Rather than ask for help about X, they go and ask for help about Y, which may or may not make any sense once given the full context. Instead, always communicate something along these lines:</p><blockquote><p>I&#8217;m trying to solve problem X. I found this documentation which indicates if I do Z, I can solve X. Unfortunately, when I tried Z, I ran into problem Y.</p></blockquote><p>This provides crucial context when asking for help, as your initial jump from X to Y may not make sense in the first place or there may be a better route. Just because you found Z first doesn&#8217;t mean it&#8217;s the <em>right</em> way. Even if I helped you with Y, your final solution Z may have some other issue.</p><h2>Be Honest and Self-Aware</h2><p>If you&#8217;re falling behind on a task, you need to clearly communicate that and why you are falling behind so you can get help. Yes, it can bruise the ego, but getting fired because you can&#8217;t do your work is going to bruise much more, I promise. If you&#8217;re on a supportive team, be honest about what&#8217;s up and what you need help with so we can provide it. Message people directly if you aren&#8217;t comfortable doing it in a daily meeting.</p><p>I&#8217;ve seen so many engineers go radio silent for weeks trying to do a single task. Meanwhile, resentment builds up in the rest of the team. &#8220;What is Joe even doing?&#8221; Then, we just go ask Joe what&#8217;s up, and it turns out he&#8217;s been grinding on something for a week that could&#8217;ve been fixed in a few minutes if he&#8217;d just asked.</p><p>Don&#8217;t be like Joe. Ask for help.</p><h2>Breadth Before Depth</h2><p>At this point of your career, you should be building breadth. If you&#8217;re doing feature work mostly, pickup an infrastructure task. If you&#8217;ve been working on synchronous API code, go work on something asynchronous. Try a new language. Go fix a security issue. Find some automation work that needs done. Shadow an on-call rotation. Pickup a front-end ticket. Write a product spec.</p><p>This approach serves you well in your early career because you probably don&#8217;t know what you actually enjoy. You&#8217;ve done some basic coding in school, but do you have any idea what actually interests you? What gets your brain going? If you&#8217;re stuck doing the same thing for years, you may end up with a specialization that you can&#8217;t stand and ultimately burn out. You may end up lacking skills that make you competitive in the job market and struggle to find work.</p><p>I started out doing infrastructure, automation, and monitoring. I had a broad scope and could pretty much get my hands dirty with whatever I wanted. I learned something important about myself in doing so: I really enjoy being a jack-of-all-trades that can bridge the gaps between specializations and I&#8217;m pretty good at it. I would never have found that out if all I was doing was configuring monitoring tools.</p><h2>Continue Learning</h2><p>It&#8217;s a hard fact that most degree programs don&#8217;t actually prepare you to be a software engineer. You&#8217;re learning the foundations: sorting algorithms, programming paradigms, different languages, data structures, and so on, but no one is teaching you how to breakdown and estimate work, write production-quality code, troubleshoot production issues, or learn how to use common third-party libraries.</p><p>You must continue learning on your own. Read books. Read blogs and newsletters. Ask questions. Your education didn&#8217;t stop once you got the piece of paper to hang on the wall. All that does is prove you know the absolute bare minimum about Computer Science, not that you&#8217;re an engineer.</p><p>Most of my career advancement has come from reading books to get the theory, then using opportunities at work to try those theories out. Some I found to work great, like <em>Clean Architecture</em> and <em>Anti-Patterns</em>. Some I found rather useless, like <em>Test Driven Development</em>. <em>High Conflict</em> taught me how to recognize and interrupt systemic cycles of conflict. <em>Management</em> taught me the principles underlying management as a practice so I could lead my team and interface with my managers more easily.</p><p></p><p>To keep advancing in your craft, you must keep learning, and you generally must do this on your own. There are no more classes with strict curricula to follow. You need to make your own. Be honest with yourself and find the things you aren&#8217;t great at. Take opportunities to fix those, be it a project in that space, reading a book, getting a certification, and so on. Step by step, you&#8217;ll turn yourself into a leader.</p><div><hr></div><p>Questionably Functional is a reader-supported publication, providing a single free article monthly with weekly paid articles. If you found this article helpful and would like more, please subscribe below.</p><p>Some employers may allow you to expense subscriptions to industry newsletters under their Education or Development budgets. Click <a href="https://www.questionablyfunctional.net/p/expensing-questionably-functional">here</a> for more information.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.questionablyfunctional.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.questionablyfunctional.net/subscribe?"><span>Subscribe now</span></a></p><p>If you have a question or topic that&#8217;s been on your mind, and you&#8217;d like my opinion on it, you can submit a question using the link in the navigation bar. Thank you!</p>]]></content:encoded></item><item><title><![CDATA[Domain-Driven Organizations]]></title><description><![CDATA[Weaponize Conway's Law and Domain Modeling to produce a strong socio-technical system fully aligned with your business needs]]></description><link>https://www.questionablyfunctional.net/p/domain-driven-organizations</link><guid isPermaLink="false">https://www.questionablyfunctional.net/p/domain-driven-organizations</guid><dc:creator><![CDATA[Matthew Shea]]></dc:creator><pubDate>Wed, 27 Sep 2023 17:30:12 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/a7693f20-d1ba-4e08-89c2-6c26bbb98d32_4709x3141.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Conway&#8217;s law is a specter in the software engineering world. It&#8217;s always there, influencing your organization and your software, but rarely seen or acknowledged. For those unfamiliar, Conway&#8217;s law is based on the following quotation from Melvin Conway, a pioneer in the field of software development.</p><blockquote><p>Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure.</p><p>&#8212;&#8202;Melvin E. Conway</p></blockquote><p>While not based on any mathematical theory of systems, this Law has proven true in the real world consistently enough that it&#8217;s safe to treat as an axiom of organizations.</p><p>This often manifests negatively, with people bemoaning Conway&#8217;s Law as the driver of their poor software architecture and ownership. It brings with it a rather sobering conclusion: the true software architects in your organization are not the expensive engineers or systems specialists&#8230; they are the HR department and executives. The problem is that they don&#8217;t generally understand that they are doing systems engineering when designing an organization, nor are they typically trained in it.</p><p>Fortunately, there is a simple approach we can implement that will instantly align your organization from top to bottom, enabling you to build a truly agile business. That tool is called domain modeling, as popularized in <em>Domain-Driven Design</em>.</p><p>Using Domain-Driven Design principles allows you to build a Domain-Driven Organization that uses Conway&#8217;s Law to constantly reinforce a strong socio-technical system aligned with your business needs.</p><ul><li><p>Use domain modeling to deeply understand the space in which you operate</p></li><li><p>Using that new understanding, structure your organization along the domains and document the dependencies and communication lines</p></li><li><p>Recurse into each domain and continue modeling</p></li><li><p>Let Conway&#8217;s Law do the work of keeping your business aligned with the model from top to bottom, empowering your teams to have full ownership over their space of the domain model while still driving towards a common purpose</p></li></ul><h2>Domain Modeling</h2><p>For the purposes of this article, we&#8217;re going to use a mock domain model I did recently for a genetics testing service similar to 23andMe. Let&#8217;s look at some of the functions we need:</p><ul><li><p>Sample Collection - Get samples from a customer</p></li><li><p>Sample Processing - Process the physical samples to produce a genome</p></li><li><p>Genome Analysis - Run tests against the genome data, checking for the presence of specific genes</p></li><li><p>Reporting - Collect the results from the analysis and store them</p></li><li><p>Customer Experience - Present the results to the customer</p></li></ul><p>Sample Collection and Sample Processing are deeply intertwined, because the type of sample needed, how they are stored, how they are transported, what equipment is needed to process them, and so on, are all related. We&#8217;ll bundle these into a Sampling domain.</p><p>Genome Analysis is unique enough as a domain. It&#8217;s responsible for taking a specific input, the genome, and producing a specific output, the analysis results.</p><p>Reporting, similarly, is unique. What do we do with those results? How do we analyze them, share them, and do research against them?</p><p>Customer Experience manages the front-end customer experience, from the packaging of the kits to the front-end website.</p><p>Let&#8217;s map these out in a domain model, along with some of the basic entities inside each domain.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RFOP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a53c0f-50d5-4699-9fb4-8e19f0fc8849_4681x3562.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RFOP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a53c0f-50d5-4699-9fb4-8e19f0fc8849_4681x3562.png 424w, https://substackcdn.com/image/fetch/$s_!RFOP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a53c0f-50d5-4699-9fb4-8e19f0fc8849_4681x3562.png 848w, https://substackcdn.com/image/fetch/$s_!RFOP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a53c0f-50d5-4699-9fb4-8e19f0fc8849_4681x3562.png 1272w, https://substackcdn.com/image/fetch/$s_!RFOP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a53c0f-50d5-4699-9fb4-8e19f0fc8849_4681x3562.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RFOP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a53c0f-50d5-4699-9fb4-8e19f0fc8849_4681x3562.png" width="1456" height="1108" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e9a53c0f-50d5-4699-9fb4-8e19f0fc8849_4681x3562.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1108,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1150186,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!RFOP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a53c0f-50d5-4699-9fb4-8e19f0fc8849_4681x3562.png 424w, https://substackcdn.com/image/fetch/$s_!RFOP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a53c0f-50d5-4699-9fb4-8e19f0fc8849_4681x3562.png 848w, https://substackcdn.com/image/fetch/$s_!RFOP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a53c0f-50d5-4699-9fb4-8e19f0fc8849_4681x3562.png 1272w, https://substackcdn.com/image/fetch/$s_!RFOP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9a53c0f-50d5-4699-9fb4-8e19f0fc8849_4681x3562.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The dependencies are as follows:</p><ul><li><p>Customer Experience depends on Sampling for the sample containers and instructions for use.</p></li><li><p>Customer Experience depends on Reporting for the analysis results so they can be presented to the customer.</p></li><li><p>Sample Collection depends on Genome Analysis to specify the genome format, storage location, and upload procedure for the genome data.</p></li><li><p>Genome Analysis depends on Reporting to specify the result format and storage location</p></li></ul><p>That&#8217;s it. For this whole business, we have four dependencies and thus four organizational relationships to be managed.</p><p>Next up, let&#8217;s look at the skill sets we&#8217;ll need in each domain.</p><p>The Customer Experience domain needs designers, both computer interface and packaging designers, logistics specialists, manufacturing experts, and software engineers.</p><p>The Sampling domain needs lab specialists, people who know how to design a testing lab, lab technicians, equipment and facilities managers, sequencer device specialists, and software engineers.</p><p>The Genome Analysis domain needs scientists, bioinformatics engineers, and software engineers.</p><p>The Reporting domain needs researchers and software engineers.</p><p>Notice that, aside from software engineers, almost every domain has unique needs. This is a good sign that we&#8217;ve defined a strong domain model - specialist knowledge is contained within a single domain.</p><h2>The Domain-Driven Organization</h2><p>In order to weaponize Conway&#8217;s law and align our entire organization, we need to align the organization to the domain model. Let&#8217;s hire a Director for each area of the business. We also need to revisit our communication channels and make sure that those are all managed by a single owner. That will typically be a Product Manager for each domain who is responsible for ensuring that these domains all work well together. Aside from these interactions, the organizations can operate largely independently.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hDDz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19bac796-5a24-428d-b42f-9e6049afe907_5124x2525.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hDDz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19bac796-5a24-428d-b42f-9e6049afe907_5124x2525.png 424w, https://substackcdn.com/image/fetch/$s_!hDDz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19bac796-5a24-428d-b42f-9e6049afe907_5124x2525.png 848w, https://substackcdn.com/image/fetch/$s_!hDDz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19bac796-5a24-428d-b42f-9e6049afe907_5124x2525.png 1272w, https://substackcdn.com/image/fetch/$s_!hDDz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19bac796-5a24-428d-b42f-9e6049afe907_5124x2525.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hDDz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19bac796-5a24-428d-b42f-9e6049afe907_5124x2525.png" width="1456" height="717" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/19bac796-5a24-428d-b42f-9e6049afe907_5124x2525.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:717,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:910706,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!hDDz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19bac796-5a24-428d-b42f-9e6049afe907_5124x2525.png 424w, https://substackcdn.com/image/fetch/$s_!hDDz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19bac796-5a24-428d-b42f-9e6049afe907_5124x2525.png 848w, https://substackcdn.com/image/fetch/$s_!hDDz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19bac796-5a24-428d-b42f-9e6049afe907_5124x2525.png 1272w, https://substackcdn.com/image/fetch/$s_!hDDz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19bac796-5a24-428d-b42f-9e6049afe907_5124x2525.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Now we need to break things down further, because you need more than two people for each domain. We&#8217;ll pick the Genome Analysis domain to look at as an example.</p><p>One of my favorite parts of the domain modeling approach is that it&#8217;s recursive. As the Director of Genome Analysis, I need to figure out what my organization structure looks like. Let&#8217;s do a domain model for this specific domain.</p><ul><li><p>Genome Storage - We need to securely ingest, store, and audit access to genome data, including custodianship requirements</p></li><li><p>Bioinformatics - Specialists who understand genome data and can build the analysis jobs</p></li><li><p>Analysis Platform - We need a way to run arbitrary analysis jobs against a genome</p></li></ul><p>Mapping out their interactions, we get the following:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!g-rp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0efa5200-ef5f-4c50-9906-f1164871b980_3453x2005.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!g-rp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0efa5200-ef5f-4c50-9906-f1164871b980_3453x2005.png 424w, https://substackcdn.com/image/fetch/$s_!g-rp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0efa5200-ef5f-4c50-9906-f1164871b980_3453x2005.png 848w, https://substackcdn.com/image/fetch/$s_!g-rp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0efa5200-ef5f-4c50-9906-f1164871b980_3453x2005.png 1272w, https://substackcdn.com/image/fetch/$s_!g-rp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0efa5200-ef5f-4c50-9906-f1164871b980_3453x2005.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!g-rp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0efa5200-ef5f-4c50-9906-f1164871b980_3453x2005.png" width="1456" height="845" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0efa5200-ef5f-4c50-9906-f1164871b980_3453x2005.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:845,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:497413,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!g-rp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0efa5200-ef5f-4c50-9906-f1164871b980_3453x2005.png 424w, https://substackcdn.com/image/fetch/$s_!g-rp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0efa5200-ef5f-4c50-9906-f1164871b980_3453x2005.png 848w, https://substackcdn.com/image/fetch/$s_!g-rp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0efa5200-ef5f-4c50-9906-f1164871b980_3453x2005.png 1272w, https://substackcdn.com/image/fetch/$s_!g-rp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0efa5200-ef5f-4c50-9906-f1164871b980_3453x2005.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>There are two primary interactions:</p><ul><li><p>The Analysis Platform domain needs to provide a common interface for the analysis jobs, as well as define a way to ingest and execute those jobs</p></li><li><p>The Genome Storage domain needs to define how the Analysis Platform can access genome data</p></li></ul><p>We&#8217;ll need Product Managers to manage those dependencies.</p><p>Now let&#8217;s build an organization structure.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VoNa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ade3eb7-4db2-4d60-b6af-13c13f0a7f75_4027x2785.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VoNa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ade3eb7-4db2-4d60-b6af-13c13f0a7f75_4027x2785.png 424w, https://substackcdn.com/image/fetch/$s_!VoNa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ade3eb7-4db2-4d60-b6af-13c13f0a7f75_4027x2785.png 848w, https://substackcdn.com/image/fetch/$s_!VoNa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ade3eb7-4db2-4d60-b6af-13c13f0a7f75_4027x2785.png 1272w, https://substackcdn.com/image/fetch/$s_!VoNa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ade3eb7-4db2-4d60-b6af-13c13f0a7f75_4027x2785.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VoNa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ade3eb7-4db2-4d60-b6af-13c13f0a7f75_4027x2785.png" width="1456" height="1007" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0ade3eb7-4db2-4d60-b6af-13c13f0a7f75_4027x2785.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1007,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:917006,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VoNa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ade3eb7-4db2-4d60-b6af-13c13f0a7f75_4027x2785.png 424w, https://substackcdn.com/image/fetch/$s_!VoNa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ade3eb7-4db2-4d60-b6af-13c13f0a7f75_4027x2785.png 848w, https://substackcdn.com/image/fetch/$s_!VoNa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ade3eb7-4db2-4d60-b6af-13c13f0a7f75_4027x2785.png 1272w, https://substackcdn.com/image/fetch/$s_!VoNa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ade3eb7-4db2-4d60-b6af-13c13f0a7f75_4027x2785.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Those accustomed to traditional organizations will notice something odd here. We have Product Managers and Security Engineers embedded into two of our domains.</p><p><strong>This is intentional.</strong></p><p>It&#8217;s been proven time and time again that building a multi-disciplinary team focused on one common goal drives results because it gives that team <em>complete ownership</em>. That stack of people under the Genome Storage manager is wholly and entirely in control of how genome data is stored, accessed, and audited. They are running their own little business-within-a-business and are empowered to do what&#8217;s necessary to succeed.</p><p><em>This is the end goal of the domain-driven organization. Ownership and empowerment for everyone with a clear scope and vision that aligns with the overall business, held in place with a seemingly inevitable law of organizations.</em></p><h2>Mitigating the Side Effects</h2><p>This model does have some downsides. Namely, your specialist groups of software engineers, product managers, and security engineers are isolated from each other. This could lead to drift or inconsistent standards across the organization, especially as it grows. In other words, how do we ensure that these job functions are staying unified in their approach and standards?</p><p>This is where treating your organization as a system instead of a hierarchy becomes valuable. The diagram above operates on a single vertical axis, enforcing superiority of one individual over another. Let&#8217;s get creative and add a second axis, this time looking at what job specializations there are.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VIFE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9578f72e-13fd-4fab-8dbc-547cb022afbf_4497x3370.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VIFE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9578f72e-13fd-4fab-8dbc-547cb022afbf_4497x3370.png 424w, https://substackcdn.com/image/fetch/$s_!VIFE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9578f72e-13fd-4fab-8dbc-547cb022afbf_4497x3370.png 848w, https://substackcdn.com/image/fetch/$s_!VIFE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9578f72e-13fd-4fab-8dbc-547cb022afbf_4497x3370.png 1272w, https://substackcdn.com/image/fetch/$s_!VIFE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9578f72e-13fd-4fab-8dbc-547cb022afbf_4497x3370.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VIFE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9578f72e-13fd-4fab-8dbc-547cb022afbf_4497x3370.png" width="1456" height="1091" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9578f72e-13fd-4fab-8dbc-547cb022afbf_4497x3370.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1091,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1306405,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VIFE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9578f72e-13fd-4fab-8dbc-547cb022afbf_4497x3370.png 424w, https://substackcdn.com/image/fetch/$s_!VIFE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9578f72e-13fd-4fab-8dbc-547cb022afbf_4497x3370.png 848w, https://substackcdn.com/image/fetch/$s_!VIFE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9578f72e-13fd-4fab-8dbc-547cb022afbf_4497x3370.png 1272w, https://substackcdn.com/image/fetch/$s_!VIFE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9578f72e-13fd-4fab-8dbc-547cb022afbf_4497x3370.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>We&#8217;ve added a second form of organization here, the Guild. While not the only approach to solving this problem, the Guilds serve as job function specific organizations that evolve independently of the business-domain oriented structures. This empowers the Security Guild to decide &#8220;We are going to deprecate TLS 1.2&#8221; and that decision have force across the organization. The Product Management guild may decide they want to track goals using a specific tool. </p><p>While the above chart is just the Genome Analysis domain, it should be understood that these guilds span the entire organization. Guilds are responsible for training and improving their job specialization, while the Managers operate their business function. As the organization grows, it may be wise to hire dedicated heads of these guilds whose entire function is to improve their job specialization across the organization.</p><h2>Managing Growth</h2><p>Eventually, your organization will scale or extend into some new line of business that doesn&#8217;t align with the previous model. Maybe we want to support Ancestry now instead of just simple gene presence checks.</p><p>When situations like this arise, start the process over with the top level domain model. Analyze how the additions impact the existing model and continue down recursively. This can happen at any level of the organization, and the owners of that domain must be empowered to do this analysis and modify their portion of the organization as needed.</p><h2>How to Get There</h2><p>This example is a new organization, but you may already have one in place that needs to be migrated. I&#8217;ve been through this process myself as an engineer who did the domain modeling that led to organizational change.</p><p>The first step is to model what you actually have. Map out your socio-technical system along with its communication lines. It is critical that you involve key people of all specialization at all levels in this exercise. You need depth and breadth here to produce an <strong>accurate</strong> model of where you&#8217;re at currently. You need to be self critical here. You&#8217;re going to find silly things. Write them down in the model and move on.</p><p>The second step is to model where you want to be. It&#8217;s important that this is the second step, as you don&#8217;t want your idealized model to bias your current state model from the first step. </p><p>The third step is to figure out what the <em>minimal</em> set of changes is to get from where you are to where you want to be. Prioritize these changes to target areas that are known problems. Communicate these changes broadly and explain them so that everyone understands what&#8217;s happening and what the goal is.</p><p>Finally, start making changes. Do one change at a time, see how it works, and continue. Do not attempt to reorganize your entire organization at once. This will cause massive amounts of friction and decrease morale and productivity. You may need to hire people or move people around. Do not be rash and layoff entire organizations. Be slow and strategic. You are playing an infinite game, so act like it.</p><p>Over time, you&#8217;ll slowly align with the idealized domain model.</p><h2>Conclusion</h2><p>Domain-Driven Organizations empower small units to fully own their space while still remaining aligned to the overall model of the business. It enables you to think about your organization as a complex system instead of as a hierarchy, allowing you to apply systems design and analysis to it. It produces high quality software and human systems with clear boundaries that align with the business.</p>]]></content:encoded></item><item><title><![CDATA[Your Organization Isn't a Hierarchy]]></title><description><![CDATA[How many natural systems are strict hierarchies?]]></description><link>https://www.questionablyfunctional.net/p/your-organization-isnt-a-hierarchy</link><guid isPermaLink="false">https://www.questionablyfunctional.net/p/your-organization-isnt-a-hierarchy</guid><dc:creator><![CDATA[Matthew Shea]]></dc:creator><pubDate>Wed, 20 Sep 2023 18:30:08 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/6e151428-066d-4f1a-baf8-a9156441bc2e_6060x4040.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>How many natural systems are strict hierarchies? That is, for each node in the system, there is one node that is in some way superior to it, until you ultimately reach a single node at the top which has authority over all other nodes. The only ones that come to mind involve animals. Pack leaders, hive queens, and so on. It makes sense, then, that we naturally organize humans this way as well. Some forms of life have some implicit need to be structured into hierarchies, including us. We structure our organizations this way without really asking why. We use it for everything. It&#8217;s the standard across governments, corporations, non-profits, small businesses, big businesses, educational institutions, and so on. We just cannot escape the hierarchy. </p><p>But why? We&#8217;re humans. Having received the gift of fire from Prometheus, shouldn&#8217;t we be looking for a better way? </p><ul><li><p>Hierarchies enable accountability and are essential for humans to function at scale</p></li><li><p>Organizations are complex systems of interdependencies and communication channels that do not align to a hierarchy, akin to organs in a living organism</p></li><li><p>Only individual organs know how best to serve their functions and should be empowered to do so</p></li></ul>
      <p>
          <a href="https://www.questionablyfunctional.net/p/your-organization-isnt-a-hierarchy">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Running Projects: A Systems Approach]]></title><description><![CDATA[It can be daunting for an engineer to take on leading their first large project.]]></description><link>https://www.questionablyfunctional.net/p/running-projects-a-systems-approach</link><guid isPermaLink="false">https://www.questionablyfunctional.net/p/running-projects-a-systems-approach</guid><dc:creator><![CDATA[Matthew Shea]]></dc:creator><pubDate>Wed, 13 Sep 2023 18:30:13 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/30d9f6d8-b54c-46ba-92fd-213fd0b0d693_3353x2514.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>It can be daunting for an engineer to take on leading their first large project. They may have a dozen engineers, multiple work streams, intense reporting requirements, and tight deadlines. Fortunately, we can leverage a strength any good software engineer has: systems design.</p><p>You can use systems thinking and design to break down a project from technical design to tasks, organize those tasks into work streams, set up reporting, and provide accurate estimates to your stakeholders.</p><p>You can accomplish this by doing the following steps:</p><ol><li><p>Find the work streams</p></li><li><p>Model dependencies between the work streams</p></li><li><p>Breakdown each work stream</p></li><li><p>Find the KPIs for each work stream</p></li><li><p>Build the project system</p></li><li><p>Monitor and adjust</p></li></ol><p>We&#8217;re going to look at two examples inspired by projects I&#8217;ve led, modified to protect proprietary information. For the first example, we&#8217;ll discuss a service that consists of an API that takes in asynchronous work requests and a workflow that processes those requests. For the second example, we&#8217;ll talk about a major project that touches over a dozen services with hundreds of changes.</p><h3>Find the work streams</h3><p>Typically, your software will have boundaries that separate components and you can leverage these to separate your work streams as well. A good tech design will help guide you through this process. We&#8217;ll use this when we go through the first example above.</p><p>If there isn&#8217;t a tech design, you may need to look at the work itself. Assess the work that needs done and find any common patterns in <em>how</em> it will be done. Those patterns will help us define the work streams in the second example.</p><h3>Model dependencies between the work streams</h3><p>Work streams may have dependencies between them. These dependencies will eventually result in bottlenecks where one work stream is waiting on another. To find these, inspect the boundaries in your software. Are there API definitions that need completed? Database models? Message formats? Figure these out, and prioritize resolving these first.</p><h3>Breakdown each work stream</h3><p>For each work stream, start at a high level and find which pieces can be done independently. For instance, you may be building two sets of CRUD APIs for two different resources so you can build these separately. For each resource, you may need to define a data model which will prevent working on each of the Create, Read, Update, Delete APIs. You don&#8217;t want the Create and Delete APIs operating on completely different data models! Model these dependencies between high level tasks. As you do this, you&#8217;ll get a sense for what can be done in parallel and what tasks are blocking others.</p><h3>Find the KPIs for each work stream</h3><p>If you&#8217;re leading a project of any size, there will be someone wanting to know how progress is going. For some projects, it may make sense to assign task points and try to report the progress on those. For some projects, that could be a complete waste of time and something like ticket count would be a better fit. For others, you may report on the completion of each sub workstream, such as which APIs are done and which aren&#8217;t. Work with your stakeholders to find the right way to report progress.</p><p>KPI (Key Performance Indicator) is business word to many engineers, but it&#8217;s really just a metric to measure the success of a particular system. As software engineers, we know how to measure systems. Consider each of your work streams and what you would need to measure to report status to your stakeholders. </p><h3>Build the project system</h3><p>Now, we have the information we need to start figuring out how the project should function. We have our work streams, we understand the dependencies, and we know how many people we have. You&#8217;ll generally want to assign a single owner to each work stream, unless a stream is especially small and can be easily managed by someone with split attention. Model out the project as you would any other system, including reporting lines and work streams.</p><h3>Monitor and adjust</h3><p>No plan survives first contact with reality, and your project system is no exception. People will get sick, work streams will move more slowly or more quickly than expected, priorities will shift, and so on. Keep a close eye on the system, identify constraints, and eliminate them.</p><div><hr></div><h2>Example One: Async Workflow</h2><p>For this example, we have a simple system where an API ingests work that a workflow completes in the background. Here&#8217;s the (very) high level technical design.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!E77p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401cf080-4640-465d-b249-83fe072fe435_962x164.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!E77p!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401cf080-4640-465d-b249-83fe072fe435_962x164.png 424w, https://substackcdn.com/image/fetch/$s_!E77p!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401cf080-4640-465d-b249-83fe072fe435_962x164.png 848w, https://substackcdn.com/image/fetch/$s_!E77p!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401cf080-4640-465d-b249-83fe072fe435_962x164.png 1272w, https://substackcdn.com/image/fetch/$s_!E77p!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401cf080-4640-465d-b249-83fe072fe435_962x164.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!E77p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401cf080-4640-465d-b249-83fe072fe435_962x164.png" width="962" height="164" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/401cf080-4640-465d-b249-83fe072fe435_962x164.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:164,&quot;width&quot;:962,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:21882,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!E77p!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401cf080-4640-465d-b249-83fe072fe435_962x164.png 424w, https://substackcdn.com/image/fetch/$s_!E77p!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401cf080-4640-465d-b249-83fe072fe435_962x164.png 848w, https://substackcdn.com/image/fetch/$s_!E77p!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401cf080-4640-465d-b249-83fe072fe435_962x164.png 1272w, https://substackcdn.com/image/fetch/$s_!E77p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F401cf080-4640-465d-b249-83fe072fe435_962x164.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p><ol><li><p>API writes the work request to a datastore</p></li><li><p>The datastore event triggers the workflow</p></li><li><p>The workflow performs the work and marks the request as completed</p></li><li><p>When the caller requests the status, the API reads from the datastore</p></li></ol><p>Let&#8217;s go through the process outlined above to build a project system that can deliver this software system.</p><h3>Work Streams</h3><p>First, we can see three main parts of the system: The API, The Datastore, The Workflow. In this case, the work streams fall out of the architecture diagram. Let&#8217;s start by considering each of these a separate work stream and move to the next step.</p><h3>Dependencies</h3><p>Looking at the diagram, we can see that The API and The Workflow depend on The Datastore. The API and The Workflow are fairly independent, though. There may be some common code, but the bulk will be in how they interact with The Datastore. We can rework our diagram to show these dependencies.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!r-sA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb39d4b7f-d8b9-4345-a04b-470b8b0d6019_722x322.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!r-sA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb39d4b7f-d8b9-4345-a04b-470b8b0d6019_722x322.png 424w, https://substackcdn.com/image/fetch/$s_!r-sA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb39d4b7f-d8b9-4345-a04b-470b8b0d6019_722x322.png 848w, https://substackcdn.com/image/fetch/$s_!r-sA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb39d4b7f-d8b9-4345-a04b-470b8b0d6019_722x322.png 1272w, https://substackcdn.com/image/fetch/$s_!r-sA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb39d4b7f-d8b9-4345-a04b-470b8b0d6019_722x322.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!r-sA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb39d4b7f-d8b9-4345-a04b-470b8b0d6019_722x322.png" width="722" height="322" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b39d4b7f-d8b9-4345-a04b-470b8b0d6019_722x322.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:322,&quot;width&quot;:722,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:21121,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!r-sA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb39d4b7f-d8b9-4345-a04b-470b8b0d6019_722x322.png 424w, https://substackcdn.com/image/fetch/$s_!r-sA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb39d4b7f-d8b9-4345-a04b-470b8b0d6019_722x322.png 848w, https://substackcdn.com/image/fetch/$s_!r-sA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb39d4b7f-d8b9-4345-a04b-470b8b0d6019_722x322.png 1272w, https://substackcdn.com/image/fetch/$s_!r-sA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb39d4b7f-d8b9-4345-a04b-470b8b0d6019_722x322.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>We have a problem, though. According to this diagram, we need to complete The Datastore before we can start work on The API or The Workflow. This means those two work streams will be stalled waiting on the third, which isn&#8217;t great. We want to go fast.</p><p>Fortunately, with a strong architecture in our code, we can abstract away the implementation detail of The Datastore. I won&#8217;t get into code architecture in this post because it deserves its own, but just imagine The API&#8217;s code and The Workflow&#8217;s code operate against interfaces instead of making database queries.</p><p>With this abstraction, we can break the dependencies and work on all three work streams simultaneously.</p><h3>Breakdown The Work</h3><p>Now, we need to get some tasks. I recommend using a simple bullet list to start. For the API workstream, we might produce something like this:</p><ul><li><p>API Infrastructure</p><ul><li><p>Create containers</p></li><li><p>Create load balancer</p></li></ul></li><li><p>CreateFoo</p><ul><li><p>Define API model</p></li><li><p>Implement</p></li><li><p>Testing</p></li></ul></li><li><p>ReadFoo</p><ul><li><p>Define API model</p></li><li><p>Implement</p></li><li><p>Testing</p></li></ul></li><li><p>UpdateFoo</p><ul><li><p>Define API model</p></li><li><p>Implement</p></li><li><p>Testing</p></li></ul></li><li><p>DeleteFoo</p><ul><li><p>Define API model</p></li><li><p>Implement</p></li><li><p>Testing</p></li></ul></li></ul><p>And so on and so forth. Once you have your bullet list, it&#8217;s worth doing a check for dependencies again. We want to make this maximally parallelizable. Fortunately, if you are following a strong testing pyramid design, these can all be done individually. You can build the CreateFoo API and test it without having any real containers running. You can continue breaking this bullet list down, perhaps a task for each test. At this point, we&#8217;re talking tasks and not work streams, so we&#8217;ll leave it here.</p><h3>Reporting and KPIs</h3><p>For this example, we can probably follow a traditional task pointing system. The work is fairly well understood and easy to estimate. Once you go through your planning sessions and assign points as a team, you can just report progress on those points as your KPI.</p><h3>The Project System</h3><p>Let&#8217;s say we have 5 engineers that can work on this project: Alice, Bob, Charlie, and Dani. The last one is the project lead: you.</p><p>We have three parallelizable work streams: The API, The Workflow, and The Datastore. We&#8217;ll assign Alice to The API and Charlie to The Workflow, as they need opportunities to lead a small project. You must delegate ownership of these streams to them. We&#8217;ll get into delegation in another post and how to use it to empower your fellow engineers and help them grow. The Datastore is especially concerning, as you need to make sure the data model is extensible. You&#8217;ll take that responsibility as the most experienced engineer on the team.</p><p>This leaves Bob and Dani unassigned. The Datastore doesn&#8217;t have a large volume of work, so you assign them to Alice and Charlie&#8217;s work streams respectively.</p><p>Since Alice and Charlie own their own workstreams, they only need to communicate with you insofar as escalating major issues or resolving conflicts on the boundary. You are the only one communicating with stakeholders, so they have a single point of contact and there is no confusion when communicating.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0FuS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F906bdbd0-eeca-46cf-a087-456d665ecc14_1842x916.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0FuS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F906bdbd0-eeca-46cf-a087-456d665ecc14_1842x916.png 424w, https://substackcdn.com/image/fetch/$s_!0FuS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F906bdbd0-eeca-46cf-a087-456d665ecc14_1842x916.png 848w, https://substackcdn.com/image/fetch/$s_!0FuS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F906bdbd0-eeca-46cf-a087-456d665ecc14_1842x916.png 1272w, https://substackcdn.com/image/fetch/$s_!0FuS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F906bdbd0-eeca-46cf-a087-456d665ecc14_1842x916.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0FuS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F906bdbd0-eeca-46cf-a087-456d665ecc14_1842x916.png" width="1456" height="724" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/906bdbd0-eeca-46cf-a087-456d665ecc14_1842x916.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:724,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:127132,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0FuS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F906bdbd0-eeca-46cf-a087-456d665ecc14_1842x916.png 424w, https://substackcdn.com/image/fetch/$s_!0FuS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F906bdbd0-eeca-46cf-a087-456d665ecc14_1842x916.png 848w, https://substackcdn.com/image/fetch/$s_!0FuS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F906bdbd0-eeca-46cf-a087-456d665ecc14_1842x916.png 1272w, https://substackcdn.com/image/fetch/$s_!0FuS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F906bdbd0-eeca-46cf-a087-456d665ecc14_1842x916.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This diagram illustrates the system for the project team. You are not interacting with Bob and Dani since Alice and Charlie are directing them. The Stakeholder is not communicating with anyone else, ensuring clear communication from the project team. Any issues in the work streams are escalated through you, the project lead.</p><h3>Monitor and adjust</h3><p>When we executed this project, we encountered some unexpected complexity in the Datastore that resulted in almost two weeks of extra planning and another two weeks of implementation work. Once we realized that it was going to be more complex, we were able to pull a more experienced engineer off of the Workflow workstream to assist. The API also ended up being simpler than expected, so we were able to rebalance one engineer from that workstream to the Workflow.</p><p>Pay close attention to how your project system is behaving and adjust accordingly.</p><div><hr></div><h2>Example Two: Multi-Region Support</h2><p>For Example Two, we&#8217;re going to look at a project with a larger scope and a different structure. This project is to take our system consisting of around a dozen microservices and enable it to launch in any AWS Region. Until now, the service had only needed to run in one region, so there are a lot of places in the code that just refer to the one region. Further, we need to consider data replication across regions and a failover mechanism should one region stop functioning.</p><h3>Work Streams</h3><p>For this project, we could structure the work in a few ways. For the first pass, we look at enabling this service-by-service, where we would define our work streams based on the service, so a dozen work streams. That&#8217;s a lot of parallel work to track and doesn&#8217;t really look at the entire system. </p><p>The first step we&#8217;ll take is to get an idea of the work that actually needs done. After completing an audit, we find the following:</p><ul><li><p>Hundreds of static references to a specific region</p></li><li><p>Twelve datastores that need to support cross-region replication</p></li><li><p>Three workflows that need to support some kind of cross-region exclusivity</p></li><li><p>Updating deployment pipelines to support multiple regions</p></li></ul><p>After doing this audit, we can really break it down into four major types of work:</p><ul><li><p>Static Configuration Fixes</p></li><li><p>Datastore Replication</p></li><li><p>Workflow Exclusivity</p></li><li><p>Deployment Pipeline</p></li></ul><p>Since these types are all likely to have similar <em>solutions</em>, we define these as the work streams. This will allow the people working each stream to focus within a particular <em><strong>problem/solution space</strong></em><strong>,</strong> and we can assign them based on their skills.</p><h3>Dependencies</h3><p>Going through the dependency modeling exercise, we know that Datastore Replication and Workflow Exclusivity are going to be blocked on the Static Configuration Fixes. We can&#8217;t really test solutions for cross-region replication or exclusivity locks when the services can&#8217;t even be deployed in multiple regions due to hardcoded values. Updates to the Deployment Pipeline are going to have similar concerns.</p><p>Unlike Example One, we can&#8217;t really abstract the dependencies behind interfaces to break them during development. We can do some exploration and design in the later work streams, but not really much more. We need to figure out how to structure the work so that the blocked work streams can actually get started.</p><p>Looking at the work streams, we identify specific tasks along another dimension: the microservice. Let&#8217;s look at three hypothetical microservices: Thor, Odin, and Fafnir.</p><p>As we see, we actually have <em>twelve</em> divisions of work to go on. Further, we know that Fafnir needs Odin present to function, and Odin needs Thor. We model our dependencies like this, which gives us an ordering to do the workstreams in for each service.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VboH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391cd9e5-9cc3-4036-9634-ed728660c494_1018x534.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VboH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391cd9e5-9cc3-4036-9634-ed728660c494_1018x534.png 424w, https://substackcdn.com/image/fetch/$s_!VboH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391cd9e5-9cc3-4036-9634-ed728660c494_1018x534.png 848w, https://substackcdn.com/image/fetch/$s_!VboH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391cd9e5-9cc3-4036-9634-ed728660c494_1018x534.png 1272w, https://substackcdn.com/image/fetch/$s_!VboH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391cd9e5-9cc3-4036-9634-ed728660c494_1018x534.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VboH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391cd9e5-9cc3-4036-9634-ed728660c494_1018x534.png" width="1018" height="534" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/391cd9e5-9cc3-4036-9634-ed728660c494_1018x534.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:534,&quot;width&quot;:1018,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:76395,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VboH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391cd9e5-9cc3-4036-9634-ed728660c494_1018x534.png 424w, https://substackcdn.com/image/fetch/$s_!VboH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391cd9e5-9cc3-4036-9634-ed728660c494_1018x534.png 848w, https://substackcdn.com/image/fetch/$s_!VboH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391cd9e5-9cc3-4036-9634-ed728660c494_1018x534.png 1272w, https://substackcdn.com/image/fetch/$s_!VboH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F391cd9e5-9cc3-4036-9634-ed728660c494_1018x534.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Let&#8217;s model this as a directed graph, taking into account the dependencies in the actual work, and the order we want to do these services in. This will come in handy later.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RaV3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4236ec7b-cd8c-4a2b-9405-50fa81a7dcbc_721x721.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RaV3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4236ec7b-cd8c-4a2b-9405-50fa81a7dcbc_721x721.png 424w, https://substackcdn.com/image/fetch/$s_!RaV3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4236ec7b-cd8c-4a2b-9405-50fa81a7dcbc_721x721.png 848w, https://substackcdn.com/image/fetch/$s_!RaV3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4236ec7b-cd8c-4a2b-9405-50fa81a7dcbc_721x721.png 1272w, https://substackcdn.com/image/fetch/$s_!RaV3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4236ec7b-cd8c-4a2b-9405-50fa81a7dcbc_721x721.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RaV3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4236ec7b-cd8c-4a2b-9405-50fa81a7dcbc_721x721.png" width="721" height="721" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4236ec7b-cd8c-4a2b-9405-50fa81a7dcbc_721x721.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:721,&quot;width&quot;:721,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:104239,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!RaV3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4236ec7b-cd8c-4a2b-9405-50fa81a7dcbc_721x721.png 424w, https://substackcdn.com/image/fetch/$s_!RaV3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4236ec7b-cd8c-4a2b-9405-50fa81a7dcbc_721x721.png 848w, https://substackcdn.com/image/fetch/$s_!RaV3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4236ec7b-cd8c-4a2b-9405-50fa81a7dcbc_721x721.png 1272w, https://substackcdn.com/image/fetch/$s_!RaV3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4236ec7b-cd8c-4a2b-9405-50fa81a7dcbc_721x721.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h3>Breakdown the Work</h3><p>For each of these, we&#8217;ll do the standard work breakdown process as covered in Example One.</p><h3>Reporting and KPIs</h3><p>For a project like this, it may be tempting to report based on the work streams, but the reality is that your stakeholder doesn&#8217;t care about the implementation details of your services. They want to know how far you are through the service list that needs fixed and when you can launch in the new region. For this project, we actually want to report on that extra dimension we added above, the service. But we are planning to do the work based on the type of work, not the service. Our stakeholders are going to complain if we say no services are done, then suddenly they all are, so we need a way to approach this work so that we can report service-by-service, but allow our engineers to work in a specific problem space.</p><h3>The Project System</h3><p>In a case like this, we need to embrace a system inspired by graph traversal. We will walk the dependency graph, actively working on any nodes that have no blocking dependencies.</p><p>First, we&#8217;ll have our Static Configuration team tackle Thor&#8217;s configurations. When this is done, we have unblocked the Datastore Replication and Workflow Exclusivity work streams. We&#8217;ve also freed up the Static Configuration workstream to move on to Odin.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yZVc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dede05-9136-4b97-bf78-61e254dd70b0_721x721.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yZVc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dede05-9136-4b97-bf78-61e254dd70b0_721x721.png 424w, https://substackcdn.com/image/fetch/$s_!yZVc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dede05-9136-4b97-bf78-61e254dd70b0_721x721.png 848w, https://substackcdn.com/image/fetch/$s_!yZVc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dede05-9136-4b97-bf78-61e254dd70b0_721x721.png 1272w, https://substackcdn.com/image/fetch/$s_!yZVc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dede05-9136-4b97-bf78-61e254dd70b0_721x721.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yZVc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dede05-9136-4b97-bf78-61e254dd70b0_721x721.png" width="721" height="721" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a2dede05-9136-4b97-bf78-61e254dd70b0_721x721.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:721,&quot;width&quot;:721,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:104653,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yZVc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dede05-9136-4b97-bf78-61e254dd70b0_721x721.png 424w, https://substackcdn.com/image/fetch/$s_!yZVc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dede05-9136-4b97-bf78-61e254dd70b0_721x721.png 848w, https://substackcdn.com/image/fetch/$s_!yZVc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dede05-9136-4b97-bf78-61e254dd70b0_721x721.png 1272w, https://substackcdn.com/image/fetch/$s_!yZVc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dede05-9136-4b97-bf78-61e254dd70b0_721x721.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Now, we have three parallel work streams running: Odin Static Configuration, Thor Data Replication, Thor Workflow Exclusivity. Let&#8217;s say they all finish at roughly the same time, so we can update our graph. Now, we have all four work streams running.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zxwT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb15ab5-80c2-4401-ae3b-c565958c9ac0_721x721.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zxwT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb15ab5-80c2-4401-ae3b-c565958c9ac0_721x721.png 424w, https://substackcdn.com/image/fetch/$s_!zxwT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb15ab5-80c2-4401-ae3b-c565958c9ac0_721x721.png 848w, https://substackcdn.com/image/fetch/$s_!zxwT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb15ab5-80c2-4401-ae3b-c565958c9ac0_721x721.png 1272w, https://substackcdn.com/image/fetch/$s_!zxwT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb15ab5-80c2-4401-ae3b-c565958c9ac0_721x721.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zxwT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb15ab5-80c2-4401-ae3b-c565958c9ac0_721x721.png" width="721" height="721" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4cb15ab5-80c2-4401-ae3b-c565958c9ac0_721x721.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:721,&quot;width&quot;:721,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:104270,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zxwT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb15ab5-80c2-4401-ae3b-c565958c9ac0_721x721.png 424w, https://substackcdn.com/image/fetch/$s_!zxwT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb15ab5-80c2-4401-ae3b-c565958c9ac0_721x721.png 848w, https://substackcdn.com/image/fetch/$s_!zxwT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb15ab5-80c2-4401-ae3b-c565958c9ac0_721x721.png 1272w, https://substackcdn.com/image/fetch/$s_!zxwT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cb15ab5-80c2-4401-ae3b-c565958c9ac0_721x721.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In the next phase, we will have completed the Thor Deployment Pipeline work, which will allow us to report that Thor is completed to our stakeholders. The next round, we&#8217;ll finish Odin. The following, Fafnir. The project is done.</p><p>Now there are some caveats to this approach. First, we still have work streams waiting on others. This is just unavoidable in such a situation, so we may have later work streams doing design or investigation work while the Static Configuration team works on Thor. Alternatively, we can slowly ramp people into this project as their work streams become unblocked. They could also participate in some of the other work streams to move things along faster. Flexibility is the name of the game with this approach. Everyone should be ready to do what&#8217;s needed at any given time.</p><p>So where does that leave you, our project lead? You will need to wear two hats. First, manage the graph traversal. Keep track of the progress being made on each item and what downstream impacts it may have. You may need to shuffle people around to keep things balanced. Second, work through the more complex issues where your technical guidance may be needed.</p><h3>Monitor and adjust</h3><p>This project system is a complex dance of timings and downstream impacts, and needs close monitoring and rapid adjustment. If any one work stream starts lagging behind, it could delay the entire project significantly.</p><p>You will need to move people around and find creative ways to work around dependencies. This is a highly dynamic process that can only be managed through good KPIs and an attentive project leader.</p><h2>Conclusion</h2><p>Leading large projects can be overwhelming and intimidating at first, but at its core, you just need to find the right system. Example One shows us a basic system where <strong>the work aligns to the software being built</strong>. Example Two demonstrates a more complex arrangement where you opt to <strong>align the work to the problem or solution spaces at hand</strong>.</p><p>In both cases, you&#8217;re ultimately aligning to some understandable sequence implicit in the work itself. Learning to identify how the work is structured naturally will enable you to apply the right approach for any given project.</p><div><hr></div><p>Questionably Functional is a reader-supported publication, providing a single free article monthly with weekly paid articles. If you found this article helpful and would like more, please subscribe below.</p><p>Some employers may allow you to expense subscriptions to industry newsletters under their Education or Development budgets. Click <a href="https://www.questionablyfunctional.net/p/expensing-questionably-functional">here</a> for more information.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.questionablyfunctional.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.questionablyfunctional.net/subscribe?"><span>Subscribe now</span></a></p><p>If you have a question or topic that&#8217;s been on your mind, and you&#8217;d like my opinion on it, you can submit a question using the link in the navigation bar. Thank you!</p>]]></content:encoded></item><item><title><![CDATA[Remote Work Isn't Ineffective, It's Just Different]]></title><description><![CDATA[Anyone who has always cooked on a gas stove and then switched to electric will decry electric stoves as an objectively inferior solution. Conversely, someone who has always cooked electric and then tried to cook on gas will decry gas stoves as an objectively inferior solution. Setting aside the shockingly volatile social media landscape around this issue, the lesson here is really one of familiarity. These are both perfectly viable solutions for getting heat into a pan, but they require different techniques to get you to the same place. If you try to apply the techniques used cooking on a gas stove to cooking on electric, you&#8217;re going to have a bad time.]]></description><link>https://www.questionablyfunctional.net/p/remote-work-isnt-ineffective-its-just-different</link><guid isPermaLink="false">https://www.questionablyfunctional.net/p/remote-work-isnt-ineffective-its-just-different</guid><dc:creator><![CDATA[Matthew Shea]]></dc:creator><pubDate>Wed, 06 Sep 2023 18:30:10 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/8fb7508b-02ec-43f2-9d38-266854cb7f6e_5848x3899.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Someone who has always cooked on a gas stove and then switched to electric will decry electric stoves as an objectively inferior solution. Conversely, someone who has always cooked electric and then tried to cook on gas will decry gas stoves as an objectively inferior solution. Setting aside the shockingly volatile social media landscape around this issue, the lesson here is one of familiarity. These are both perfectly viable solutions for getting heat into a pan, but they require different techniques to get you to the same place. If you try to apply the techniques used cooking on a gas stove to cooking on electric, you&#8217;re going to have a bad time. </p><p>This is the case with remote work and office work. One isn&#8217;t implicitly better than the other, but they do require different techniques. If you&#8217;re experiencing friction in a remote or hybrid team, the odds are high that you&#8217;re just trying to use the wrong techniques to build your organizational system.  This is the core problem with many claims about remote work&#8217;s alleged ineffectiveness. <strong>By neglecting to look at organizations through a systems frame, it&#8217;s easy to believe that specific techniques are the only solution available.</strong> That is, that gas stoves are the <em>only</em> option to cook food effectively. Instead, you must look at the system and the needs it actually has. Once identified, think broadly and deeply about how you can resolve those needs in certain contexts and with certain constraints. To torture the metaphor one last time, an open fire is a delightful technique to cook food when out camping, but applying that technique indoors will lead to a visit from the fire department. Think critically and choose wisely.</p><div><hr></div><p>In this post, we&#8217;ll take a look at some common needs working in a white-collar office job and explore how different techniques can be used for each situation. Having worked successfully both in-office and remote for many years, I&#8217;ve learned a few things about how to address common gaps. We&#8217;ll also touch on some of the unique benefits enabled by work flexibility that can be billed as employee perks to attract talent.</p><h3>Information Sharing</h3><h4>Crossing Silos</h4><p>Advocates of an office environment will claim that there is improved information sharing compared to remote work, specifically citing the &#8220;water cooler conversations&#8221; or &#8220;after meeting chats.&#8221; Water cooler conversations are typically short exchanges of information, such as a problem you&#8217;re having or a project you&#8217;ve started. These exchanges are incredibly valuable to an organization, because they help expose gaps in the formal communication mechanisms.</p><p>The error here is thinking these are ends in-and-of themselves. That is, &#8220;You can&#8217;t have water cooler conversations when there is no water cooler.&#8221; That&#8217;s obvious, but are water cooler conversations some implicit good? No, absolutely not. They are only useful as a <em>technique</em> for sharing information across typical boundaries and silos. If you have no water cooler, you need to address this need with another technique. </p><p>There are a few options here, the ones I&#8217;ve seen most often being sync meetings and adhoc notifications. I&#8217;m generally against sync meetings, even in the office. The cold hard reality is that people largely wait for their turn to speak in these meetings and don&#8217;t really engage consistently. We&#8217;ll get into meeting engagement in another post, but I think we can all agree this is more-or-less true. Doing these meetings over video conference only adds a layer of disconnection.</p><p>Instead, try <strong>adhoc notification mechanisms</strong>. Create a place where teams can send high-level notices and updates, such as a Slack channel, email list, etc. If you&#8217;re starting to explore a particular problem space, send a notice. If you&#8217;ve delivered something of high value, send a notice. If you need guidance on something others may have already solved, send a notice. This fully replaces the need for water cooler conversations, and actually performs the function better. It&#8217;s not just two or three people who all sit near each other getting the information, it&#8217;s dozens of people across the company. Managers, product managers, and senior engineers can watch these channels casually, looking for anything that needs their attention.</p><p>During my time at Amazon, this was used to great effect. First, it was interest mailing lists. By subscribing to <code>lambda-interest</code> , you&#8217;d get notifications about things happening with AWS Lambda. Later, this moved to Slack, but the function remained largely the same. These mechanisms have been critical for me when trying to keep tabs on what&#8217;s happening across an organization of that size.</p><h4>Diving Deep</h4><p>The &#8220;after-meeting chat&#8221; is another technique that is often cited as necessary. Reflecting on my experience with them, these chats were almost always deep dives into some specific area. Maybe someone brought up the need for encryption in a meeting, but wasn&#8217;t sure how to do it. You stay with them for 10 minutes afterwards to share your experiences.</p><p>There&#8217;s absolutely no reason this can&#8217;t be done remotely. Slack&#8217;s Huddle feature is perfect for quick chats like this, and I use it all the time. The only difference is that it requires hitting a button instead of awkwardly standing around a meeting room. You should encourage each other to be available for conversations like this, as they are critical to the &#8220;riffing&#8221; cited by certain executives. If people on your team are not making themselves available, this is a performance management problem, not a process problem.</p><h4>The Rest</h4><p>Any mechanism based on a meeting remains more-or-less the same when working remotely. Weekly or monthly updates are usually meetings. Sprint ceremonies are usually meetings. These are just as easy to do remotely as in-person. Encourage people to turn their cameras on during meetings to help with communication. We&#8217;ll get to that topic later.</p><h3>Raw Productivity</h3><p>Ultimately, we all have work to do. Write code, write design documents, meet with customers, look for candidates on LinkedIn, etc. This is all work that requires some degree of uninterrupted focus.</p><p>Modern open office floorplans, which I&#8217;ll address in another post, are probably the greatest sin committed against this need. <strong>People need to focus, and in order to do so they need workspaces that allow them to focus.</strong> Typically, this means noise cancelling headphones <em>everywhere.</em> Why are we building office environments that are so harmful to productivity that people feel the need to isolate themselves anyway?</p><p>Working remotely is clearly better in this instance. Employees are empowered to build workspaces that enable them to work most effectively. They can have as much cleanliness or distraction as is necessary. For me, I need to fidget when thinking, so I have an array of fidget toys on my desk that can make as much noise as I want. My cat also sleeps nearby, so I can get some ear scritches in during a stressful meeting. Empowering employees this way is absolutely critical if you are aiming to support a more diverse workforce. We&#8217;ll get into diversity in a later section.</p><h3>Collaboration</h3><p>Collaboration is the trickiest area for remote work. In-office advocates will rightly point out the power of whiteboarding sessions. Getting people in front a whiteboard together to brainstorm or work through technical designs can have a great effect, but that&#8217;s not the only way to collaborate. Let&#8217;s look at the needs that the whiteboarding  technique addresses:</p><ul><li><p>Live feedback</p></li><li><p>Diagramming and writing</p></li><li><p>Broad input</p></li></ul><p>Live feedback and broad input can be achieved with virtual meetings. The real challenge virtually is with diagramming and writing.</p><p>Virtual whiteboards exist and have been very effective for me, but ultimately what I&#8217;ve found to work best is shifting to a more asynchronous collaboration model inspired by the Japanese business practice of nemawashi. Nemawashi is, as defined by Wikipedia, the &#8220;informal process of quietly laying the foundation for some proposed change or project by talking to the people concerned and gathering support and feedback before a formal announcement." Have one or two people take an initial pass at the design, then share it out to collaborators for feedback. Your collaborators can take some time to review it, really think it through, then send you any changes they think need to be made. Update the design and send it back out. Do this until you have some broad agreement. If there are any sticking points between collaborators, you can schedule a short focused meeting to address that point.</p><p>I truly believe this model is better for collaborating on all manner of work. It enables deep thought on the topic, encourages feedback from everyone, and ultimately produces a better product. Companies like Amazon have been doing this very thing through their narrative process long before remote work was common; where someone writes a narrative document, gets it reviewed, updates it, gets it reviewed, and so on until there is agreement. This approach comes with the benefit of being self-documenting as well.</p><h3>Team Building</h3><p>Lack of connection to your team is another issue that comes up. The traditional team building techniques, such as lunches, events, and happy hours, are just not possible remotely. You need to take a compeltely different approach to team building when working remote, but it is completely possible. You <em>can</em> have human connection when remote.</p><p>Cameras on, folks! I know this is controversial, but I&#8217;ve never really understood the disdain for cameras in meetings. If you were in the office, you wouldn&#8217;t be able to hide behind an off switch. Having your camera on enables your team to see your body language and facial expressions, which are both critical components of human communication. Disembodied voices are for airport announcements. If you&#8217;re in a meeting, turn your camera on. It&#8217;s essential to how humans communicate. If you get self-conscious staring at yourself, most virtual meeting tools support turning off your own camera display.</p><p>In the office, teams rely on happy hours, game time, and so on to try to foster communication. Even before remote, this was getting less and less popular. My team had a standing happy hour starting around 3PM on Friday. Most people just showed up for the free food and left at 3:30PM for a start to an early weekend. This kind of team event is low effort and does nothing substantial. This is made even worse when it&#8217;s remote, because no one wants to sit in front of a camera doing nothing for two hours. Instead, invest in team events such as virtual escape rooms, or multiplayer games. We did Jackbox and Among Us on my team a few times, which were great experiences. These types of events are good because they are drop-in and people can come and go as needed. If anyone of you play video games, play them together. The key thing is to get people tackling problems of some kind together. Nothing builds community and trust like going through something challenging together, even if it&#8217;s just a game.</p><p>From the perspective of the company, the most vital thing you can do is to arrange offsites or conferences. Use all that money you&#8217;re saving on rent, leases, property tax, subsidies, maintenance, HVAC, and more to bring your teams together two or more times a year. It&#8217;s expensive, yes, but it will foster a sense of community like nothing else. You can get meals together, brainstorm, run lecture workshops, announce big initiatives, have cross-organization planning sessions, and so on. Events like this contribute to resolving pretty much every gap in remote work, and will accelerate your business and build your team. They are a great return on investment and also serve as a great employee perk to advertise, because who doesn&#8217;t like an all-expenses paid trip to different cities?</p><h3>Work Flexibility</h3><p>Remote work is itself a technique for your organization that comes with its own benefits, the first of which is flexibility.</p><p>Flexibility in work is one of the largest benefits to remote work. People need to get to the doctor, go to the bank, take a pet to the vet, handle a home repair, and so on. These are things that exist regardless of where the person works, but are so much easier to handle with remote work.</p><p>In the office, your employees&#8217; only option is to take time off work to get things done. Even if they take a partial day, the office may be nowhere near their vet doctor, so they are commuting even more than usual. By enabling employees to work remotely, you empower them to balance their work and their life needs far more effectively. </p><p>A home repair could mean working 6 hours and dealing with the repair for 2 instead of taking a full day off. A couple of years ago, I had my home&#8217;s plumbing completely redone. It took several days with several plumbers. If I were mandated to be in the office, I would have had to take the days off, which would have meant no productivity for my employer. Since I was working remotely, I could keep working and just check in on them every couple of hours. It was actually <em>beneficial</em> for my employer because I was still working and still delivering to meet deadlines.</p><p>Child care is another great example. Working remotely, you can drop your kids off at school and pick them up on time, saving the cost of after-school care or babysitters. Is your child sick? You can keep an eye on them throughout the day while still getting work done. A child being sick may not mean a client meeting is cancelled.</p><p>These are <em>major</em> perks for employees that also benefit the employer because their workforce is more predictable and consistent.</p><h3>Diversity, Equity, and Inclusion</h3><p>I won&#8217;t pretend to be an expert on DEI, but I do my best. That said, I&#8217;ve seen the benefits that remote work can bring to organizations, and they cannot be overstated. Remote work is itself a technique to improving diversity.</p><p>Neurodivergent individuals may suffer from open office floor plans where distraction is high and social interaction is a constant consideration, but thrive when able to work in a space suited to them. Motherhood no longer precludes a woman from working, because work flexibility empowers her to do both. Those with medical conditions, such as the 15% of the population with IBS, are able to continue working without fear of no bathroom being available when lightning strikes. Those with mobility impairments don&#8217;t need to be concerned with crossing several streets to get to another building for a meeting. These are all benefits to improving the diversity of your workforce.</p><p>You can even enable diversity in your workforce in unexpected ways unrelated to the traditional protected classes. Remote work enables a geographically and culturally diverse team that can bring in new opinions and perspectives. For example, I worked for a team whose primary customer base consists of homeowners with a mind towards securing their property. I was shocked to discover that I was one of only a few people in my department who owned a single-family home in a city with one of the highest property crime rates in the country. How are you going to truly understand your customers if no one on your team is actually in that situation? How will people living in secured apartment buildings and condos understand the needs of someone who owns a single-family home? They can&#8217;t. They&#8217;re just making educated guesses. By enabling diversity of where people live and work, you can empower your business to understand customers in ways that were previously impossible.</p><p>If you&#8217;re <em>serious</em> about DEI and not just using it as marketing on your website, supporting remote work is imperative. Diversity is good for your business and for your employees.</p><h2>Conclusion</h2><p>Remote work isn&#8217;t ineffective, it&#8217;s just different. If you&#8217;re trying to use the same techniques as an in-office organization to run a remote team, you&#8217;re simply doing it wrong. You&#8217;re going to have friction and rough edges. Embrace remote work and learn the techniques needed to manage a distributed organization. Rather than lamenting what&#8217;s been lost, dive deeper and find a way to replace it or improve it.</p><p>The burden is on you, the employer, because employees absolutely will leave you for someone who embraces more flexible work options. Do you want to be left behind, fighting your employees, or do you want to lead the charge by applying systems thinking to your organization, doing the hard work, and building a talented and diverse workforce that gives you a competitive edge?</p><div><hr></div><p>Questionably Functional is a reader-supported publication, providing a single free article monthly with weekly paid articles. If you found this article helpful and would like more, please subscribe below.</p><p>Some employers may allow you to expense subscriptions to industry newsletters under their Education or Development budgets. Click <a href="https://www.questionablyfunctional.net/p/expensing-questionably-functional">here</a> for more information.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.questionablyfunctional.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.questionablyfunctional.net/subscribe?"><span>Subscribe now</span></a></p><p>If you have a question or topic that&#8217;s been on your mind, and you&#8217;d like my opinion on it, you can submit a question using the link in the navigation bar. Thank you!</p>]]></content:encoded></item><item><title><![CDATA[What is "Questionably Functional"?]]></title><description><![CDATA[A world of systems]]></description><link>https://www.questionablyfunctional.net/p/what-is-questionably-functional</link><guid isPermaLink="false">https://www.questionablyfunctional.net/p/what-is-questionably-functional</guid><dc:creator><![CDATA[Matthew Shea]]></dc:creator><pubDate>Wed, 30 Aug 2023 18:30:07 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/0e7296f2-4c25-4832-bd5a-699c1a765906_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>A world of systems</h2><p>Systems rule our lives in ways that aren&#8217;t always obvious. These can be massive systems, like the economy. These can be small systems, like the way your favorite restaurant runs their kitchen, or even your morning routine.</p><p>We live within these systems, but rarely stop to think about them deeply. To some extent, this makes sense. What impact are you going to have on the stock market&#8217;s trading system standing in the shower? We go along with our lives, but the harsh reality is that these systems are all questionably functional at best. That is, they rarely serve the people within them effectively.</p><p>By better understanding how systems work, we can reflect on the systems we live in and work to improve them. Helping people understand these systems is a primary goal of Questionably Functional.</p><h2>Technology leadership</h2><p>As I&#8217;ve progressed in my career, one thing became abundantly obvious: once you get out of your early career guidance in this industry dries up very quickly. Early on, there are dozens of books and YouTube channels you can learn from, but as you get into the complexities of organizing, inspiring, and developing people, they dry up. Sure, there are books like <em>Radical Candor</em> that can teach you some tricks, but at the end of the day, you&#8217;re on your own. I&#8217;ll be sharing strategies I&#8217;ve used personally when leading software teams to keep people engaged and growing.</p><h2>Software quality</h2><p>Building quality software is fairly well understood, but balancing it against competing demands of cost and time can be deeply challenging. The right tradeoff often depends on your existing software, your business, and your organization&#8217;s needs. Finding the right mixture is more an art than a science, and one I&#8217;ve become fairly adept at. I&#8217;ll be reviewing examples of tradeoffs I&#8217;ve had to make along with what led me to bias towards a particular solution.</p><div><hr></div><p>If any of this sounds interesting, please subscribe using the button below. There will be one free post monthly, paid posts weekly, and the occasional bonus post if something strikes my fancy. Thank you for your support.</p><p></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.questionablyfunctional.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.questionablyfunctional.net/subscribe?"><span>Subscribe now</span></a></p>]]></content:encoded></item></channel></rss>