An unexpected find that freed 20GB of unused index space (2021)
hakibenita.com
hakibenita.com
sounds incredibly cheap
My own company struggles with that - throwing more storage on the live db is easy, so we've kept doing that for years, but pushing around multi-terabyte backups is getting cumbersome and we're going to have to slim down the data in prod even at the cost of engineer effort.
20TB (~18GB usable) drive is $370 + whatever power it will use
6 of them in RAID6 will give you 72TB backup storage, add extra copy and say extra drive as spare and that's 13*370 = $4810 USD for ~5 years + whatever power it will use, ~50-55W if idling most of the time and just writing backup once a day
I think people got completely disconnected from how it actually costs to run something because of vastly higher resell value of storage and bandwidth in the cloud.
> My own company struggles with that - throwing more storage on the live db is easy, so we've kept doing that for years, but pushing around multi-terabyte backups is getting cumbersome and we're going to have to slim down the data in prod even at the cost of engineer effort.
...but that's definitely a bigger part of that issue, cloud or not. Backup is slow, restore is slow, anything that involves any of the two is also slow
Anyway Segate Exos SAS 20TB drive is $409, you can re-do math for "true enterprise" grade hardware. "Enterprise" drive from SAN vendor will be a normal hard drive with some bits in firmware changed so SAN can reject non-SAN-vendor rebrands. They die just the same, we had stacks of them to prove it.
Hell, some of our Intel enterprise NVMes died suspiciously quickly compared to other but that might be a fluke...
SAN Flash controllers are hideously expensive because they need to push tens/hundreds worth of SSDs to tens of servers.
If you can solve redundancy other way (say via pair of replicated databases), a pair of servers with local storage will be far more $ effective
I know the corporate idea of "everything on SAN, nothing outside of SAN" very well, it's just plainly solving political problems, not techncial ones.
One major benefit that SAN-backed database storage provides us is, when combined with VMs, enables us to spin up another database instance against already existing data in the SAN (i.e. a staging DB that looks at prod data).
Engineering hours: there's a good chance you pay for that once, and that solves the problem.
10 SSDs: will require rack space, electricity, PCIe slots, timely replacement, management software... most of these expenses will be recurring expenses. If done once, sometimes the existing infrastructure can amortize these expenses (i.e. you might have already had empty space in a rack, you might have already had spare PCIe slots, etc.), but amortization will only work in small numbers.
Another aspect of this trade-off: systems inevitably lose performance per unit of equipment as they grow due to management expenses and increased latency. So, if you keep solving problems by growing the system, overall, the system will become more and more "sluggish" until it becomes unserviceable.
On the other hand, solutions which minimize the number of system resources necessary to accomplish a task increase overall performance per unit. In other words, create a higher-quality system, which is an asset in its own right.
> 10 SSDs: will require rack space, electricity, PCIe slots, timely replacement, management software... most of these expenses will be recurring expenses. If done once, sometimes the existing infrastructure can amortize these expenses (i.e. you might have already had empty space in a rack, you might have already had spare PCIe slots, etc.), but amortization will only work in small numbers.
10NVMe SSDs fit into 1U.
The cloud always comes out terrible on hardware. The cloud is not selling hardware, it's terrible to buy any hardware in cloud, it sells spike capacity, and it sells software running on it.
There are many services in cloud that would be a lot of work to create (even if you need just small part of functionality) on-site but if you don't use it and just need to throw raw hardware at the problem consistently, a rack with hardware will be far cheaper solution even after incurring the engineering cost to deploy and automate it.
We have 7 racks and time to manage hardware is some minuscule fraction, and time to manage automation on it is still small part of our time, and we're just ops team of 3.
Why $1000 for four hours?
Does it cost your company $150,000 per month per engineer?
$1000 doesn't buy you 800GB more of the RAM that your server likely takes, which is likely to run $3-6/GB ($3 for uncertified, $6 for motherboard manufacturer certified RAM), plus $0.50-$1/GB for the DIMM slots over and above your baseline RAM config.
It can still sometimes be smart to "throw hardware at it", but I don't think you can go from 128 GB of RAM today to 1 TB of RAM tomorrow for $1K in most cases.
In my proximity I don't know anyone who is doing any sort of Engineering work, be it dev/sysadmin/ML/datascience/whatever. I'm so astonished by the numbers of 250$/hour of fulltime job (consulting likely a different story).
I'm very much curious, what kind of Engineering role that could be, in which industry/country/company, if you can name a few and/or share some other info.
I know good SREs (fancy sysadmin plus some devops, but with more class) on the scale from around $120k/yr up to about $300k/yr. This is in the USA. Everyone I know started in SF but since the COVID diaspora, they are all around the US now.
$250/hr estimate -> $125/hr salary -> roughly $250k/yr
My estimate might have been a big high, but really what I'm trying to drive home is that people are almost always more expensive than hardware.
I have to wonder if B-tree de-duplication would have helped with that particular case? The PostgreSQL 13 documentation seems to imply it, as far as I can tell[0] (under 63.4.2):
> B-Tree deduplication is just as effective with “duplicates” that contain a NULL value, even though NULL values are never equal to each other according to the = member of any B-Tree operator class.
I don't think it would be as effective as a partial index as applied in the post, I'm just curious.
[0]: https://www.postgresql.org/docs/13/btree-implementation.html
One minor "word to the wise", cause I thought this was a great post but also has the potential to be misused: if you work at a startup or early stage company, it is nearly always the better decision to throw more disk space at a storage problem like this than worry about optimizing for size. Developers are expensive, disk space is cheap.
This is great advice. In general at the beginning it is better to keep things as simple as possible.
At one fast growing startup I worked at, one of the founders insisted we kept upgrading just one machine (plus redundancy and backups). It was a great strategy! Kept the architecture super simple, easy to manage, easy to debug and recover. For the first 5 years of the company, the whole thing ran on one server, while growing exponentially and serving millions of users globally.
After seeing that, it’s clear to me you should only upgrade when needed, and in the simplest, most straightforward way possible.
Using a partial index where it’s obviously matches the use case (like when a majority of values are null) is just correct modeling and should not be considered a premature optimization or waste or developer time.
Again, for a startup or early stage company, spending developer time on read and write performance is almost certainly a waste. (Obviously if it's bad enough to be a blocker then fix it, but if it's bad enough to be a blocker then you've noticed it already).
https://github.com/NikolayS/postgres_dba
I managed to free 10% a.k.a about 100 GB of storage by reorganizing table column ordering in a big table.
A contributing factor for the huge index I think was the distribution of data. It's had inserts, updates and deletes continuously since 2015. Data is more likely to be deleted the older it gets so there's more data from recent years, but about 0.1% of the data is still from 2015. I think maybe this skewed distribution with a very long tail meant vacuum had a harder time dealing with that index bloat.
An unexpected find that freed 20GB of unused index space in PostgreSQL - https://news.ycombinator.com/item?id=25988871 - Feb 2021 (78 comments)
Indexes have log(n) insertion time per record. If you had 1000 records in your test database, as you approach 65k your insertion time goes up by 60% (2^10 vs 2^16 records). Success slows everything down, and there are only so many server upgrades available.
Add a couple new indexes for obscure features the business was looking for, and now you're up to double.
I manage plenty of DBs with hundreds of millions of records and 40+ indexes per table/collection...
Doing binary search over a b-tree page is <100 cycles. b-tree traversal over 100M records should still be measured in microseconds and binary search over that should be in microseconds too if not in 100s of nanoseconds.
At the beginning it’s rarely noticeable, but it does exist and under heavy load or with a lot of index writes needing to happen it can cause very noticeable overhead.
Given that you’ve included the log(b) claim I thought you were referring to a normally functioning btree.
A situation where 65k rows end up slowing down things severely should have more to do with other database features (foreign keys and similar).
Insert my rant on the stupidity of non-reflexively-equal nulls here.