Requirements · Craft

Two Glasses by the Bed

On the value of “wasting” time thinking ahead, against the pull of shipping now. Two real cases, and four reasons not to push every change back onto the client.

July 2026·7 min read

Every joke contains a little joke

How does a programmer go to sleep? He puts two glasses by the bed — one full of water, one empty. Full, in case he wakes up thirsty. Empty, in case he wakes up and isn’t.

It’s an old joke, and like every good one, the funny part is smaller than the true part. A good developer thinks about every possible turn, including the one that isn’t anywhere on the horizon. Across more than two decades of work I’ve watched this prove itself again and again — in my own projects and in other people’s.

And I don’t mean the trivial things: shared functions, reusable classes. Though sadly that isn’t trivial for everyone either — I still meet developers for whom every new form in the UI is born from a copy-paste of the previous one, then edited from the inside until it fits. You know the rest: one small change to the requirements now needs fixing in every single place, and good luck remembering them all.

I mean something else. I mean what happens the moment we sit down with the client.

The request that always arrives mid-build

The client defines the problem. Everything is clear, everything is settled, we can start building.

Wait. Stop. Have you thought about what happens mid-build?

Because it is tried and tested — at some point the phone rings. “Oh, one small thing, I forgot that in this case we also need…”. And from the client’s side it really is small. More than that: had we known upfront, it would have been a few extra minutes of work. But now it’s a change to the structure of the software, and at this stage a change like that is, if not drastic, then at least painful.

Anyone who has worked with clients even a little knows this. Two examples of my own.

“Just one query, something simple”

An internal client at the company asked for a simple visual interface: type in a SQL query, run it against a particular database, show the results, and export them to Excel. Instead of copying and pasting by hand every time.

Showing results in a window is simple — anyone who works with data knows that. The Excel export isn’t complicated either: open the application, a double loop over rows and columns, and the file is ready. You can even add a text box and a button for choosing a folder and file name. Under an hour, styling included.

But this is where the two glasses come in. I thought: she writes requirements, she works with queries all day. Today it’s one query — tomorrow she’ll want two, three, five. Today she only cares about the file name — tomorrow she’ll want sheet names. And the row count, which she insists is “just a few”, could grow enormously.

She, for her part, kept stressing: “No, absolutely not, really not, something quick and simple.”

Instead of an hour, it took me several good days. But here is what came out of it: a DLL component that takes several queries at once, pushes them all into Excel almost instantly and without loops, names the sheets, and runs either visibly — opening the application — or in the background. Later I added a no-interface mode driven from the command line with parameters. That part was easy too, because the internal structure was already set up for it.

The ending? A few weeks later she came back with exactly those requirements, and I got to tell her it already worked. And out of that “simple” request grew, after a few small additions, a project whose second half — the batch-driven run — is in production today on heavy jobs that process large reports several times a month. All of it with minimal adaptation.

The cell that was meant to hold one condition

A smaller example, from a different domain. A private client asked for an Excel sheet that runs some accounting calculations. One of the cells held a conditional — if A then…, otherwise… An IF function solves that in a single line.

Then I looked at the data I had. It wasn’t a dichotomous variable like male/female, but something along the lines of “salary greater than N”.

The conclusion writes itself: sooner or later she’ll ask for more brackets. Who knows how many. And beyond the hassle of adding them — if something goes wrong, good luck debugging this monster:

=IF(salary>x1, action1,
   IF(salary>x2, action2,
      IF(salary>x3, action3, action4)))

And that’s only the beginning. In a case like this the right answer is obviously a salary table with a named range, which she can fill in herself however she likes. More complex to build? Yes. Worth it in the end? Almost always.

“And if it changes — let the client pay”

You can of course be clever about it and say: if a change comes, we’ll bill the client. Let them pay. Ultimately it’s their problem that they didn’t think to mention it earlier. Besides, a developer has to make a living too — and if we hand the client everything upfront, they won’t come back to us.

Possible. But I have four arguments against.

The ethical argument

Most clients don’t understand their own real needs well enough. To many of them a computer is still a strange animal, if not an alien, and they can’t articulate what they want. You, the developer, are supposed to know the space of possibilities and steer them toward what they actually need. Just as we expect a good doctor to think past the story the patient tells, we’re meant to deliver a solution before the client has thought to want it.

The lazy argument

Once you’ve agreed a price, try arguing that the “small thing” they never mentioned now requires a change this large. Impossible? No. But how many of us actually want the fight, the proving, the arguing. Some of us will simply absorb it — and lose both time and money.

The selfish argument

If you thought about it upfront and priced it in, then when the client comes asking, you get to tell them proudly that it’s already done, because you saw it coming. It makes you look like a professional, and it’s a good moment to point out that you saved them money. And if we take the selfish angle all the way — you can charge for what you already anticipated and built, with no extra effort.

The practical argument

Sometimes the project is long closed and you’re deep in something else. Then that client turns up with the change, and sometimes it’s urgent for them. Having seen it coming, you can deliver without disrupting your current project. That is what builds a client who sees you as reliable and professional.

In closing

My not-inconsiderable experience proves it to me over and over: it is worth investing thought in what’s ahead, even when that thought costs us time we can ill afford. In most cases it bears fruit — and not only in the long run.

Back to all articles