{"course":{"slug":"how-software-changed","title":"How Software Development Changed","url":"https://addaly.com/learn/how-software-changed","level":"intermediate","track":"work"},"lesson":{"slug":"what-stays-worth-learning","title":"The layer that does not get cheaper","url":"https://addaly.com/learn/how-software-changed/what-stays-worth-learning","position":63,"of":87,"minutes":10,"answer":"Invest study time where a wrong answer fails silently or late, because loud immediate failures are corrected by the loop itself while silent ones need a person who already knows.","keyIdea":"Invest study time where a wrong answer fails silently or late, because loud immediate failures are corrected by the loop itself while silent ones need a person who already knows."},"body":{"format":"markdown","text":"## The selection rule\n\nPeople ask which skills survive. The useful version of the question is narrower: **where is the feedback loop broken?**\n\nWhen generated code is wrong in a way that fails immediately and loudly, you do not need to know much. You run it, it throws, you ask again. The cost of not knowing is one iteration.\n\nWhen generated code is wrong in a way that is silent, delayed, or only visible under load, you need to know, because nothing in the loop will tell you. That is the selection rule. The durable skills are the ones whose absence produces silence.\n\n## Data modelling and invariants\n\nA schema is a set of promises about what can never be true. `NOT NULL` promises absence is impossible. A foreign key promises no orphan. A unique constraint promises no duplicate. Get these right and a whole category of bug becomes unrepresentable; get them wrong and the data rots quietly for two years and then someone runs a report.\n\nA generator will produce a plausible schema. It cannot know that in your business a customer can have two active subscriptions during a migration window, or that the legacy import has rows with a blank email that you are contractually obliged to keep. These facts are not in any training corpus. They are in a conversation somebody had in 2021.\n\nThe failure is silent and arrives years later, which is exactly the shape the rule selects for.\n\n## Concurrency and time\n\nRaces do not throw. They produce a wrong number, occasionally, under load, on the days that matter.\n\nWhat to actually hold:\n\n- **At-least-once means duplicates.** Every queue and every retry delivers twice sometimes. If the handler is not idempotent, you have a double charge waiting for a bad afternoon.\n- **Retries amplify.** A service that retries three times turns a partial outage into a full one. Exponential backoff with jitter exists because synchronised retries are a thundering herd.\n- **Clocks lie.** They go backwards over NTP corrections, they differ between machines, and `now()` in two places is two different times.\n- **A timeout is a decision, not a safety net.** No timeout means a hung thread forever; a timeout shorter than the work means you retry work that is still running.\n\n## Failure and operations\n\nThe generated version of a network call almost always assumes success and handles the exception. What it does not do is decide what the system should do when a dependency is up but slow, which is the failure mode that actually takes services down. Circuit breakers, bulkheads, backpressure, load shedding: these are choices about behaviour under partial failure, and they follow from what your business can tolerate.\n\n## Reading instruments\n\nThe strongest single investment is the ability to read the outputs the machine cannot fake.\n\n```sql\nEXPLAIN (ANALYZE, BUFFERS) SELECT ... ;\n```\n\nThat tells you whether the index was used, how far the estimate was from reality, and where the time went. A sequential scan on ten rows in development and on forty million in production is the same query and a different outage.\n\nSame family: a flame graph from `perf` or `py-spy`, a `tcpdump` capture, a heap dump, `EXPLAIN` on a Mongo aggregation, the GC log. Each one is a direct measurement rather than an opinion. All of these tools are free and open source and run on any laptop.\n\n## Numbers to hold in your head\n\nJeff Dean's latency table, in the shape worth memorising: an L1 cache reference is about a nanosecond. Main memory is about a hundred. A random read from a good SSD is on the order of tens of microseconds. A round trip inside a data centre is around half a millisecond. London to California and back is about 150 milliseconds and cannot be improved, because it is the speed of light in glass.\n\nWhy this matters: these ratios let you reject a proposed design in ten seconds without measuring. Anything that says \"we will do a network call per row\" is dead on arrival for a million rows, and you know that from arithmetic.\n\n## What this is not\n\nThis is not a claim that syntax no longer matters. You cannot review what you cannot read, and you cannot read a language you do not know. It is a claim about where marginal study time pays now.\n\nAnd be honest about the shape of the advice: this is a reasoned selection, not a measured one. Nobody has ranked skills by future value with data, and anyone presenting such a ranking is selling a course. The rule (invest where the failure is silent) is defensible. The specific list is a starting point, and your system will have its own silences."},"check":{"question":"Why does the \"invest where failure is silent\" rule put data modelling above framework syntax?","options":[{"text":"Schemas change less often than frameworks, so knowledge of them depreciates more slowly.","correct":false,"tempting":"True but irrelevant to the rule, which is about feedback speed rather than the shelf life of the knowledge."},{"text":"A wrong framework call throws on the first run; a wrong invariant rots quietly for years.","correct":true},{"text":"Models are trained on less database code than application code, so their schema output is weaker.","correct":false,"tempting":"Assumes a data-volume explanation, but the rule holds even where the model's schema output is strong."},{"text":"Database work requires mathematical reasoning that generation cannot perform.","correct":false,"tempting":"Overstates the difficulty; normalisation is routine, and the hard part is business facts that are in nobody's corpus."}]},"prev":{"slug":"the-competence-illusion","title":"A five-minute test for whether you understood it","url":"https://addaly.com/learn/how-software-changed/the-competence-illusion"},"next":{"slug":"practising-with-the-answer-available","title":"Practising when the answer is one keystroke away","url":"https://addaly.com/learn/how-software-changed/practising-with-the-answer-available"},"authorship":"Founder and series editor: Dr Mustafa Mun. Written by AI models to a written standard. Exam keys checked blind by a second model: 3,665 of 3,666 agreed. Academic review invited.","review":{"status":"Draft, open for academic review"},"cite":"Addaly (2026) 'The layer that does not get cheaper', in How Software Development Changed. Edited by M. Mun. Addaly. Available at: https://addaly.com/learn/how-software-changed/what-stays-worth-learning (Accessed: 13 October 2026).","licence":{"name":"CC BY-NC-SA 4.0","url":"https://creativecommons.org/licenses/by-nc-sa/4.0/"},"reader":{"schema":1,"title":"The layer that does not get cheaper","courseTitle":"How Software Development Changed","module":{"index":7,"slug":"skill-and-the-missing-rung","title":"Skill, hiring and the missing rung"},"answer":null,"keyIdea":"Invest study time where a wrong answer fails silently or late, because loud immediate failures are corrected by the loop itself while silent ones need a person who already knows.","hero":{"kind":"plate","image":null,"alt":null,"caption":null},"blocks":[{"t":"h2","id":"the-selection-rule","runs":[{"text":"The selection rule"}]},{"t":"p","runs":[{"text":"People ask which skills survive. The useful version of the question is narrower: "},{"text":"where is the feedback loop broken?","b":true}]},{"t":"p","runs":[{"text":"When generated code is wrong in a way that fails immediately and loudly, you do not need to know much. You run it, it throws, you ask again. The cost of not knowing is one iteration."}]},{"t":"p","runs":[{"text":"When generated code is wrong in a way that is silent, delayed, or only visible under load, you need to know, because nothing in the loop will tell you. That is the selection rule. The durable skills are the ones whose absence produces silence."}]},{"t":"h2","id":"data-modelling-and-invariants","runs":[{"text":"Data modelling and invariants"}]},{"t":"p","runs":[{"text":"A schema is a set of promises about what can never be true. "},{"text":"NOT NULL","code":true},{"text":" promises absence is impossible. A foreign key promises no orphan. A unique constraint promises no duplicate. Get these right and a whole category of bug becomes unrepresentable; get them wrong and the data rots quietly for two years and then someone runs a report."}]},{"t":"p","runs":[{"text":"A generator will produce a plausible schema. It cannot know that in your business a customer can have two active subscriptions during a migration window, or that the legacy import has rows with a blank email that you are contractually obliged to keep. These facts are not in any training corpus. They are in a conversation somebody had in 2021."}]},{"t":"p","runs":[{"text":"The failure is silent and arrives years later, which is exactly the shape the rule selects for."}]},{"t":"h2","id":"concurrency-and-time","runs":[{"text":"Concurrency and time"}]},{"t":"p","runs":[{"text":"Races do not throw. They produce a wrong number, occasionally, under load, on the days that matter."}]},{"t":"p","runs":[{"text":"What to actually hold:"}]},{"t":"ul","items":[[{"text":"At-least-once means duplicates.","b":true},{"text":" Every queue and every retry delivers twice sometimes. If the handler is not idempotent, you have a double charge waiting for a bad afternoon."}],[{"text":"Retries amplify.","b":true},{"text":" A service that retries three times turns a partial outage into a full one. Exponential backoff with jitter exists because synchronised retries are a thundering herd."}],[{"text":"Clocks lie.","b":true},{"text":" They go backwards over NTP corrections, they differ between machines, and "},{"text":"now()","code":true},{"text":" in two places is two different times."}],[{"text":"A timeout is a decision, not a safety net.","b":true},{"text":" No timeout means a hung thread forever; a timeout shorter than the work means you retry work that is still running."}]]},{"t":"h2","id":"failure-and-operations","runs":[{"text":"Failure and operations"}]},{"t":"p","runs":[{"text":"The generated version of a network call almost always assumes success and handles the exception. What it does not do is decide what the system should do when a dependency is up but slow, which is the failure mode that actually takes services down. Circuit breakers, bulkheads, backpressure, load shedding: these are choices about behaviour under partial failure, and they follow from what your business can tolerate."}]},{"t":"h2","id":"reading-instruments","runs":[{"text":"Reading instruments"}]},{"t":"p","runs":[{"text":"The strongest single investment is the ability to read the outputs the machine cannot fake."}]},{"t":"code","lang":"sql","label":"SQL","text":"EXPLAIN (ANALYZE, BUFFERS) SELECT ... ;"},{"t":"p","runs":[{"text":"That tells you whether the index was used, how far the estimate was from reality, and where the time went. A sequential scan on ten rows in development and on forty million in production is the same query and a different outage."}]},{"t":"p","runs":[{"text":"Same family: a flame graph from "},{"text":"perf","code":true},{"text":" or "},{"text":"py-spy","code":true},{"text":", a "},{"text":"tcpdump","code":true},{"text":" capture, a heap dump, "},{"text":"EXPLAIN","code":true},{"text":" on a Mongo aggregation, the GC log. Each one is a direct measurement rather than an opinion. All of these tools are free and open source and run on any laptop."}]},{"t":"h2","id":"numbers-to-hold-in-your-head","runs":[{"text":"Numbers to hold in your head"}]},{"t":"p","runs":[{"text":"Jeff Dean’s latency table, in the shape worth memorising: an L1 cache reference is about a nanosecond. Main memory is about a hundred. A random read from a good SSD is on the order of tens of microseconds. A round trip inside a data centre is around half a millisecond. London to California and back is about 150 milliseconds and cannot be improved, because it is the speed of light in glass."}]},{"t":"p","runs":[{"text":"Why this matters: these ratios let you reject a proposed design in ten seconds without measuring. Anything that says “we will do a network call per row” is dead on arrival for a million rows, and you know that from arithmetic."}]},{"t":"h2","id":"what-this-is-not","runs":[{"text":"What this is not"}]},{"t":"p","runs":[{"text":"This is not a claim that syntax no longer matters. You cannot review what you cannot read, and you cannot read a language you do not know. It is a claim about where marginal study time pays now."}]},{"t":"p","runs":[{"text":"And be honest about the shape of the advice: this is a reasoned selection, not a measured one. Nobody has ranked skills by future value with data, and anyone presenting such a ranking is selling a course. The rule (invest where the failure is silent) is defensible. The specific list is a starting point, and your system will have its own silences."}]}],"check":{"question":[{"text":"Why does the “invest where failure is silent” rule put data modelling above framework syntax?"}],"options":[{"text":[{"text":"Schemas change less often than frameworks, so knowledge of them depreciates more slowly."}],"correct":false,"tempting":[{"text":"True but irrelevant to the rule, which is about feedback speed rather than the shelf life of the knowledge."}]},{"text":[{"text":"A wrong framework call throws on the first run; a wrong invariant rots quietly for years."}],"correct":true,"tempting":null},{"text":[{"text":"Models are trained on less database code than application code, so their schema output is weaker."}],"correct":false,"tempting":[{"text":"Assumes a data-volume explanation, but the rule holds even where the model’s schema output is strong."}]},{"text":[{"text":"Database work requires mathematical reasoning that generation cannot perform."}],"correct":false,"tempting":[{"text":"Overstates the difficulty; normalisation is routine, and the hard part is business facts that are in nobody’s corpus."}]}],"order":[2,3,0,1],"why":null},"prev":{"slug":"the-competence-illusion","title":"A five-minute test for whether you understood it","minutes":9},"next":{"slug":"practising-with-the-answer-available","title":"Practising when the answer is one keystroke away","minutes":9}}}