<?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[Hongologue]]></title><description><![CDATA[I'm Hong and these are my ramblings]]></description><link>https://www.lihongyi.com</link><image><url>https://www.lihongyi.com/img/substack.png</url><title>Hongologue</title><link>https://www.lihongyi.com</link></image><generator>Substack</generator><lastBuildDate>Mon, 15 Jun 2026 10:51:10 GMT</lastBuildDate><atom:link href="https://www.lihongyi.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Li Hongyi]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[hongologue@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[hongologue@substack.com]]></itunes:email><itunes:name><![CDATA[Li Hongyi]]></itunes:name></itunes:owner><itunes:author><![CDATA[Li Hongyi]]></itunes:author><googleplay:owner><![CDATA[hongologue@substack.com]]></googleplay:owner><googleplay:email><![CDATA[hongologue@substack.com]]></googleplay:email><googleplay:author><![CDATA[Li Hongyi]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[How to Be Innovative]]></title><description><![CDATA[Innovation is hard]]></description><link>https://www.lihongyi.com/p/how-to-be-innovative</link><guid isPermaLink="false">https://www.lihongyi.com/p/how-to-be-innovative</guid><dc:creator><![CDATA[Li Hongyi]]></dc:creator><pubDate>Sun, 12 Oct 2025 16:00:00 GMT</pubDate><content:encoded><![CDATA[<h2><strong>Innovation is hard</strong></h2><p>Everybody wants to be more innovative, but it&#8217;s rare to see someone actually succeed. Despite talk about moving to the cloud, the rise of AI, or whatever digital transformation is, most orgs are still stuck with legacy systems and manual processes. Some try to tackle the problem culturally, telling people to be more agile, bold, and creative. But this rarely achieves much more than everyone getting new t-shirts. It&#8217;s not that technology and culture aren&#8217;t important. They are. It&#8217;s that the root causes for these problems run much deeper. To solve them we first have to understand why innovation, especially in the public sector, is actually really really hard.</p><p>First you have to work with people who don&#8217;t want anything. When we started building FormSG, we talked to dozens of agencies, ministries, and stat boards. Most of them said the same thing: &#8220;Who are you?&#8221;, &#8220;Why are you here?&#8221;, &#8220;Please go away.&#8221;. The only person who wanted help was someone at NEA whose job it was to collect pigeon complaints. Singapore has a lot of pigeons and Singaporeans like to complain. So of course there was a form for people to complain about pigeons. When he heard we could help automate his job he was very happy.</p><p>Then you have to work with people who want too many things. When Parking.sg was getting close to launch the three partner agencies (HDB, LTA, URA) all suddenly had long lists of features they needed from the app. They wanted it to manage season parking, pay fines, support family sharing, and literally a hundred other ideas. At that point we couldn&#8217;t even do refunds yet. We only managed to launch because I convinced them to let us do our alpha testing first, and we&#8217;d try to get to those features later. Thankfully once it was clear people liked the app, they stopped asking for more.</p><p>Perhaps the worst problem is when you actually do launch something, a lot of people get very upset. Our team helped with the new ActiveSG app last year. The old system was very expensive and unmaintainable, and there were some challenges working with the vendor. So we knew we had to replace it. We worked very hard over 3 months to hit the handover date. It wasn&#8217;t perfect but we had a solid system. Except if you&#8217;re a parent wrangling three kids showing up for swim class and suddenly you&#8217;re told to use a new app, it doesn&#8217;t matter how good it is, you&#8217;re going to be annoyed.</p><p>So it is hard. Oddly enough, it is rarely the technology that is difficult. And it&#8217;s not enough to tell people to try harder. You have to understand the underlying systems that allow some teams to be innovative while others can only talk about it. There&#8217;s a lot to unpack, but for me it comes down to 3 things: outcomes, structure, and iteration.</p><h2><strong>Innovation needs clear outcomes</strong></h2><p>A common problem in innovation programs is that we don&#8217;t know what we&#8217;re innovating for. Are we trying to reduce costs? Improve usability? Save time? Or are we just trying to do something &#8220;new&#8221;? Without a clear goal your only reference point is what you&#8217;re already doing. And your only source of feedback is whether anyone is unhappy about change, which someone always is. And so you get stuck, wanting to innovate but not able to move.</p><p>Conversely, when you have a clear goal you can be very flexible about how to get there. In the private sector, it might be profit. In F1, it&#8217;s lap time. In AI, it&#8217;s quality benchmark scores. Once you know what you&#8217;re trying to achieve, you can stop obsessing over how you achieve it. Good metrics tell you what to care about, but also what not to care about. Practically, in the public sector even when a team manages to overcome the bureaucracy, technical challenges, and operations to build something really good and present it to leadership, it often gets shot down with a simple &#8220;That&#8217;s not how we do things&#8221;. It&#8217;s not really anyone&#8217;s fault. It&#8217;s hard to make something happen when your job is to make sure nothing happens.</p><p>As an example, AskGov is our Q&amp;A system for the government. Originally, when we did product reviews we would spend a lot of time diving into bug fixes, new buttons, and various design details. While these are all good details for the team to care about, it was not productive for them to walk me through every detail. That changed when we aligned on just two metrics I would care about: Reducing call volume and increasing citizen satisfaction. If calls went down while satisfaction went up, then I did not need to care exactly how the team went about it. On the other hand, if call volume stayed the same and citizens were not happier, then I also did not care what the team had built. Clear outcomes gave the team more freedom to innovate because it gave me a better way to know if it was working.</p><p>This also means that you need to adjust your performance management to match. Innovation awards and recognition are great, but the moment reviews come around and people see they&#8217;re still being judged on something else, all that motivation disappears. This is especially important because, by default, performance ratings are based on your manager&#8217;s impression of you. If you don&#8217;t deliberately tie performance to the outcomes, then you&#8217;ll get a lot of innovation theatre: Projects that get attention and hype, but ultimately don&#8217;t deliver anything. Outcomes are only real when anchored in accountability.</p><h2><strong>Innovation needs structural space</strong></h2><p>Traditional orgs are based on a military structure: top down, central decision making, optimized for command and control. They&#8217;re designed for a small group of people to make decisions, and for everyone else to align quickly and consistently. This is great when you already know what to do and just need to execute. It&#8217;s not so great if you need to figure out what needs to be done.</p><p>Just telling people to innovate doesn&#8217;t work. You need to build structures that give them the space to do it. Innovation, almost by definition, requires creativity and autonomy. This is the opposite of command and control and so you need to design the org in the opposite direction.</p><p>At OGP we designed the team to be a support structure rather than a command structure. The job of management is to provide the space, resources, and tools for the teams to work as effectively as possible, while still holding the team accountable for their outcomes. The team decides what to build, how to build it, and how to prioritize. That&#8217;s where innovation happens.</p><p>A Rube Goldberg machine is one of those things where a marble knocks over some dominoes, which flips a switch, which pushes a broom, and eventually a light turns on. If you removed even a single domino the whole thing would stop working. With traditional structures, we tend to form human Rube Goldberg machines. The CEO tells the director, who tells the team lead, who tells the procurement manager, who tells the vendor, who tells the project manager, who tells the developer. If any part of that chain changes, the whole company might stall. It&#8217;s no surprise then when nobody innovates.</p><p>At Singpass we previously had a lot of Rube Goldberg problems. Even minor launches required coordination from at least six different groups and dozens of people. To address this, we restructured to group people around each product with a clear goal, and explicitly mapped out the main ways the different teams depended on each other. For example, the authentication team had the goal &#8220;Maximize scale and reliability of logins&#8221;, while the customer experience team had &#8220;Minimize user frustration.&#8221;. Each new team was cross-functional (design, frontend, backend, operations). This meant that the vast majority of the work could happen within each team, only occasionally requiring cross team collaboration.</p><p>To be clear, every org structure makes some things easy and other things hard. The key is to make the most common and important things easy, and accept that rare and less important things will be hard. So if you want to be innovative, you need to structure for it deliberately. This means providing support, reducing dependencies, and creating space for creativity and autonomy.</p><h2><strong>Innovation needs iteration</strong></h2><p>Even with clear goals and a good structure, innovation fails most of the time. At OGP, we run a month long hackathon at the start of each year. The team explores different ideas, builds quick prototypes, and takes the best ones to launch. We start with around 100 ideas. About 25 make it to prototypes. Fewer than 5 become full products. The other ideas aren&#8217;t bad. There are just a lot of reasons they may not work. Maybe the operations were too complex. Maybe the integrations weren&#8217;t ready. Maybe the users didn&#8217;t think there was a problem in the first place.</p><p>This means that even if a very smart leader has an idea, the likelihood that it fails is 95%. Even if a committee thoroughly gathers requirements and debates scope for months, only 1 in 20 will succeed. It&#8217;s not that they did their job poorly. These are just probabilities you have to work with.</p><p>To get good ideas, you have to start with a lot of ideas, then experiment to find out what can actually work. What makes an idea valuable is not the idea itself, but whether it&#8217;s been refined through iteration.</p><p>One example is Armory, an app we built for SCDF to help firemen track their equipment. After a year of development and iteration we got something really good rolled out to all the fire stations. By moving off paper, it made equipment checks easier, tracked necessary maintenance, and improved operational readiness. Since the firemen loved it, we thought the paramedics could use it too.</p><p>They hated it. Ambulances carry hundreds of small items and medications. Armory forced them to check every item, every shift, even ones they hadn&#8217;t used. This added up to over 400 different checks every day. It was slow, frustrating, and not worth it. It&#8217;s surprisingly hard to anticipate why an idea might not work. Even good ideas can fail when subtle differences between seemingly similar users turn out to matter more than expected.</p><p>So we kept iterating. We cut unnecessary checks. We added item groups, so teams could clear items in bulk. We introduced scheduling, so some items only needed to be checked weekly or monthly. This cut the number of daily checks from over 400 to less than 70. It took lots of feedback and testing, but eventually it became something paramedics actually wanted to use. With so many ways for ideas to fail, iteration is the only way to successfully innovate.</p><h2><strong>Why we need to be innovative</strong></h2><p>We&#8217;ve talked a lot about how we can innovate, but I think it&#8217;s worth closing off by asking why we should? After all, the Singapore system is pretty good. Why bother with innovation and just focus on keeping things running instead?</p><p>For me it&#8217;s because, while we&#8217;re doing relatively well, there are still a lot of people who need help. People who just live with medical problems because getting treatment means taking too much time off work. People who get scammed out of their life savings because it was too hard to protect yourself online. People who could have avoided life changing issues if they only got the right support at the right time just a little bit earlier. If we say &#8220;this is good enough&#8221; what we&#8217;re saying to these people is &#8220;this is what you have to live with&#8221;.</p><p>Innovation isn&#8217;t about being cool, or getting attention, or building excitement. It&#8217;s about being honest that we still have real problems to solve and hard work to do in solving it. We&#8217;re not here to admire how well the system works for most people. We&#8217;re here to make sure it works for everyone.</p><p><em>This article was originally written for and published by <a href="https://knowledge.csc.gov.sg/how-to-be-innovative/">Civil Service College Singapore</a></em></p>]]></content:encoded></item><item><title><![CDATA[Setting Standards for Roles You Know Nothing About]]></title><description><![CDATA[How do you set standards for roles which you have no expertise in?]]></description><link>https://www.lihongyi.com/p/setting-standards-for-roles-you-know</link><guid isPermaLink="false">https://www.lihongyi.com/p/setting-standards-for-roles-you-know</guid><dc:creator><![CDATA[Li Hongyi]]></dc:creator><pubDate>Wed, 10 Sep 2025 16:00:00 GMT</pubDate><content:encoded><![CDATA[<p>How do you set standards for roles which you have no expertise in? This was a challenge I faced when building OGP. What&#8217;s the right bar for a product manager, a senior designer, or a staff engineer? Job titles are all over the place so you can&#8217;t rely on them. And every org means something different when they call someone an engineer.</p><p>What I ended up doing was talking to anyone in tech who was willing to share their responsibilities and compensation. This gave me a baseline from which I could create competitive roles with similar standards, then adjusted them to our needs. For example, we use rapid prototypes to get buy-in from agencies, so our engineers need more fluency in being full-stack than they do in scaling infrastructure. Similarly, our product managers don&#8217;t need to do much marketing, but they need to be very good at navigating stakeholders. It took a while, but to get this right I had to let go of setting standards philosophically and focus instead on the practical implications.</p><p>When I set standards too high, it was relatively straightforward to diagnose. People got frustrated with their performance ratings. My best officers left for other roles with greater responsibility and compensation. And good candidates consistently got past our interviews only to reject our offers. This was painful, but at least it was easy to fix.</p><p>When I set standards too low, the problem was more insidious. In the short run, everyone was happier. Bigger performance bonuses. Promotions were celebrated. Candidates were happily accepting generous offers. It felt like we had done the right thing.</p><p>Where it bit us later was when teams failed to deliver. Quality dropped and deadlines slipped. People lost trust as colleagues dropped the ball. Yet despite these problems, people stuck around and teams got bigger while delivering worse results. I spent a lot of time chasing these issues before identifying the core problem: people were in roles beyond their capability.</p><p>This can get very complicated in practice. You might expect too much of junior officers while being too lax with senior ones. Mismatched standards meant I had amazing infrastructure engineers struggling because I really needed webdevs. Because our roles are very different from other orgs, I had to accept that new hires wouldn&#8217;t be able to hit the ground running, and we needed to double down on training to get them up to speed. You never get it perfect, but what&#8217;s important is you continually adjust as your needs change.</p><p>At OGP, our mission is to get government technology working with the same efficiency and innovation that the tech industry is known for. I&#8217;ve found that getting standards right has been much more important than any strategic direction or product decision.</p><div><hr></div><p>Practical steps for how I set roles and levels for OGP</p><p>The broad approach is to:</p><ul><li><p>Decide org structure</p></li><li><p>Design roles and levels for it</p></li><li><p>Map them to the market</p></li><li><p>See where you&#8217;re wrong and iterate</p></li></ul><p>Concretely:</p><ol><li><p>Figure out what your org is trying to do. OGP&#8217;s goal is to experiment with new tech ideas across the public sector. So our strategy is to have lots of independent product teams who are good at rapid prototyping.</p></li><li><p>Figure out your ideal long term org structure. Our basic product team is 1 PM 1 Designer 3 Engineers. A division has 5 teams to allow managers to keep context. Division leadership has functional leads to keep expertise in management. This is a bit &#8220;draw the rest of the owl&#8221; but it doesn&#8217;t have to be perfect.</p></li><li><p>Identify stereotypical roles you have in this structure. Write a job description for each of these roles so you&#8217;re clear on what you expect them to do. Actual people will differ from these stereotypes, but they are a useful reference point for expectations.</p></li><li><p>Group similar roles and label them with an approximate seniority needed. In reality you might need someone more senior/junior there depending on project needs, but it serves as a good reference point. Some roles are progressions, where others are different jobs entirely.</p></li><li><p>Go talk to anyone who is in a similar space and is willing to share. Show them what you&#8217;ve mapped out and ask them what they think. You will learn a lot about how reasonable your expectations are. Or if you&#8217;re even talking to the right industry to begin with.</p></li><li><p>Map competitive roles in other companies. Your roles will never be an exact match. What matters is not whether they are philosophically the same, but practically what you are competing with for the people you need.</p></li><li><p>Try to hire &amp; retain and adjust as you fail. All this was just to get an approximation. As candidates decline offers and people leave for other jobs, ask them if they are okay sharing what the other offer is like. You&#8217;ll quickly get a sense of how off you are. Sometimes it&#8217;s just a small adjustment to comp to make it competitive. Sometimes you&#8217;ll need to rethink your entire structure. For example, with OGP we found that good cross-functional leaders are exceedingly rare, so I&#8217;m shifting to teams of leaders from different functions instead.</p></li></ol><p>When I first started building a team, learning about different job titles and career frameworks all felt very arcane. Taking this practical approach really helped me demystify things. There&#8217;s no universal &#8220;software engineer,&#8221; or &#8220;senior,&#8221; or even &#8220;critical skills&#8221;. There&#8217;s just the org you want, the roles to run that org, and the competitive market for those roles. Everything else is a contrivance to get to that.OGP is looking for experienced engineers and product managers!</p>]]></content:encoded></item><item><title><![CDATA[When is it a bad idea to promote a good officer?]]></title><description><![CDATA[A good promotion empowers someone to take on more responsibility and feels great for the team.]]></description><link>https://www.lihongyi.com/p/when-is-it-a-bad-idea-to-promote</link><guid isPermaLink="false">https://www.lihongyi.com/p/when-is-it-a-bad-idea-to-promote</guid><dc:creator><![CDATA[Li Hongyi]]></dc:creator><pubDate>Mon, 31 Mar 2025 16:00:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!LWI1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53932784-5d78-4557-9e18-418e651c70f2_800x333.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LWI1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53932784-5d78-4557-9e18-418e651c70f2_800x333.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LWI1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53932784-5d78-4557-9e18-418e651c70f2_800x333.jpeg 424w, https://substackcdn.com/image/fetch/$s_!LWI1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53932784-5d78-4557-9e18-418e651c70f2_800x333.jpeg 848w, https://substackcdn.com/image/fetch/$s_!LWI1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53932784-5d78-4557-9e18-418e651c70f2_800x333.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!LWI1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53932784-5d78-4557-9e18-418e651c70f2_800x333.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LWI1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53932784-5d78-4557-9e18-418e651c70f2_800x333.jpeg" width="800" height="333" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/53932784-5d78-4557-9e18-418e651c70f2_800x333.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:333,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;No alternative text description for this image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="No alternative text description for this image" title="No alternative text description for this image" srcset="https://substackcdn.com/image/fetch/$s_!LWI1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53932784-5d78-4557-9e18-418e651c70f2_800x333.jpeg 424w, https://substackcdn.com/image/fetch/$s_!LWI1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53932784-5d78-4557-9e18-418e651c70f2_800x333.jpeg 848w, https://substackcdn.com/image/fetch/$s_!LWI1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53932784-5d78-4557-9e18-418e651c70f2_800x333.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!LWI1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53932784-5d78-4557-9e18-418e651c70f2_800x333.jpeg 1456w" sizes="100vw" fetchpriority="high"></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>A good promotion empowers someone to take on more responsibility and feels great for the team. A bad promotion can break a team as the person fails to deliver on things people depend on them for. It gets worse long term, as the underperforming officer now sets a bad example for the org. This misguides people who don&#8217;t understand the standards and demoralises the people who do. It&#8217;s not even good for the officer, getting stressed as they struggle while everyone else is frustrated at them.</p><p>At Open Government Products I use a framework to help avoid this. Performance looks back and measures how much impact someone has made, while promotions look forward and estimates how much responsibility they will be able to take. While performance is a key factor, making a good promotion requires looking at several other things too.</p><p>The most common mistake is promoting someone immediately after a period of good performance. Everybody has good years and bad years, and there is a lot of luck that goes into whether a project goes smoothly. Promoting someone too soon sets them up for failure because either their next opportunity isn&#8217;t as good, they&#8217;re missing some key skills, or they just burnout because you promoted them while they were working unsustainably. Whatever the reason, waiting to see if their performance is consistent is the most reliable way of avoiding these problems.</p><p>A common pattern I see is junior officers trying to get promoted by working super hard but not taking the time to develop their skills. While you should recognise them with good performance ratings, promoting them is a mistake. This creates a culture of people working harder and harder until they literally run out of hours in a day, then get stuck barely meeting expectations while quickly burning out. That&#8217;s why it&#8217;s important someone has the right skills and is working sustainably before they get promoted, otherwise you&#8217;re just locking them into a death spiral.</p><p>To reduce the pressure of getting promoted early, at OGP we allocate bonuses so that people with the same performance get the same total compensation, regardless of their level. So if a junior engineer performs at a senior level, his salary + bonus for that year will be the same as a senior engineer&#8217;s. This means there is little downside to just staying lower level and outperforming, only taking on promotions when you&#8217;re really ready for it.</p><p>It&#8217;s impossible to get this exactly right. My philosophy is that it&#8217;s better to have a team of outperfomers than a team of underperformers. The former might be a bit frustrated that they&#8217;re not promoted, but overall they&#8217;re happy they&#8217;re exceeding expectations and working well with each other. On the other hand, the latter is frustrated as they let each other down, while anxiously overworking to try and meet their targets. At OGP we have around 40% of people outperforming and we&#8217;ve managed to get underperformance down to under 5%.</p>]]></content:encoded></item><item><title><![CDATA[Human Rube Goldberg Machines]]></title><description><![CDATA[How can every person in an organization be critical, yet the team as a whole is completely ineffective?]]></description><link>https://www.lihongyi.com/p/human-rube-goldberg-machines</link><guid isPermaLink="false">https://www.lihongyi.com/p/human-rube-goldberg-machines</guid><dc:creator><![CDATA[Li Hongyi]]></dc:creator><pubDate>Wed, 19 Mar 2025 16:00:00 GMT</pubDate><content:encoded><![CDATA[<p>How can every person in an organization be critical, yet the team as a whole is completely ineffective?</p><p>They are all working very hard, are very skilled, and are working together extremely well. You&#8217;ve looked at every single job and you really can&#8217;t remove anyone without the whole team collapsing. Yet costs are high, output is low, and the org as whole is stuck.</p><p>You&#8217;ve probably seen a Rube Goldberg machine before. It&#8217;s those things where a marble knocks over some dominoes that pushes a broom etc etc and long time later the TV is turned on or something. If you removed even a single domino the whole thing would stop working. I think the problem is that we form human Rube Goldberg machines.</p><p>Rube Goldberg machines show you can take an arbitrarily simple task and make it arbitrarily complex. And you can do so while every component of the machine remains critical. The CEO tells the director who tells the team lead who tells the procurement manager who tells the vendor who tells the project manager who tells the developer. It happens horizontally as well, the app team gives requirements to the backend team who puts requests to the infrastructure team who has to clear the security team who has to coordinate with the launch calendar. Working between teams is always necessary, but if you&#8217;re not careful it can quickly become degenerate.</p><p>I don&#8217;t think anyone sets out to build human Rube Goldberg machines. Ironically, I think they&#8217;re the result of optimization efforts at a geological scale. As organizations grow and shrink, any roles that aren&#8217;t on a critical path get cut while jobs attached to critical paths get kept. Overtime, this cycle of deposition and erosion leaves the organizations made up mostly of very long critical chains.</p><p>To fix this, you cannot look at things piece by piece. You will correctly conclude that everything is critical but incorrectly conclude that nothing can be done. You have to know what the objectives of the org are, what the actual efficient flows looks like, and do a larger scale restructuring to get there. Practically, I&#8217;ve found the most effective way to fix a critical chain is not to try and restructure it live, but instead to build a bypass flow and ramp that up while winding down the inefficient one.</p><p>At Open Government Products I try to let the product teams run as independently as possible specifically to minimize Rube Goldberg problems. To be clear, every org structure is going to make some things easy and other things hard. What structure you choose depends on what you&#8217;re trying to do as an organization. The trick is to make the common important things easy, and accept clunkiness on things which are uncommon and less important, but that&#8217;s something I&#8217;ll write more about another time.</p>]]></content:encoded></item><item><title><![CDATA[Don't Feed Weak Teams]]></title><description><![CDATA[You have 2 teams: Team A is doing well and Team B is doing poorly.]]></description><link>https://www.lihongyi.com/p/dont-feed-weak-teams</link><guid isPermaLink="false">https://www.lihongyi.com/p/dont-feed-weak-teams</guid><dc:creator><![CDATA[Li Hongyi]]></dc:creator><pubDate>Sun, 09 Mar 2025 16:00:00 GMT</pubDate><content:encoded><![CDATA[<p>You have 2 teams: Team A is doing well and Team B is doing poorly. Who do you give resources to?</p><p>If you give resources to Team B you get 2 projects delivered instead of 1. Leadership! But now your weaker team is bigger and whatever skills/communication/structural issues there were are made worse. Repeat this a few times and suddenly most of your organization is doing poorly. Even with the best of intentions, you can see how easy it is for organizations to slide into inefficacy</p><p>I think the right response is to give resources to Team A, but also move some of Team B&#8217;s responsibilities over. It seems more complicated, but this grows your strongest teams while giving weaker teams a chance to focus and perform on a smaller scope.</p><p>In the real world it&#8217;s rarely so clear though. Instead Team A will be handling things so smoothly that you don&#8217;t even think about them. While Team B will always be meeting with you and explaining how their challenges are so big it&#8217;s impossible without more resources. Seeing the earnest efforts and plight of Team B, you go take some resources from a quiet team that doesn&#8217;t seem to be doing much, and pass them to Team B.</p><p>To be clear, they&#8217;re not lying. To a lower skilled team with structural issues it really does seem impossible without more resources. Just as I would find it impossible to run a marathon, they&#8217;re being completely honest when they report problems and say more resources are needed.</p><p>This is why I think leaders need domain expertise. Even with completely honest feedback, if you just address the problems as reported you end up growing your lowest performing teams. You need to be able to judge which problems are actually hard, empower your best performers while helping your low performers focus and succeed.</p><p>I think this is probably the much harder problem than choosing which projects to pursue. Get it wrong and your hardest working teams get frustrated you&#8217;re not supporting them. Even if you get it right, people are likely still going to be frustrated with you. But you have to do it otherwise you&#8217;ll face a surreptitious decline of the organization.</p>]]></content:encoded></item><item><title><![CDATA[How to Build Good Software]]></title><description><![CDATA[Why Bad Software Happens to Good People]]></description><link>https://www.lihongyi.com/p/how-to-build-good-software</link><guid isPermaLink="false">https://www.lihongyi.com/p/how-to-build-good-software</guid><dc:creator><![CDATA[Li Hongyi]]></dc:creator><pubDate>Sat, 20 Jul 2019 16:00:00 GMT</pubDate><content:encoded><![CDATA[<h2>Why Bad Software Happens to Good People</h2><p>Bad software is one of the few things in the world you cannot solve with money. Billion dollar airlines have flight search apps that are often inferior to those built by groups of students. Established taxi companies the world over have terrible booking apps despite the threat they face from ride-sharing services. And painful corporate IT systems are usually projects with massive budgets, built over the course of many years. Whatever the cause of bad software is, it does not seem to be a lack of funding.</p><p>Surprisingly, the root cause of bad software has less to do with specific engineering choices, and more to do with how development projects are managed. The worst software projects often proceed in a very particular way: The project owners start out wanting to build a specific solution and never explicitly identify the problem they are trying to solve. They then gather a long list of requirements from a large group of stakeholders. This list is then handed off to a correspondingly large external development team, who get to work building this highly customised piece of software from scratch. Once all the requirements are met, everyone celebrates as the system is launched and the project is declared complete.</p><p>However, though the system technically meets specifications, severe issues are found when it is put in the hands of actual users. It is slow, confusing, and filled with subtle bugs that make using it an exercise in frustration. Unfortunately, by this time the external development team has been dismissed and there are no resources left over to make the necessary fixes. By the time a new project can be initiated years later, all knowledge of what caused these problems has left the organisation and the cycle starts over again.</p><p>The right coding language, system architecture, or interface design will vary wildly from project to project. But there are characteristics particular to software that consistently cause traditional management practices to fail, while allowing small startups to succeed with a shoestring budget: &#8226; Reusing good software is easy; it is what allows you to build good things quickly; &#8226; Software is limited not by the amount of resources put into building it, but by how complex it can get before it breaks down; and &#8226; The main value in software is not the code produced, but the knowledge accumulated by the people who produced it.</p><p>Understanding these characteristics may not guarantee good outcomes, but it does help clarify why so many projects produce bad outcomes. Furthermore, these lead to some core operating principles that can dramatically improve the chances of success:</p><ol><li><p>Start as simple as possible;</p></li><li><p>Seek out problems and iterate; and</p></li><li><p>Hire the best engineers you can.</p></li></ol><p>While there are many subtler factors to consider, these principles form a foundation that lets you get started building good software.</p><h2>Reusing Software Lets You Build Good Things Quickly</h2><p>Software is easy to copy. At a mechanical level, lines of code can literally be copied and pasted onto another computer. More generally, the internet is full of tutorials on how to build different kinds of systems using ready-made code modules that are available online. Modern software is almost never developed from scratch. Even the most innovative applications are built using existing software that has been combined and modified to achieve a new result.</p><p>The biggest source of reusable code modules is the open source community. Open source software is software in which code is freely published for anyone to see and use. Many of the largest contributors to the open source community are giant tech companies. If you want to use a state-of-the-art planet scalable database as Facebook does, just download the code for Cassandra that they open sourced in 2008. If you want to try out Google&#8217;s cutting-edge machine learning for yourself, download the TensorFlow system published in 2015. Using open source code does not just make your application development faster, it gives you access to technology that is far more sophisticated than anything you could have developed yourself. For the most popular open source code, it is even more secure as there are many more people paying attention and fixing vulnerabilities. This is the reason digital technology has made such rapid progress: even the newest engineers can build upon the most advanced tools our profession has to offer.</p><p>The advent of cloud services has taken reusability even further, offering the full use of even proprietary systems for just a subscription fee. Need a simple website? Just configure one in a few clicks using a website building service like Squarespace or Wix. A database? Subscribe to a virtual one from Amazon Web Services or Microsoft Azure. Cloud services allow developers to benefit from specialisation; the service provider handles the setup, maintenance, and continued development of a reliable, high-quality piece of software that is used by all its subscribers. This allows software developers to stop wasting time on solved problems and instead focus on delivering actual value.</p><p>You cannot make technological progress if all your time is spent on rebuilding existing technology. Software engineering is about building automated systems, and one of the first things that gets automated away is routine software engineering work. The point is to understand what the right systems to reuse are, how to customise them to fit your unique requirements, and fixing novel problems discovered along the way.</p><h2>Software Is Limited by Complexity</h2><p>How useful a piece of software can be is usually limited by its complexity rather than the amount of resources invested in building it.</p><p>IT systems are often full of features but are still hated by users because of how confusing they become. In contrast, highly ranked mobile apps tend to be lauded for their simplicity and intuitiveness. Learning to use software is hard. Beyond a point, new features actually make things worse for users because the accumulated complexity starts to become overwhelming. For example, after serving as the hub of Apple&#8217;s media ecosystem for almost 20 years, iTunes was split into three different apps (for music, podcasts, and TV shows) this year, as its features had grown too complex for one app to handle. From a usability perspective, the limit is not how many features can be implemented, but rather what can fit into a simple intuitive interface.</p><p>Even ignoring usability, engineering progress slows to a halt once a project becomes too complex. Each new line of code added to an application has a chance of interacting with every other line. The bigger an application&#8217;s codebase, the more bugs are introduced whenever a new feature is built. Eventually, the rate of work created from new bugs cancels out the rate of work done from feature development. This is known as &#8220;technical debt&#8221; and is the main challenge in professional software development. It is the reason why many large IT systems have issues that go unfixed for years. Adding more engineers to the project just adds to the chaos: they start running faster in place as the codebase keels over from its own weight.</p><p>In such cases, the only way forward is to take a step back to rationalise and simplify the codebase. The system architecture can be redesigned to limit unexpected interactions. Non-critical features can be removed even if they have already been built. Automated tools can be deployed to check for bugs and badly written code. Bill Gates once said &#8220;Measuring programming progress by lines of code is like measuring aircraft building progress by weight&#8221;. Human minds can only handle a finite amount of complexity, so how sophisticated a software system can get depends on how efficiently this complexity budget is used.</p><p>Building good software involves alternating cycles of expanding and reducing complexity. As new features are developed, disorder naturally accumulates in the system. When this messiness starts to cause problems, progress is suspended to spend time cleaning up. This two-step process is necessary because there is no such thing as platonically good engineering: it depends on your needs and the practical problems you encounter. Even a simple user interface such as Google&#8217;s search bar contains a massive amount of complexity under the surface that cannot be perfected in a single iteration. The challenge is managing this cycle, letting it get messy enough to make meaningful progress, but not letting it get so complicated that it becomes overwhelming.</p><h2>Software Is about Developing Knowledge More than Writing Code</h2><p>In software development, most ideas are bad; this is not anyone&#8217;s fault. It is just that the number of possible ideas is so large that any particular idea is probably not going to work, even if it was chosen very carefully and intelligently. To make progress, you need to start with a bunch of bad ideas, discard the worst, and evolve the most promising ones. Apple, a paragon of visionary design, goes through dozens of prototypes before landing on a final product. The final product may be deceptively simple; it is the intricate knowledge of why this particular solution was chosen over its alternatives that allows it to be good.</p><p>This knowledge continues to be important even after the product is built. If a new team takes over the code for an unfamiliar piece of software, the software will soon start to degrade. Operating systems will update, business requirements will change, and security problems will be discovered that need to be fixed. Handling these subtle errors is often harder than building the software in the first place, since it requires intimate knowledge of the system&#8217;s architecture and design principles.</p><p>In the short term, an unfamiliar development team can address these problems with stopgap fixes. Over time though, new bugs accumulate due to the makeshift nature of the additional code. User interfaces become confusing due to mismatched design paradigms, and system complexity increases as a whole. Software should be treated not as a static product, but as a living manifestation of the development team&#8217;s collective understanding.</p><p>This is why relying on external vendors for your core software development is difficult. You may get a running system and its code, but the invaluable knowledge of how it is built and what design choices were made leaves your organisation. This is also why handing a system over to new vendors for &#8220;maintenance&#8221; often causes problems. Even if the system is very well documented, some knowledge is lost every time a new team takes over. Over the years, the system becomes a patchwork of code from many different authors. It becomes harder and harder to keep running; eventually, there is no one left who truly understands how it works.</p><p>For your software to keep working well in the long term, it is important to have your staff learning alongside the external help to retain critical engineering knowledge in your organisation.</p><h2>3 Principles for Good Software Development</h2><h3>Start as Simple as Possible</h3><p>Projects that set out to be a &#8220;one-stop shop&#8221; for a particular domain are often doomed. The reasoning seems sensible enough: What better way to ensure your app solves people&#8217;s problems than by having it address as many as possible? After all, this works for physical stores such as supermarkets. The difference is that while it is relatively easy to add a new item for sale once a physical store is set up, an app with twice as many features is more than twice as hard to build and much harder to use.</p><p>Building good software requires focus: starting with the simplest solution that could solve the problem. A well-made but simplistic app never has problems adding necessary features. But a big IT system that does a lot of things poorly is usually impossible to simplify and fix. Even successful &#8220;do it all&#8221; apps like WeChat, Grab, and Facebook started out with very specific functionality and only expanded after they had secured their place. Software projects rarely fail because they are too small; they fail because they get too big.</p><p>Unfortunately, keeping a project focused is very hard in practice: just gathering the requirements from all stakeholders already creates a huge list of features.</p><p>One way to manage this bloat is by using a priority list. Requirements are all still gathered, but each are tagged according to whether they are absolutely critical features, high-value additions, or nice-to-haves. This creates a much lower-tension planning process because features no longer need to be explicitly excluded. Stakeholders can then more sanely discuss which features are the most important, without worrying about something being left out of the project. This approach also makes explicit the trade-offs of having more features. Stakeholders who want to increase the priority for a feature have to also consider what features they are willing to deprioritise. Teams can start on the most critical objectives, working their way down the list as time and resources allow.</p><p>We followed a similar process for all our most successful apps. Form.gov.sg started out as a manual Outlook Macro that took us six hours to set up for our first user but today has processed about a million public submissions. Data.gov.sg started out as a direct copy of an open source project and has since grown to over 300,000 monthly visits. Parking.sg had a massive list of almost 200 possible features that we never got around to building but still has over 1.1 million users today. These systems are well received not in spite of their simplicity but because of it.</p><h3>Seek Out Problems and Iterate</h3><p>In truth, modern software is so complicated and changes so rapidly that no amount of planning will eliminate all shortcomings. Like writing a good paper, awkward early drafts are necessary to get a feel of what the final paper should be. To build good software, you need to first build bad software, then actively seek out problems to improve on your solution.</p><p>This starts with something as simple as talking to the actual people you are trying to help. The goal is to understand the root problem you want to solve and avoid jumping to a solution based just on preconceived biases. When we first started on Parking.sg, our hypothesis was that enforcement officers found it frustrating to have to keep doing the mental calculations regarding paper coupons. However, after spending just one afternoon with an experienced officer, we discovered that doing these calculations was actually quite simple for someone doing it professionally. That single conversation saved us months of potentially wasted effort and let us refocus our project on helping drivers instead.</p><p>Beware of bureaucratic goals masquerading as problem statements. &#8220;Drivers feel frustrated when dealing with parking coupons&#8221; is a problem. &#8220;We need to build an app for drivers as part of our Ministry Family Digitisation Plans&#8221; is not. &#8220;Users are annoyed at how hard it is to find information on government websites&#8221; is a problem. &#8220;As part of the Digital Government Blueprint, we need to rebuild our websites to conform to the new design service standards&#8221; is not. If our end goal is to make citizens&#8217; lives better, we need to explicitly acknowledge the things that are making their lives worse.</p><p>Having a clear problem statement lets you experimentally test the viability of different solutions that are too hard to determine theoretically. Talking to a chatbot may not be any easier than navigating a website, and users may not want to install yet another app on their phones no matter how secure it makes the country. With software, apparently obvious solutions often have fatal flaws that do not show up until they are put to use. The aim is not yet to build the final product, but to first identify these problems as quickly and as cheaply as possible. Non-functional mock-ups to test interface designs. Semi-functional mock-ups to try different features. Prototype code, written hastily, could help garner feedback more quickly. Anything created at this stage should be treated as disposable. The desired output of this process is not the code written, but a clearer understanding of what the right thing to build is.</p><p>With a good understanding of the right solution, you can start work on building the actual product. You stop exploring new ideas and narrow down to identifying problems with your particular implementation. Begin with a small number of testers who will quickly spot the obvious bugs that need to be fixed. As problems are addressed, you can increasingly open up to a larger pool who will find more esoteric issues.</p><p>Most people only give feedback once. If you start by launching to a large audience, everyone will give you the same obvious feedback and you&#8217;ll have nowhere to go from there. Even the best product ideas built by the best engineers will start out with significant issues. The aim is to repeatedly refine the output, sanding down rough edges until a good product emerges. Even after all this iteration, after launch is when problems with a product matter the most. A problem that happens only 0.1% of the time may not get noticed during testing. But once you have a million users, every day the problem goes unresolved is a thousand more angry people you have to deal with. You need to fix problems caused by new mobile devices, network outages, or security attacks before they cause substantial harm to your users. With Parking.sg we built a series of secondary systems that continuously check the main system for any discrepancies in payments, duplicate parking sessions, and application crashes. Building up an &#8220;immune system&#8221; over time lets you avoid being overwhelmed as new issues inevitably come up.</p><p>Overall, the approach is to use these different feedback loops to efficiently identify problems. Small feedback loops allow for quick and easy correction but miss out on broader issues. Large feedback loops catch broader issues but are slow and expensive. You want to use both, resolving as much as possible with tight loops while still having wide loops to catch unexpected errors. Building software is not about avoiding failure; it is about strategically failing as fast as possible to get the information you need to build something good.</p><h3>Hire the Best Engineers You Can</h3><p>The key to having good engineering is having good engineers. Google, Facebook, Amazon, Netflix, and Microsoft all run a dizzying number of the largest technology systems in the world, yet, they famously have some of the most selective interview processes while still competing fiercely to recruit the strongest candidates. There is a reason that the salaries for even fresh graduates have gone up so much as these companies have grown, and it is not because they enjoy giving away money.</p><p>Both Steve Jobs and Mark Zuckerberg have said that the best engineers are at least 10 times more productive than an average engineer. This is not because good engineers write code 10 times faster. It is because they make better decisions that save 10 times the work.</p><p>A good engineer has a better grasp of existing software they can reuse, thus minimising the parts of the system they have to build from scratch. They have a better grasp of engineering tools, automating away most of the routine aspects of their own job. Automation also means freeing up humans to work on solving unexpected errors, which the best engineers are disproportionately better at. Good engineers themselves design systems that are more robust and easier to understand by others. This has a multiplier effect, letting their colleagues build upon their work much more quickly and reliably. Overall, good engineers are so much more effective not because they produce a lot more code, but because the decisions they make save you from work you did not know could be avoided.</p><p>This also means that small teams of the best engineers can often build things faster than even very large teams of average engineers. They make good use of available open source code and sophisticated cloud services, and offload mundane tasks onto automated testing and other tools, so they can focus on the creative problem-solving aspects of the job. They rapidly test different ideas with users by prioritising key features and cutting out unimportant work. This is the central thesis of the classic book &#8220;The Mythical Man-Month&#8221;1: in general, adding more software engineers does not make a project go faster, it only makes it grow bigger.</p><p>Smaller teams of good engineers will also create fewer bugs and security problems than larger teams of average engineers. Similar to writing an essay, the more authors there are, the more coding styles, assumptions, and quirks there are to reconcile in the final composite product, exposing a greater surface area for potential issues to arise. In contrast, a system built by a smaller team of good engineers will be more concise, coherent, and better understood by its creators. You cannot have security without simplicity, and simplicity is rarely the result of large-scale collaborations.</p><p>The more collaborative an engineering effort, the better the engineers need to be. Problems in an engineer&#8217;s code affect not just his work but that of his colleagues as well. In large projects, bad engineers end up creating more work for one another, as errors and poor design choices snowball to create massive issues. Big projects need to be built on solid reliable code modules in an efficient design with very clear assumptions laid out. The better your engineers, the bigger your system can get before it collapses under its own weight. This is why the most successful tech companies insist on the best talent despite their massive size. The hard limit to system complexity is not the quantity of engineering effort, but its quality.</p><h2>Conclusion</h2><p>Good software development starts with building a clear understanding of the problem you want to solve. This lets you test many possible solutions and converge on a good approach. Development is accelerated by reusing the right open source code and cloud services, granting immediate access to established software systems and sophisticated new technology. The development cycle alternates between exploration and consolidation, quickly and messily progressing on new ideas, then focusing and simplifying to keep the complexity manageable. As the project moves forward, it gets tested with successively larger groups of people to eliminate increasingly uncommon problems. Launching is when the real work ramps up for a good development team: layers of automated systems should be built to handle issues quickly and prevent harm to actual users. Ultimately, while there are infinite intricacies to software development, understanding this process provides a basis to tackle the complexities of how to build good software.</p><p><em>This article was originally written for and published by <a href="https://knowledge.csc.gov.sg/ethos-issue-21/how-to-build-good-software/">Civil Service College Singapore</a></em></p>]]></content:encoded></item></channel></rss>