Calm heads.
Quite stubborn.

We care about the actual cause. Whatever framework is in fashion right now can wait its turn.

Ticket #4711Open

The month-end close takes nine hours.

Until the July update it took twenty minutes.

Reported by
Accounting
Priority
The board is already asking

Five whys.

The case is made up. Unfortunately it isn’t rare. We keep asking until the answer gives us more than “that’s just how it is”.

  1. Database · today

    Why? 1 of 5

    Because the database scans the entire customer table for every invoice. 40,000 times per run.

    The reflex we skip: “We need a bigger server.”

  2. Update · July 2026

    Why? 2 of 5

    Because the index on the customer number has been missing since the July update. Without it, every lookup becomes manual labour.

    The reflex we skip: “Who did this?”

  3. Cleanup script · 2021

    Why? 3 of 5

    Because a cleanup script from 2021 deletes indexes it thinks are duplicates on every update. This time it caught the wrong one.

    The reflex we skip: “The database is too old. We need a new one.”

  4. Data model · since 2016

    Why? 4 of 5

    Because there are two customer tables with identically named indexes: “Customers” and “customers”. The script ignores upper and lower case.

    The reflex we skip: “We’re moving everything to microservices.”

  5. Migration · September 2016

    Why? 5 of 5

    Because someone copied the table “temporarily” during a migration, on a Friday at 5:48 pm. The comment is still there today.

    The reflex we skip: “It’s always been like that.”

Bedrock reached

One index too few.
One table too many.

What we changed

  • Restored the index and measured before and after.
  • Fixed the cleanup script. A test now checks exactly this case.
  • Merged the two tables, with a way back.
  • Wrote it all down so nobody has to dig it up again.

Result

Month-end close
18 minutes
Server
the same one
Rewrite
cancelled

What lies at the bottom.
Four principles.

Every bore ends at the same four statements. We stick to them, especially when things are urgent.

  • The reflex we skip: “We’ll just rewrite it.”

    Understand it before touching it.

    We start with the system you actually have: its limits, the people behind it and the undocumented behaviour everyone quietly relies on. Before we promise anything, we make visible what is still unknown.

    Old code. Does it have to go?
  • The reflex we skip: “Let’s use what everyone else is using.”

    The right tools. Yours included.

    Technology is a means to an end. We choose it by load, team and the expected lifetime of the software. Sometimes the best tool is the one you already know.

  • The reflex we skip: “It already feels faster.”

    Progress you can verify.

    We work with small changes, meaningful tests and trade-offs stated openly. We measure performance against your real load, and we talk about risks while there’s still time to do something about them.

    Faster is not a gut feeling.
  • The reflex we skip: “It’s all in the code.”

    Easier to run than before.

    Readable code, deployments you can follow and documentation that answers questions. The work should keep paying off after the handover.

    Courage is not a rollback.

Project-speak.
Translated.

You’ll hear these sentences in almost every software project. Here is what they usually mean.

“It just grew that way over the years.”
Nobody knows why it’s like this anymore. Nobody wants to touch it either.
“Just a quick fix.”
Nobody checked what else depends on it.
“Works on my machine.”
On exactly one computer. Sadly not the one that matters.
“It’s not a bug, it’s a feature.”
A bug everyone has got used to.
“We’ll clean that up after go-live.”
Nobody will clean that up.
“Our technical debt is under control.”
Your team pays the interest every day, in overtime.

With us, you get the plain version from the start.

Good software makes your working day
pleasantly uneventful.

Send us your ticket