{
    "archive_path": "archive/1767581688.857638",
    "base_url": "addyosmani.com/blog/21-lessons",
    "basename": "",
    "bookmarked_date": "2026-01-05 02:54",
    "canonical": {
        "archive_org_path": "https://web.archive.org/web/addyosmani.com/blog/21-lessons",
        "dom_path": "output.html",
        "favicon_path": "favicon.ico",
        "git_path": "git/",
        "google_favicon_path": "https://www.google.com/s2/favicons?domain=addyosmani.com",
        "headers_path": "headers.json",
        "htmltotext_path": "htmltotext.txt",
        "index_path": "index.html",
        "media_path": "media/",
        "mercury_path": "mercury/content.html",
        "pdf_path": "output.pdf",
        "readability_path": "readability/content.html",
        "screenshot_path": "screenshot.png",
        "singlefile_path": "singlefile.html",
        "warc_path": "warc/",
        "wget_path": null
    },
    "domain": "addyosmani.com",
    "downloaded_at": "2026-01-05T02:54:56.956987+00:00",
    "downloaded_datestr": "2026-01-05 02:54",
    "extension": "",
    "hash": "1YZDWD4CXDTWDK3HE8KS",
    "history": {
        "archive_org": [
            {
                "cmd": [
                    "/usr/bin/curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--proxy",
                    "socks5://tor-socks-proxy:9150",
                    "--head",
                    "--max-time",
                    "60",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "https://web.archive.org/save/https://addyosmani.com/blog/21-lessons/"
                ],
                "cmd_version": "8.10.1",
                "end_ts": "2026-01-05T02:56:47.429828+00:00",
                "index_texts": null,
                "output": "TimeoutExpired: Command '['/usr/bin/curl', '--silent', '--location', '--compressed', '--proxy', 'socks5://tor-socks-proxy:9150', '--head', '--max-time', '60', '--user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)', 'https://web.archive.org/save/https://addyosmani.com/blog/21-lessons/']' timed out after 60 seconds",
                "pwd": "/data/archive/1767581688.857638",
                "schema": "ArchiveResult",
                "start_ts": "2026-01-05T02:55:47.373834+00:00",
                "status": "failed"
            }
        ],
        "dom": [
            {
                "cmd": [
                    "/usr/bin/chromium-browser",
                    "--proxy-server=socks5://tor-socks-proxy:9150",
                    "--disable-features=DarkMode",
                    "--run-all-compositor-stages-before-draw",
                    "--hide-scrollbars",
                    "--autoplay-policy=no-user-gesture-required",
                    "--no-first-run",
                    "--use-fake-ui-for-media-stream",
                    "--use-fake-device-for-media-stream",
                    "--simulate-outdated-no-au='Tue, 31 Dec 2099 23:59:59 GMT'",
                    "--headless=new",
                    "--no-sandbox",
                    "--no-zygote",
                    "--disable-dev-shm-usage",
                    "--disable-software-rasterizer",
                    "--disable-sync",
                    "--window-size=1440,2000",
                    "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "--user-data-dir=/data/personas/Default/chrome_profile",
                    "--profile-directory=Default",
                    "--dump-dom",
                    "https://addyosmani.com/blog/21-lessons/"
                ],
                "cmd_version": "131.0.6778",
                "end_ts": "2026-01-05T02:55:25.598916+00:00",
                "index_texts": null,
                "output": "output.html",
                "pwd": "/data/archive/1767581688.857638",
                "schema": "ArchiveResult",
                "start_ts": "2026-01-05T02:55:16.550507+00:00",
                "status": "succeeded"
            }
        ],
        "favicon": [
            {
                "cmd": [
                    "/usr/bin/curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--proxy",
                    "socks5://tor-socks-proxy:9150",
                    "--max-time",
                    "60",
                    "--output",
                    "favicon.ico",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "https://www.google.com/s2/favicons?domain=addyosmani.com"
                ],
                "cmd_version": "8.10.1",
                "end_ts": "2026-01-05T02:55:10.396318+00:00",
                "index_texts": null,
                "output": "favicon.ico",
                "pwd": "/data/archive/1767581688.857638",
                "schema": "ArchiveResult",
                "start_ts": "2026-01-05T02:54:57.499974+00:00",
                "status": "succeeded"
            }
        ],
        "git": [],
        "headers": [
            {
                "cmd": [
                    "/usr/bin/curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--proxy",
                    "socks5://tor-socks-proxy:9150",
                    "--head",
                    "--max-time",
                    "60",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "https://addyosmani.com/blog/21-lessons/"
                ],
                "cmd_version": "8.10.1",
                "end_ts": "2026-01-05T02:55:10.498712+00:00",
                "index_texts": null,
                "output": "headers.json",
                "pwd": "/data/archive/1767581688.857638",
                "schema": "ArchiveResult",
                "start_ts": "2026-01-05T02:55:10.441789+00:00",
                "status": "succeeded"
            }
        ],
        "htmltotext": [
            {
                "cmd": [
                    "(internal) archivebox.extractors.htmltotext",
                    "./{singlefile,dom}.html"
                ],
                "cmd_version": "0.8.5rc51",
                "end_ts": "2026-01-05T02:55:39.849010+00:00",
                "index_texts": [
                    "(AddyOsmani.com RSS Feed) (http://addyosmani.com/rss.xml) AddyOsmani.com - 21 Lessons From 14 Years at Google (/assets/images/favicons/apple-touch-icon-57x57.png) (/assets/images/favicons/apple-touch-icon-60x60.png) (/assets/images/favicons/apple-touch-icon-72x72.png) (/assets/images/favicons/apple-touch-icon-76x76.png) (/assets/images/favicons/apple-touch-icon-114x114.png) (/assets/images/favicons/apple-touch-icon-120x120.png) (/assets/images/favicons/apple-touch-icon-144x144.png) (/assets/images/favicons/apple-touch-icon-152x152.png) (/assets/images/favicons/apple-touch-icon-180x180.png) (/assets/images/favicons/favicon-32x32.png) (/assets/images/favicons/android-chrome-192x192.png) (/assets/images/favicons/favicon-96x96.png) (/assets/images/favicons/favicon-16x16.png) (/manifest.json) (/assets/images/favicons/safari-pinned-tab.svg) (/assets/css/style.css) (/assets/css/post-page.css) (/assets/css/highlight.css) (My Blog) (/rss.xml)  (/)  Home  (https://github.com/addyosmani) GitHub  (/press) Press  (/bio) Biography  (https://www.linkedin.com/in/addyosmani/) LinkedIn (https://twitter.com/addyosmani) Twitter  (https://addyo.substack.com) Newsletter (/blog) Blog   21 Lessons From 14 Years at Google January 3, 2026  When I joined Google ~14 years ago, I thought the job was about writing great code. I was partly right. But the longer I\u2019ve stayed, the more I\u2019ve realized that the engineers who thrive aren\u2019t necessarily the best programmers - they\u2019re the ones who\u2019ve figured out how to navigate everything around the code: the people, the politics, the alignment, the ambiguity. These lessons are what I wish I\u2019d known earlier. Some would have saved me months of frustration. Others took years to fully understand. None of them are about specific technologies - those change too fast to matter. They\u2019re about the patterns that keep showing up, project after project, team after team. I\u2019m sharing them because I\u2019ve benefited enormously from engineers who did the same for me. Consider this my attempt to pay it forward. 1. The best engineers are obsessed with solving user problems.  It\u2019s seductive to fall in love with a technology and go looking for places to apply it. I\u2019ve done it. Everyone has. But the engineers who create the most value work backwards: they become obsessed with understanding user problems deeply, and let solutions emerge from that understanding. User obsession means spending time in support tickets, talking to users, watching users struggle, asking \u201cwhy\u201d until you hit bedrock. The engineer who truly understands the problem often finds that the elegant solution is simpler than anyone expected. The engineer who starts with a solution tends to build complexity in search of a justification. 2. Being right is cheap. Getting to right together is the real work.  You can win every technical argument and lose the project. I\u2019ve watched brilliant engineers accrue silent resentment by always being the smartest person in the room. The cost shows up later as \u201cmysterious execution issues\u201d and \u201cstrange resistance.\u201d The skill isn\u2019t being right. It\u2019s entering discussions to align on the problem, creating space for others, and remaining skeptical of your own certainty. Strong opinions, weakly held - not because you lack conviction, but because decisions made under uncertainty shouldn\u2019t be welded to identity. 3. Bias towards action. Ship. You can edit a bad page, but you can\u2019t edit a blank one.  The quest for perfection is paralyzing. I\u2019ve watched engineers spend weeks debating the ideal architecture for something they\u2019ve never built. The perfect solution rarely emerges from thought alone - it emerges from contact with reality. AI can in many ways help here. First do it, then do it right, then do it better. Get the ugly prototype in front of users. Write the messy first draft of the design doc. Ship the MVP that embarrasses you slightly. You\u2019ll learn more from one week of real feedback than a month of theoretical debate. Momentum creates clarity. Analysis paralysis creates nothing. 4. Clarity is seniority. Cleverness is overhead.  The instinct to write clever code is almost universal among engineers. It feels like proof of competence. But software engineering is what happens when you add time and other programmers. In that environment, clarity isn\u2019t a style preference - it\u2019s operational risk reduction. Your code is a strategy memo to strangers who will maintain it at 2am during an outage. Optimize for their comprehension, not your elegance. The senior engineers I respect most have learned to trade cleverness for clarity, every time. 5. Novelty is a loan you repay in outages, hiring, and cognitive overhead.  Treat your technology choices like an organization with a small \u201cinnovation token\u201d budget. Spend one each time you adopt something materially non-standard. You can\u2019t afford many. The punchline isn\u2019t \u201cnever innovate.\u201d It\u2019s \u201cinnovate only where you\u2019re uniquely paid to innovate.\u201d Everything else should default to boring, because boring has known failure modes. The \u201cbest tool for the job\u201d is often the \u201cleast-worst tool across many jobs\u201d-because operating a zoo becomes the real tax. 6. Your code doesn\u2019t advocate for you. People do.  Early in my career, I believed great work would speak for itself. I was wrong. Code sits silently in a repository. Your manager mentions you in a meeting, or they don\u2019t. A peer recommends you for a project, or someone else. In large organizations, decisions get made in meetings you\u2019re not invited to, using summaries you didn\u2019t write, by people who have five minutes and twelve priorities. If no one can articulate your impact when you\u2019re not in the room, your impact is effectively optional. This isn\u2019t strictly about self-promotion. It\u2019s about making the value chain legible to everyone- including yourself. 7. The best code is the code you never had to write.  We celebrate creation in engineering culture. Nobody gets promoted for deleting code, even though deletion often improves a system more than addition. Every line of code you don\u2019t write is a line you never have to debug, maintain, or explain. Before you build, exhaust the question: \u201cWhat would happen if we just\u2026 didn\u2019t?\u201d Sometimes the answer is \u201cnothing bad,\u201d and that\u2019s your solution. The problem isn\u2019t that engineers can\u2019t write code or use AI to do so. It\u2019s that we\u2019re so good at writing it that we forget to ask whether we should. 8. At scale, even your bugs have users.  With enough users, every observable behavior becomes a dependency - regardless of what you promised. Someone is scraping your API, automating your quirks, caching your bugs. This creates a career-level insight: you can\u2019t treat compatibility work as \u201cmaintenance\u201d and new features as \u201creal work.\u201d Compatibility is product. Design your deprecations as migrations with time, tooling, and empathy. Most \u201cAPI design\u201d is actually \u201cAPI retirement.\u201d 9. Most \u201cslow\u201d teams are actually misaligned teams.  When a project drags, the instinct is to blame execution: people aren\u2019t working hard enough, the technology is wrong, there aren\u2019t enough engineers. Usually none of that is the real problem. In large companies, teams are your unit of concurrency, but coordination costs grow geometrically as teams multiply. Most slowness is actually alignment failure - people building the wrong things, or the right things in incompatible ways. Senior engineers spend more time clarifying direction, interfaces, and priorities than \u201cwriting code faster\u201d because that\u2019s where the actual bottleneck lives. 10. Focus on what you can control. Ignore what you can\u2019t.  In a large company, countless variables are outside your control - organizational changes, management decisions, market shifts, product pivots. Dwelling on these creates anxiety without agency. The engineers who stay sane and effective zero in on their sphere of influence. You can\u2019t control whether a reorg happens. You can control the quality of your work, how you respond, and what you learn. When faced with uncertainty, break problems into pieces and identify the specific actions available to you. This isn\u2019t passive acceptance but it is strategic focus. Energy spent on what you can\u2019t change is energy stolen from what you can. 11. Abstractions don\u2019t remove complexity. They move it to the day you\u2019re on call.  Every abstraction is a bet that you won\u2019t need to understand what\u2019s underneath. Sometimes you win that bet. But something always leaks, and when it does, you need to know what you\u2019re standing on. Senior engineers keep learning \u201clower level\u201d things even as stacks get higher. Not out of nostalgia, but out of respect for the moment when the abstraction fails and you\u2019re alone with the system at 3am. Use your stack. But keep a working model of its underlying failure modes. 12. Writing forces clarity. The fastest way to learn something better is to try teaching it.  Writing forces clarity. When I explain a concept to others - in a doc, a talk, a code review comment, even just chatting with AI - I discover the gaps in my own understanding. The act of making something legible to someone else makes it more legible to me. This doesn\u2019t mean that you\u2019re going to learn how to be a surgeon by teaching it, but the premise still holds largely true in the software engineering domain. This isn\u2019t just about being generous with knowledge. It\u2019s a selfish learning hack. If you think you understand something, try to explain it simply. The places where you stumble are the places where your understanding is shallow. Teaching is debugging your own mental models. 13. The work that makes other work possible is priceless - and invisible.  Glue work - documentation, onboarding, cross-team coordination, process improvement - is vital. But if you do it unconsciously, it can stall your technical trajectory and burn you out. The trap is doing it as \u201chelpfulness\u201d rather than treating it as deliberate, bounded, visible impact. Timebox it. Rotate it. Turn it into artifacts: docs, templates, automation. And make it legible as impact, not as personality trait. Priceless and invisible is a dangerous combination for your career. 14. If you win every debate, you\u2019re probably accumulating silent resistance.  I\u2019ve learned to be suspicious of my own certainty. When I \u201cwin\u201d too easily, something is usually wrong. People stop fighting you not because you\u2019ve convinced them, but because they\u2019ve given up trying - and they\u2019ll express that disagreement in execution, not meetings. Real alignment takes longer. You have to actually understand other perspectives, incorporate feedback, and sometimes change your mind publicly. The short-term feeling of being right is worth much less than the long-term reality of building things with willing collaborators. 15. When a measure becomes a target, it stops measuring.  Every metric you expose to management will eventually be gamed. Not through malice, but because humans optimize for what\u2019s measured. If you track lines of code, you\u2019ll get more lines. If you track velocity, you\u2019ll get inflated estimates. The senior move: respond to every metric request with a pair. One for speed. One for quality or risk. Then insist on interpreting trends, not worshiping thresholds. The goal is insight, not surveillance. 16. Admitting what you don\u2019t know creates more safety than pretending you do.  Senior engineers who say \u201cI don\u2019t know\u201d aren\u2019t showing weakness - they\u2019re creating permission. When a leader admits uncertainty, it signals that the room is safe for others to do the same. The alternative is a culture where everyone pretends to understand and problems stay hidden until they explode. I\u2019ve seen teams where the most senior person never admitted confusion, and I\u2019ve seen the damage. Questions don\u2019t get asked. Assumptions don\u2019t get challenged. Junior engineers stay silent because they assume everyone else gets it. Model curiosity, and you get a team that actually learns. 17. Your network outlasts every job you\u2019ll ever have.  Early in my career, I focused on the work and neglected networking. In hindsight, this was a mistake. Colleagues who invested in relationships - inside and outside the company - reaped benefits for decades. They heard about opportunities first, could build bridges faster, got recommended for roles, and co-founded ventures with people they\u2019d built trust with over years. Your job isn\u2019t forever, but your network is. Approach it with curiosity and generosity, not transactional hustle. When the time comes to move on, it\u2019s often relationships that open the door. 18. Most performance wins come from removing work, not adding cleverness.  When systems get slow, the instinct is to add: caching layers, parallel processing, smarter algorithms. Sometimes that\u2019s right. But I\u2019ve seen more performance wins from asking \u201cwhat are we computing that we don\u2019t need?\u201d Deleting unnecessary work is almost always more impactful than doing necessary work faster. The fastest code is code that never runs. Before you optimize, question whether the work should exist at all. 19. Process exists to reduce uncertainty, not to create paper trails.  The best process makes coordination easier and failures cheaper. The worst process is bureaucratic theater - it exists not to help but to assign blame when things go wrong. If you can\u2019t explain how a process reduces risk or increases clarity, it\u2019s probably just overhead. And if people are spending more time documenting their work than doing it, something has gone deeply wrong. 20. Eventually, time becomes worth more than money. Act accordingly.  Early in your career, you trade time for money - and that\u2019s fine. But at some point, the calculus inverts. You start to realize that time is the non-renewable resource. I\u2019ve watched senior engineers burn out chasing the next promo level, optimizing for a few more percentage points of compensation. Some of them got it. Most of them wondered, afterward, if it was worth what they gave up. The answer isn\u2019t \u201cdon\u2019t work hard.\u201d It\u2019s \u201cknow what you\u2019re trading, and make the trade deliberately.\u201d 21. There are no shortcuts, but there is compounding.  Expertise comes from deliberate practice - pushing slightly beyond your current skill, reflecting, repeating. For years. There\u2019s no condensed version. But here\u2019s the hopeful part: learning compounds when it creates new options, not just new trivia. Write - not for engagement, but for clarity. Build reusable primitives. Collect scar tissue into playbooks. The engineer who treats their career as compound interest, not lottery tickets, tends to end up much further ahead. A final thought  Twenty-one lessons sounds like a lot, but they really come down to a few core ideas: stay curious, stay humble, and remember that the work is always about people - the users you\u2019re building for and the teammates you\u2019re building with. A career in engineering is long enough to make plenty of mistakes and still come out ahead. The engineers I admire most aren\u2019t the ones who got everything right - they\u2019re the ones who learned from what went wrong, shared what they discovered, and kept showing up. If you\u2019re early in your journey, know that it gets richer with time. If you\u2019re deep into it, I hope some of these resonate.    (http://twitter.com/addyosmani) Addy Osmani is a Software Engineer at Google working on Chrome and AI.   (https://twitter.com/intent/tweet?text=https://addyosmani.com/blog/21-lessons/ - 21 Lessons From 14 Years at Google by @addyosmani) Tweet  Share   Want more? Subscribe to my free newsletter: (example@gmail.com) () Subscribe         "
                ],
                "output": "htmltotext.txt",
                "pwd": "/data/archive/1767581688.857638",
                "schema": "ArchiveResult",
                "start_ts": "2026-01-05T02:55:39.819368+00:00",
                "status": "succeeded"
            }
        ],
        "media": [
            {
                "cmd": [
                    "/usr/local/bin/yt-dlp",
                    "--restrict-filenames",
                    "--trim-filenames",
                    "128",
                    "--write-description",
                    "--write-info-json",
                    "--write-annotations",
                    "--write-thumbnail",
                    "--no-call-home",
                    "--write-sub",
                    "--write-auto-subs",
                    "--convert-subs=srt",
                    "--yes-playlist",
                    "--continue",
                    "--no-abort-on-error",
                    "--ignore-errors",
                    "--geo-bypass",
                    "--add-metadata",
                    "--format=(bv*+ba/b)[filesize<=750m][filesize_approx<=?750m]/(bv*+ba/b)",
                    "--skip-download",
                    "--cache-dir=/data/yt-dlp-cache/",
                    "--cookies=/data/yt-dlp-cache/cookies.txt",
                    "--proxy=socks5://tor-socks-proxy:9150",
                    "--no-playlist",
                    "https://addyosmani.com/blog/21-lessons/"
                ],
                "cmd_version": "2024.10.7",
                "end_ts": "2026-01-05T02:55:47.326404+00:00",
                "index_texts": [],
                "output": "media/",
                "pwd": "/data/archive/1767581688.857638",
                "schema": "ArchiveResult",
                "start_ts": "2026-01-05T02:55:42.276894+00:00",
                "status": "succeeded"
            }
        ],
        "mercury": [
            {
                "cmd": [
                    "/home/archivebox/.npm/bin/postlight-parser",
                    "https://addyosmani.com/blog/21-lessons/"
                ],
                "cmd_version": "2.2.3",
                "end_ts": "2026-01-05T02:55:39.786205+00:00",
                "index_texts": null,
                "output": "mercury/",
                "pwd": "/data/archive/1767581688.857638",
                "schema": "ArchiveResult",
                "start_ts": "2026-01-05T02:55:36.591832+00:00",
                "status": "succeeded"
            }
        ],
        "pdf": [],
        "readability": [
            {
                "cmd": [
                    "/home/archivebox/.npm/bin/readability-extractor",
                    "/tmp/tmprsy2y1sy",
                    "https://addyosmani.com/blog/21-lessons/"
                ],
                "cmd_version": "0.0.11",
                "end_ts": "2026-01-05T02:55:28.747564+00:00",
                "index_texts": [
                    "When I joined Google ~14 years ago, I thought the job was about writing great code. I was partly right. But the longer I\u2019ve stayed, the more I\u2019ve realized that the engineers who thrive aren\u2019t necessarily the best programmers - they\u2019re the ones who\u2019ve figured out how to navigate everything around the code: the people, the politics, the alignment, the ambiguity.\n\nThese lessons are what I wish I\u2019d known earlier. Some would have saved me months of frustration. Others took years to fully understand. None of them are about specific technologies - those change too fast to matter. They\u2019re about the patterns that keep showing up, project after project, team after team.\n\nI\u2019m sharing them because I\u2019ve benefited enormously from engineers who did the same for me. Consider this my attempt to pay it forward.\n\n1. The best engineers are obsessed with solving user problems.\n\nIt\u2019s seductive to fall in love with a technology and go looking for places to apply it. I\u2019ve done it. Everyone has. But the engineers who create the most value work backwards: they become obsessed with understanding user problems deeply, and let solutions emerge from that understanding.\n\nUser obsession means spending time in support tickets, talking to users, watching users struggle, asking \u201cwhy\u201d until you hit bedrock. The engineer who truly understands the problem often finds that the elegant solution is simpler than anyone expected.\n\nThe engineer who starts with a solution tends to build complexity in search of a justification.\n\n2. Being right is cheap. Getting to right together is the real work.\n\nYou can win every technical argument and lose the project. I\u2019ve watched brilliant engineers accrue silent resentment by always being the smartest person in the room. The cost shows up later as \u201cmysterious execution issues\u201d and \u201cstrange resistance.\u201d\n\nThe skill isn\u2019t being right. It\u2019s entering discussions to align on the problem, creating space for others, and remaining skeptical of your own certainty.\n\nStrong opinions, weakly held - not because you lack conviction, but because decisions made under uncertainty shouldn\u2019t be welded to identity.\n\n3. Bias towards action. Ship. You can edit a bad page, but you can\u2019t edit a blank one.\n\nThe quest for perfection is paralyzing. I\u2019ve watched engineers spend weeks debating the ideal architecture for something they\u2019ve never built. The perfect solution rarely emerges from thought alone - it emerges from contact with reality. AI can in many ways help here.\n\nFirst do it, then do it right, then do it better. Get the ugly prototype in front of users. Write the messy first draft of the design doc. Ship the MVP that embarrasses you slightly. You\u2019ll learn more from one week of real feedback than a month of theoretical debate.\n\nMomentum creates clarity. Analysis paralysis creates nothing.\n\n4. Clarity is seniority. Cleverness is overhead.\n\nThe instinct to write clever code is almost universal among engineers. It feels like proof of competence.\n\nBut software engineering is what happens when you add time and other programmers. In that environment, clarity isn\u2019t a style preference - it\u2019s operational risk reduction.\n\nYour code is a strategy memo to strangers who will maintain it at 2am during an outage. Optimize for their comprehension, not your elegance. The senior engineers I respect most have learned to trade cleverness for clarity, every time.\n\n5. Novelty is a loan you repay in outages, hiring, and cognitive overhead.\n\nTreat your technology choices like an organization with a small \u201cinnovation token\u201d budget. Spend one each time you adopt something materially non-standard. You can\u2019t afford many.\n\nThe punchline isn\u2019t \u201cnever innovate.\u201d It\u2019s \u201cinnovate only where you\u2019re uniquely paid to innovate.\u201d Everything else should default to boring, because boring has known failure modes.\n\nThe \u201cbest tool for the job\u201d is often the \u201cleast-worst tool across many jobs\u201d-because operating a zoo becomes the real tax.\n\n\n\n6. Your code doesn\u2019t advocate for you. People do.\n\nEarly in my career, I believed great work would speak for itself. I was wrong. Code sits silently in a repository. Your manager mentions you in a meeting, or they don\u2019t. A peer recommends you for a project, or someone else.\n\nIn large organizations, decisions get made in meetings you\u2019re not invited to, using summaries you didn\u2019t write, by people who have five minutes and twelve priorities. If no one can articulate your impact when you\u2019re not in the room, your impact is effectively optional.\n\nThis isn\u2019t strictly about self-promotion. It\u2019s about making the value chain legible to everyone- including yourself.\n\n7. The best code is the code you never had to write.\n\nWe celebrate creation in engineering culture. Nobody gets promoted for deleting code, even though deletion often improves a system more than addition. Every line of code you don\u2019t write is a line you never have to debug, maintain, or explain.\n\nBefore you build, exhaust the question: \u201cWhat would happen if we just\u2026 didn\u2019t?\u201d Sometimes the answer is \u201cnothing bad,\u201d and that\u2019s your solution.\n\nThe problem isn\u2019t that engineers can\u2019t write code or use AI to do so. It\u2019s that we\u2019re so good at writing it that we forget to ask whether we should.\n\n\n\n8. At scale, even your bugs have users.\n\nWith enough users, every observable behavior becomes a dependency - regardless of what you promised. Someone is scraping your API, automating your quirks, caching your bugs.\n\nThis creates a career-level insight: you can\u2019t treat compatibility work as \u201cmaintenance\u201d and new features as \u201creal work.\u201d Compatibility is product.\n\nDesign your deprecations as migrations with time, tooling, and empathy. Most \u201cAPI design\u201d is actually \u201cAPI retirement.\u201d\n\n9. Most \u201cslow\u201d teams are actually misaligned teams.\n\nWhen a project drags, the instinct is to blame execution: people aren\u2019t working hard enough, the technology is wrong, there aren\u2019t enough engineers. Usually none of that is the real problem.\n\nIn large companies, teams are your unit of concurrency, but coordination costs grow geometrically as teams multiply. Most slowness is actually alignment failure - people building the wrong things, or the right things in incompatible ways.\n\nSenior engineers spend more time clarifying direction, interfaces, and priorities than \u201cwriting code faster\u201d because that\u2019s where the actual bottleneck lives.\n\n10. Focus on what you can control. Ignore what you can\u2019t.\n\nIn a large company, countless variables are outside your control - organizational changes, management decisions, market shifts, product pivots. Dwelling on these creates anxiety without agency.\n\nThe engineers who stay sane and effective zero in on their sphere of influence. You can\u2019t control whether a reorg happens. You can control the quality of your work, how you respond, and what you learn. When faced with uncertainty, break problems into pieces and identify the specific actions available to you.\n\nThis isn\u2019t passive acceptance but it is strategic focus. Energy spent on what you can\u2019t change is energy stolen from what you can.\n\n11. Abstractions don\u2019t remove complexity. They move it to the day you\u2019re on call.\n\nEvery abstraction is a bet that you won\u2019t need to understand what\u2019s underneath. Sometimes you win that bet. But something always leaks, and when it does, you need to know what you\u2019re standing on.\n\nSenior engineers keep learning \u201clower level\u201d things even as stacks get higher. Not out of nostalgia, but out of respect for the moment when the abstraction fails and you\u2019re alone with the system at 3am. Use your stack.\n\nBut keep a working model of its underlying failure modes.\n\n12. Writing forces clarity. The fastest way to learn something better is to try teaching it.\n\nWriting forces clarity. When I explain a concept to others - in a doc, a talk, a code review comment, even just chatting with AI - I discover the gaps in my own understanding. The act of making something legible to someone else makes it more legible to me.\n\nThis doesn\u2019t mean that you\u2019re going to learn how to be a surgeon by teaching it, but the premise still holds largely true in the software engineering domain.\n\nThis isn\u2019t just about being generous with knowledge. It\u2019s a selfish learning hack. If you think you understand something, try to explain it simply. The places where you stumble are the places where your understanding is shallow.\n\nTeaching is debugging your own mental models.\n\n13. The work that makes other work possible is priceless - and invisible.\n\nGlue work - documentation, onboarding, cross-team coordination, process improvement - is vital. But if you do it unconsciously, it can stall your technical trajectory and burn you out. The trap is doing it as \u201chelpfulness\u201d rather than treating it as deliberate, bounded, visible impact.\n\nTimebox it. Rotate it. Turn it into artifacts: docs, templates, automation. And make it legible as impact, not as personality trait.\n\nPriceless and invisible is a dangerous combination for your career.\n\n14. If you win every debate, you\u2019re probably accumulating silent resistance.\n\nI\u2019ve learned to be suspicious of my own certainty. When I \u201cwin\u201d too easily, something is usually wrong. People stop fighting you not because you\u2019ve convinced them, but because they\u2019ve given up trying - and they\u2019ll express that disagreement in execution, not meetings.\n\nReal alignment takes longer. You have to actually understand other perspectives, incorporate feedback, and sometimes change your mind publicly.\n\nThe short-term feeling of being right is worth much less than the long-term reality of building things with willing collaborators.\n\n15. When a measure becomes a target, it stops measuring.\n\nEvery metric you expose to management will eventually be gamed. Not through malice, but because humans optimize for what\u2019s measured.\n\nIf you track lines of code, you\u2019ll get more lines. If you track velocity, you\u2019ll get inflated estimates.\n\nThe senior move: respond to every metric request with a pair. One for speed. One for quality or risk. Then insist on interpreting trends, not worshiping thresholds. The goal is insight, not surveillance.\n\n16. Admitting what you don\u2019t know creates more safety than pretending you do.\n\nSenior engineers who say \u201cI don\u2019t know\u201d aren\u2019t showing weakness - they\u2019re creating permission. When a leader admits uncertainty, it signals that the room is safe for others to do the same. The alternative is a culture where everyone pretends to understand and problems stay hidden until they explode.\n\nI\u2019ve seen teams where the most senior person never admitted confusion, and I\u2019ve seen the damage. Questions don\u2019t get asked. Assumptions don\u2019t get challenged. Junior engineers stay silent because they assume everyone else gets it.\n\nModel curiosity, and you get a team that actually learns.\n\n17. Your network outlasts every job you\u2019ll ever have.\n\nEarly in my career, I focused on the work and neglected networking. In hindsight, this was a mistake. Colleagues who invested in relationships - inside and outside the company - reaped benefits for decades.\n\nThey heard about opportunities first, could build bridges faster, got recommended for roles, and co-founded ventures with people they\u2019d built trust with over years.\n\nYour job isn\u2019t forever, but your network is. Approach it with curiosity and generosity, not transactional hustle.\n\nWhen the time comes to move on, it\u2019s often relationships that open the door.\n\n18. Most performance wins come from removing work, not adding cleverness.\n\nWhen systems get slow, the instinct is to add: caching layers, parallel processing, smarter algorithms. Sometimes that\u2019s right. But I\u2019ve seen more performance wins from asking \u201cwhat are we computing that we don\u2019t need?\u201d\n\nDeleting unnecessary work is almost always more impactful than doing necessary work faster. The fastest code is code that never runs.\n\nBefore you optimize, question whether the work should exist at all.\n\n19. Process exists to reduce uncertainty, not to create paper trails.\n\nThe best process makes coordination easier and failures cheaper. The worst process is bureaucratic theater - it exists not to help but to assign blame when things go wrong.\n\nIf you can\u2019t explain how a process reduces risk or increases clarity, it\u2019s probably just overhead.\n\nAnd if people are spending more time documenting their work than doing it, something has gone deeply wrong.\n\n20. Eventually, time becomes worth more than money. Act accordingly.\n\nEarly in your career, you trade time for money - and that\u2019s fine. But at some point, the calculus inverts. You start to realize that time is the non-renewable resource.\n\nI\u2019ve watched senior engineers burn out chasing the next promo level, optimizing for a few more percentage points of compensation. Some of them got it. Most of them wondered, afterward, if it was worth what they gave up.\n\nThe answer isn\u2019t \u201cdon\u2019t work hard.\u201d It\u2019s \u201cknow what you\u2019re trading, and make the trade deliberately.\u201d\n\n21. There are no shortcuts, but there is compounding.\n\nExpertise comes from deliberate practice - pushing slightly beyond your current skill, reflecting, repeating. For years. There\u2019s no condensed version.\n\nBut here\u2019s the hopeful part: learning compounds when it creates new options, not just new trivia. Write - not for engagement, but for clarity. Build reusable primitives. Collect scar tissue into playbooks.\n\nThe engineer who treats their career as compound interest, not lottery tickets, tends to end up much further ahead.\n\nA final thought\n\nTwenty-one lessons sounds like a lot, but they really come down to a few core ideas: stay curious, stay humble, and remember that the work is always about people - the users you\u2019re building for and the teammates you\u2019re building with.\n\nA career in engineering is long enough to make plenty of mistakes and still come out ahead. The engineers I admire most aren\u2019t the ones who got everything right - they\u2019re the ones who learned from what went wrong, shared what they discovered, and kept showing up.\n\nIf you\u2019re early in your journey, know that it gets richer with time. If you\u2019re deep into it, I hope some of these resonate."
                ],
                "output": "readability/",
                "pwd": "/data/archive/1767581688.857638",
                "schema": "ArchiveResult",
                "start_ts": "2026-01-05T02:55:26.458973+00:00",
                "status": "succeeded"
            }
        ],
        "screenshot": [],
        "singlefile": [],
        "title": [
            {
                "cmd": [
                    "/usr/bin/curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--proxy",
                    "socks5://tor-socks-proxy:9150",
                    "--max-time",
                    "60",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "https://addyosmani.com/blog/21-lessons/"
                ],
                "cmd_version": "8.10.1",
                "end_ts": "2026-01-05T02:55:25.690059+00:00",
                "index_texts": null,
                "output": "AddyOsmani.com - 21 Lessons From 14 Years at Google",
                "pwd": "/data/archive/1767581688.857638",
                "schema": "ArchiveResult",
                "start_ts": "2026-01-05T02:55:25.671908+00:00",
                "status": "succeeded"
            }
        ],
        "wget": []
    },
    "icons": null,
    "is_archived": true,
    "is_static": false,
    "latest": {
        "archive_org": "TimeoutExpired: Command '['/usr/bin/curl', '--silent', '--location', '--compressed', '--proxy', 'socks5://tor-socks-proxy:9150', '--head', '--max-time', '60', '--user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)', 'https://web.archive.org/save/https://addyosmani.com/blog/21-lessons/']' timed out after 60 seconds",
        "dom": "output.html",
        "favicon": "favicon.ico",
        "git": null,
        "media": "media/",
        "pdf": null,
        "screenshot": null,
        "singlefile": null,
        "title": "AddyOsmani.com - 21 Lessons From 14 Years at Google",
        "warc": null,
        "wget": null
    },
    "link_dir": "/data/archive/1767581688.857638",
    "newest_archive_date": "2026-01-05T02:55:47.373834+00:00",
    "num_failures": 1,
    "num_outputs": 8,
    "oldest_archive_date": "2026-01-05T02:54:57.499974+00:00",
    "path": "/blog/21-lessons/",
    "schema": "Link",
    "scheme": "https",
    "snapshot_abid": "snp_01KE6189DKBF5C359C01D5MT8S",
    "snapshot_id": "bc063600-cef8-46d4-b8e7-fa871a5a6919",
    "sources": [
        "/data/sources/1767581688-import.txt"
    ],
    "tags": null,
    "tags_str": "",
    "timestamp": "1767581688.857638",
    "title": "AddyOsmani.com - 21 Lessons From 14 Years at Google",
    "url": "https://addyosmani.com/blog/21-lessons/"
}