Log-log chart: a dotted extrapolation line ending near 10 ms, two measured no-index curves far above it (MariaDB 10.11 at 968 ms and 13.0 at 148 ms at 1M rows), a dashed 300 ms threshold, and a flat under-1 ms line for the indexed case

I Wrote the Index Escalation Threshold as a Number, Then Measured It and Found It Off by 15x to 100x

Somewhere in a design document you have signed off on, there is a sentence of the form “when it passes X, we will do Y.” Has anyone ever generated X rows to check that the number means what it says? At the end of last month I signed off on a design that runs a lookup against a column with no index, on a table my team does not own, and wrote the condition for fixing it as a sentence with two numbers in it: “when the table passes about 1,000,000 rows or the p95 of the voucher filter passes 300 ms, request a non-unique index from the owning team.” The sentence had one job: get the option “ship without the index” through design review, with “we will add it later” turned into something a reviewer could sign. It did that job. ...

September 28, 2026 · 10 min · Hoang Nguyen Thai
A merge commit with two parents, and a third branch feeding one extra line into the resolved file

A Merge Has Exactly Two Parents. The Line From a Third Branch Took Down Every API Route.

For 17 hours and 55 minutes, every route under /api/* on staging answered with a fatal error. The merge that caused it landed at 17:18 one evening; the fix that ended it landed at 11:13 the next morning. That duration is from the private repository and the server log, so you cannot verify it; read it as my account. The merge itself was ordinary: a feature branch into staging, one conflict, in the file that registers HTTP middleware. The conflict was real, both sides had added a line at the same spot. What went wrong was not the conflict. It was how the conflict was “resolved”, and then how the result was checked and declared fine. ...

September 23, 2026 · 7 min · Hoang Nguyen Thai
Two tables with overlapping auto-increment ids, an import file pointing at one and the code reading the other

The Import That Edited the Wrong Row for Years Because Two Tables Shared the Same IDs

An import feature that adjusts campaign quotas from a spreadsheet had been in production for years. Every manual QA pass looked the same: upload a file, open the campaign, see one quota changed, mark the ticket done. Zero automated tests covered the handler. It was editing the wrong row. Not sometimes — structurally, on every run where the two ids happened to line up, and on the staging database they did. The number of production rows it touched over those years is something I have not measured and will not guess at here. What I can show is the mechanism, why three separate safety nets each let it through, and the one test that would have caught it on day one. ...

September 22, 2026 · 7 min · Hoang Nguyen Thai
A SELECT FOR UPDATE statement dissolving into an empty string on the sqlite driver

The Lock I Dropped During a Refactor, and the 1184 Green Tests That Didn't Notice

QA filed a one-line gap: no concurrency tests on the stock pool. I opened the file expecting to write four tests and close it in an afternoon. Instead I found that the lock those tests were supposed to cover was not there anymore. What can go wrong here The system is a promotions backend. Several campaigns draw from one shared stock pool per SKU. Before a campaign can reserve units, a service reads the pool balance, subtracts what is already reserved, and writes an allocation. ...

September 21, 2026 · 6 min · Hoang Nguyen Thai