Joel on Software gave a better illustration of this a while back in talking about the dangers of multitasking; he said imagine that you have no task-switching penalties but have to perform two tasks A and B which are in theory 100 units of time each. If you perform them serially, you get the result for A at time 100 and the result for B at time 200; if you perform them in parallel switching between them, you get the benefit that at time 51 you can show both of the recipients that you are 25% complete, but you deliver A at time 199 and B at time 200. B gets the same result; A gets a strictly better result, by not multitasking. If you imagine that your reputation is proportional to the average of the inverses of your times-to-completion, your reputation is 50% better in the first case due to the 100% improvement on half of your deadlines; if you had done the same nonsense with three parallel tasks your reputation would be 83% better or so.

With that said it seems, I don’t know, like something is missing? Throughput in these project-engineering contexts is little more than the plural of latency; improving latency usually works to improve throughput. So it would be nice to figure out what the actually-perpendicular vector is, given that these two so often go hand-in-hand.

I'd then want to think about situations where you could up-front invest in building a clean piece of software that is dynamic and highly-adaptable later (big wait, then lots of features can be delivered faster) vs. a clunker that was slapped together ad-hoc in order to immediately meet business needs, and it shows (immediate results but every new feature takes longer and longer).

Between the two of those I have a personality which favors the first; in one of my early programming jobs I had a lot of trouble being thrown into the tail end of a system built for years according to the second principle, and so every little change took weeks to debug because everything was spaghetti—I got a bit burned. On the flip-side, the second is in some sense Objectively Correct—lower latencies are really powerful—and I started to adopt some serious principles from that.

So with new internal tools for example, I have some baseline principles which speak to the second vision. A new tool starts without CI/CD, it starts without a database or data persistence, it has a repository but it does not have a release process or code reviews; it starts without extraneous design or styles or templates; usually it starts without tests although in theory I like test-driven development. When I say minimum viable product, I mean that word minimum and I am somewhat loose on that word viable. If there is supposed to be communication with a hypothetical API, that API does not exist and instead there is a file containing some functions which return static JSON blobs that it might have hypothetically tossed back in response. It is a frontend-first design that has no backend.

And I keep negotiating what this product is with my stakeholders, until that frontend has been massaged into something that they can use. Low latency in learning what my tool-consumer wants is key, so I can't be making it expensive to change my data model or the like. I want the complaints that “This tool is extremely useful, I wish it looked pretty and saved my info from session to session and had the latest data from our HR system” and whatever else it needs to do to actually be properly viable.

I think that what I am doing is some variant of Domain-Driven Design? Basically I am trying to suss out major product requirements from nontechnical folks by having them interact with the product requirements as early as possible, to see what those requirements imply and correct them again and again. I want to have a technical model of how they look at the world which is correct, first—and then when I am building the backend I can actually have a properly principled approach to what I am building because I know what the terms mean in this system.