NHacker Next
  • new
  • past
  • show
  • ask
  • show
  • jobs
  • submit
Shopify replaced Redis with MySQL for inventory reservations–and it scaled (shopify.engineering)
manbash 2 hours ago [-]
> Instead of one row per item with a quantity column, we use one row per sellable unit. An item with 10 units has 10 rows.

> But one row per unit for all inventory would break down at scale—an item with 50,000 units across 10 locations would mean 500,000 rows, and the reserve query would slow as it scans through them. Instead, we maintain a bounded pool of available rows, capped at 1,000 per item/location combination. Reservations consume rows from this pool; a replenishment process refills it from the inventory ledger.

Shouldn't I feel uncomfortable with such approach? It seems to create a backoff (pool) for lowering the chance of having a synchronization issue.

sandeepkd 1 hours ago [-]
Comes down to type of items, when you have physical inventory the number is limited so more manageable and interestingly enough the problem only applies to physical inventory.

You are just spending some more disk space to avoid synchronization issues. Denormalization for performance is a really common pattern, just that people do not start with it in the first place itself

jbird99 2 hours ago [-]
I guess it depends on how the replenishment process works. Unless you're ordering over 1000 of an item, I doubt it would be a problem.
isignal 1 hours ago [-]
It seems there could be a simpler solution.

1. Deduct the reservation from the inventory when the user starts to order, but in the same txn also maintain a separate row for the in progress order flow. 2. If the order flow is aborted or times out have a background process that returns these to the inventory.

That seems simpler than this approach and involves no locking. Though their presented approach is also reasonable, there must be some reason not to choose a simpler flow. It is not that difficult to have a gc service that scales, but may be they didn't want to separate that.

firasd 44 minutes ago [-]
My understanding is: your proposal is not very different from what Shopify is doing except they are tracking 'reserved units' (one per row) and you are proposing tracking 'orders' as the temporary state to then reconcile back with inventory quantities.
isignal 22 minutes ago [-]
Yes, at a high level. It doesn't rely on skip locked, which is not cheap at DB level. DB has to still typically run query and keep going until it finds an unlocked item. Deducting and checking inventory counts are simpler ops inside the DB.
soontimes 43 minutes ago [-]
Can you clarify why this involves no locking? There can still be 2 actors fighting for the same row.
isignal 20 minutes ago [-]
Two concurrent deductions of inventory do contend but only during the actual DB update. That is just normal DB locking for SQL isolation levels. The blog refers to explicit locking by the app, which is where skip locked comes in.
sandeepkd 1 hours ago [-]
The moment you added a background process you just replaced the complexity.

1. Backgrounds process can back up

2. They need context of the user and need to switch context per user

3. What if they fail, you create some DLQ or another process to handle the failure

4. Who looks on those failure and how do they act

TLDR; there is always a cost

0x696C6961 34 minutes ago [-]
The design in the shoppify post already had a background process for the item replenishment.
vxxzy 1 hours ago [-]
now you have two problems. what happens when your reservation system backs up?
sieabahlpark 43 minutes ago [-]
[dead]
firasd 1 hours ago [-]
Makes sense... if you are counting something in MySQL and now your counter is in Redis that's already strange

But I guess the point is that even in the MySQL scenario the 'reserved_quantities' is almost like a temporary table so either way is not the 'Real' inventory

srcreigh 26 minutes ago [-]
It’s fascinating that in order to do this, they had to remove 50% of reads and 33% of transactions from the main DB.
zhivota 2 hours ago [-]
"But the hardest lesson wasn't about database design. It was discovering that the real bottleneck wasn’t what we were observing and measuring."
Horffupolde 2 hours ago [-]
But was it load bearing?
ares623 14 minutes ago [-]
load = bearing

gun = smoking

insight = key

gap = closed

summary = executived

CoastalCoder 2 hours ago [-]
Even better.

It's web-scale.

paytonjjones 1 hours ago [-]
It's honestly weird Claude converges on this language because it's incredibly wordy and hard to parse.

One would think semantic density would win out in training.

peyton 59 minutes ago [-]
Who knows. I wish ant harshly penalized speaking litotically because it’s essentially reward hacking as it can often be read multiple ways.

It’s also annoying as a human because Claude et al rate their own writing very highly, putting human<>LLM interactions at a disadvantage to human->LLM<>LLM interactions.

jasonlotito 25 minutes ago [-]
> it's ... hard to parse.

No, it's not. Honestly, the more I see these complaints, I honestly just think people are bad writers and shit readers.

Simply put, if that's hard to parse for you, and you are a native-English speaker, pick up a book for once in your life.

nozzlegear 16 minutes ago [-]
It's not hard to parse, but it's a dense pair of sentences that say nothing. It just pads the length of the article and gives readers mental fatigue trying to read between the lines to figure out what the point is.
jbird99 2 hours ago [-]
The lengths companies will go to avoid running different pieces of software...
anonymars 2 hours ago [-]
It can be easier and cheaper to solve problems via technology changes than operations and people

Now you only need MySQL expertise and maintenance rather than Redis and MySQL

kennywinker 2 hours ago [-]
Shopify’s founder and their coo both fund far-right extremism, and its founder thinks only rich people should be able to vote. But anyway, they switched databases.

https://www.techwontsave.us/episode/340_shopifys_leaders_are...

hdndjsbbs 2 hours ago [-]
Yeah it's an awful place to work unless you're a far-right bro. My old director used to use slurs and vape in the office. The founder hires pro gamers with no technical expertise because he thinks they're cool.
chucksmash 18 minutes ago [-]
Don't get shy now. Which slurs?
derwiki 2 hours ago [-]
Are you implying that vaping is far right?
nozzlegear 8 minutes ago [-]
Sounded to me like they were saying people vape in the office, which would make a bad work environment on top of the far right bros.
kennywinker 2 hours ago [-]
I think that was part of the “bro” bit, not the far right bit
stiltzkin 2 hours ago [-]
[dead]
culi 46 minutes ago [-]
They were really so proud of that AI image that they just had to tack it on at the end? Did nothing but make the blog post feel like cheap mass produced slop
nozzlegear 10 minutes ago [-]
This is Shopify, the leadership is full steam ahead on AI in a big way and they review employee performance based on AI usage.
tayo42 34 minutes ago [-]
The blog probably was.shopify was pretty early and publicly all in on using AI for everything
shay_ker 2 hours ago [-]
outside the slop, i liked this post that was linked on innodb locking: https://jahfer.com/posts/innodb-locks/
tailscaler2026 2 hours ago [-]
[dead]
skullone 2 hours ago [-]
[flagged]
trueno 2 hours ago [-]
so this is interesting to me, im in retail i work closely with platforms ive used shopify ive used magento ive used smaller players ive helped implement various pieces of all of them.

and i was excited to get some insight, then i realized that this whole thing was written by AI and im going to guess the idea and implementation were probably very AI driven.

> The solution: SKIP LOCKED > Core idea: one row per unit, bounded by design

cool, thanks claude.

Now I'm wondering what the engineering culture is even like at shopify.

Here's the thing. I like databases, I think there's a lot of shit in this space that went and smoked a shit ton their own good stuff to come up with these pure event driven designs that lock you into event workflows with no isolation and remove the ability to do broader bulk-functions.. and then do something even stupider and say "all you need for the interface is graphql" and such service/platform doesn't give you any other way to reconcile or do reporting for your org you have to warehouse from graphql.. this is crap. So seeing a headline where shopify says they want to kinda get behind a unified database strat behind the scenes even if it's not necessarily customer facing, like that's good imo. SQL is many decades of relational algebra that makes insane computations acrossed vast sets of data pure magic and one of the best query dml interfaces of all time.

..however i dont even agree with the claim their making here that redis isnt the tech for a reservation system. redis when used correctly feels like an insanely awesome way to do a reservation system, i lurv redis for stuff like that.

I'm just gonna go forward with the assumption that current and future shopify updates are pure vibeslop. I already hate their data interfaces, but compared to other saas offerings i appreciate that they do have bulk-features.

akamaka 2 hours ago [-]
I found Shopify’s post very easy to read, and learned about some features of MySQL. On the other hand, I didn’t get any value from reading your comment. You seem to have a bunch of opinions about how things should be done, but haven’t given any details about how you came to these conclusions.
benmmurphy 2 hours ago [-]
You should be able to do these increments/decrements in a database at the rate you can write WAL to the disk. But the problem is in a lot of these databases the transaction will hold locks until the WAL hits the disk which causes a massive serialisation problem when you have lots of writes to the same row.

For example if it takes 20ms to write a batch to the WAL then if you do 5 updates to the same row then that is a minimum of 100ms. But without waiting on locks if you can batch all the WAL writes together then this could be just 20ms.

I don’t think holding locks while waiting for WAL is strictly necessary. There is definitely some anomalies that can happen if you don’t wait for WAL to be durable because transactions that don’t write WAL can observe non-durable writes in some situations. So for example conditional updates that don’t perform work. But I assume this can be fixed by making these wait on the commit for dependent transactions to become durable if they are empty. There is also the problem of failing writes that reveal information about non-durable writes which is more tricky. For example you try to insert into a unique index and it fails, but the duplicate was due to a non-durable write that is lost.

Pure reads should be fine when using MVCC because you just show the latest durable version of the DB. I know some other replication systems will run all transactions including reads through the WAL/replicated log in order to not have anomalies.

tybit 2 hours ago [-]
They do heavily use AI, but you haven’t refuted their point that if inventory is in SQL, storing reservation in a second storage system increases complexity.
Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact
Rendered at 03:38:44 GMT+0000 (Coordinated Universal Time) with Vercel.