The Best Worst Hack That Saved Our Bacon
Posted3 months agoActive3 months ago
jeffersonheard.ghost.ioTechstoryHigh profile
calmpositive
Debate
70/100
Software EngineeringDatabase ManagementProblem-Solving
Key topics
Software Engineering
Database Management
Problem-Solving
The post describes a hack that saved a project by using negative integers as IDs when the signed 32-bit integer limit was reached, and the discussion revolves around the implications and potential issues with this approach.
Snapshot generated from the HN discussion
Discussion Activity
Very active discussionFirst comment
4d
Peak period
44
84-96h
Avg / period
21.3
Comment distribution64 data points
Loading chart...
Based on 64 loaded comments
Key moments
- 01Story posted
Oct 1, 2025 at 12:27 PM EDT
3 months ago
Step 01 - 02First comment
Oct 5, 2025 at 3:15 AM EDT
4d after posting
Step 02 - 03Peak activity
44 comments in 84-96h
Hottest window of the conversation
Step 03 - 04Latest activity
Oct 6, 2025 at 11:02 AM EDT
3 months ago
Step 04
Generating AI Summary...
Analyzing up to 500 comments to identify key contributors and discussion patterns
ID: 45439684Type: storyLast synced: 11/20/2025, 6:30:43 PM
Want the full context?
Jump to the original sources
Read the primary article or dive into the live Hacker News thread when you're ready.
a free 68 more years!
(hopefully nobody optimized for the 1 signed bit when allocating memory tho)
The file format is obsolete (it assumes a fixed number of terminal lines per system) and has unfixable locking issues, so it has to be replaced anyway.
Is that really true? I did keep reading the entire piece. I think they're often interesting and can contain nuggets of wisdom or insight. Or sometimes they're just funny. When I meet someone who worked on something interesting, I often start trying to pry stories like this post out of them.
It’s not a hook, it’s bad read-bait.
Introverts hate this one weird trick!
If a client application makes an assumption about this, then their engineers will accept this as being their bad and will fix it.
I'd defend this as being pragmatic - minimising disruption to clients instead of the more 'correct' solution of changing the API. I'm hoping that they managed to roll out the new API update alongside the old one and avoid a 'big bang' API change with this. Sometimes this isn't possible, but it's great when that works out.
This does highlight the fact that 32 bit is just a small number these days. Personally, I prefer UUIDs instead of incrementing integers for primary keys since they also scale out without having to have global coordination, but at least choose a 64-bit number.
I find this significantly reduces decision fatigue. Deciding which hack to use for temporary identifiers is not much fun.
This wrap into negative domain would wreck havoc for sure.
That way you couldn't make them disappear.
On-prem, single company who issued invoices to customers.
When there was an audit the government could ask to see invoices in a certain range. If some of them were missing, what does that mean? Paid under the table?
My wife worked at a place where they did manual PDFs, but there they had a tool to change properties of a PDF to change the creation time / last editing time, for when 'modifications' were needed.
And this reminds me of the other post here where some people assume cash means shady. Definitely the case there.
If you opened boxes in "whatever" order you'd have invoice numbers that would run contiguous for 150 or so counts (the number of forms in the box), then skip to the next multiple of 150 to correspond to when the next (or previous!) box had been used.
TBF using the negative range could also break callers distinguishing between signed and unsigned if they’d used the latter on their side depending how the API was documented.
Honestly I would expect that to break more users code (and in weirder ways) than just changing the type. It's unclear from the story how the type was exposed though.
Like, instead of using negative primary keys, they could have also just have converted to an unsigned int32. I would assume both of those would break a bunch of customer implementations though.
MySQL does have unsigned ints out of the box, FWIW.
That said, to your point, there was almost certainly someone comparing IDs to determine recency, and during the transition from large-positive to large-negative, that would absolutely cause havoc.
I'd be curious if their API spec actually said anywhere that the IDs increased consistently.
Though I guess that likelyhood is influenced by the choice of protocol. For example when using protobuf the client code generated from the specification file will use a 32-bit integer, if that's how it was defined. While in JSON I'd generally assume it's a positive integer smaller than 2^53.
If they expose them as string and mention they're opaque? Then customers who parse them to uint will get bugs and be unhappy.
Did they expose them as ints? Customers who used uints will be unhappy.
At `jobs[-2]` the front-end parsed the ids (exposed as strings, but ints under the cover).
The backend left them alone.
That caused some issues when building out shared libraries.
At that point you’re just blowing up storage for no reason. Just use an int if you’re that sure.
Setting a string length to coincidentally the length of a int serialized to a string while doing no other validation on it is…. Just special.
But 2038 is gonna be awesome!
A few "alter table" commands cascades to an operational PITA.
I think he did a pretty bad job of explaining it if that’s the case though.
A primary key is almost an implementation detail - a key that an API knows about something is one of many things that might point to this thing, might need to change, and generally might need a different representation (so don't make it your primary key.)
I also tell people to just use the bottom of any primary key space (when choosing monotonic stuff) but so many engineers just complain that they dont like the numbers (and yet many of them have had to deal with the migration a few years later so ... enjoy that I guess.)
I ended up decompiling some android APKs our last Unity dev had built like eight months prior. I figured out how to extract our device driver library, then painstakingly rewrote the entire library to support new hardware while also maintaining a compatible ABI and stuffed it all back into the APK. I think I also had to forge some keys or something? It was a fucking mess. Anyway, that was the last work I ever did for him because he didn't pay me for about two months after that, and I quit the moment he gave me the wages he owed me.
He's only got one employee and zero customers, but hey his stupid demo worked for all that mattered.
This is so wrong. I love reading these kinds of stories
I love engineering war stories