Building DIMMsum: a price tracker for used server RAM on eBay Austin's Nerdy Things launched DIMMsum, a free price tracker for used server RAM on eBay that scrapes listings every 6 hours, normalizes titles with an LLM, and charts $/GB with median market lines per speed grade, after the creator bought 30 sticks of 16GB DDR4-3200 RDIMM at the market top in April and encountered ECC errors. The site runs 51 specific queries using Playwright-driven Chromium with randomized delays to avoid eBay's anti-scraping measures, replacing a failed 2024 approach that used requests and free proxies. This project exists because I bought 30 sticks of 16GB DDR4-3200 RDIMM for an EPYC build in early April: an r/homelabsales find at $80 a stick, which was a fair price that day. The problem is that “that day” turned out to be the exact top of the market. Buying the top is pretty standard for me. Then the server wouldn’t POST with at least 4 of the sticks installed, and of the 16 that made it in, 4 more start throwing ECC errors the moment I do anything memory-heavy LLM inferencing, which is of course why I bought them . There are still 6 untested sticks in the box. I knew the going rate; what I couldn’t see was where prices were headed or which sticks would actually work. A price tracker with real sold history fixes at least the first problem. Beyond my own bad luck, the general problem is that eBay search results for server RAM are a mess. “32GB 2x16GB ” is two 16GB sticks, not one 32GB stick. The same 2666 MT/s speed shows up as DDR4-2666, PC4-21300, PC4-2666V, or just “2666V” depending on the seller’s mood. Lots of 8, lots of 32, single sticks, and “FOR PARTS” boards are all mixed together in the same results. Comparing actual price per gigabyte across all of that by hand is miserable. LabGopher https://labgopher.com solved this years ago for whole servers, and I have wanted the RAM equivalent basically forever. So I built it: DIMMsum https://dimmsum.com , a free site that scrapes eBay every 6 hours, normalizes the listing titles with an LLM, and charts everything as $/GB with median market lines per speed grade. Welcome to Austin’s Nerdy Things, where we deploy a browser farm and a language model to avoid doing mental math on eBay listings. My first attempt 2024 was bad This is actually my second run at scraping eBay. Back in 2024 I wrote a requests + BeautifulSoup scraper that pulled search results through free SOCKS proxies from public proxy lists. It mostly worked, in the sense that it is technically still running on an LXC in my basement, appending to a parse.log that is now 636MB. The proxies were garbage free proxies are free for a reason , the regex title parsing was wrong constantly, and I never did anything with the data. Classic. Two things changed since then: eBay got much more aggressive about blocking scrapers, and LLMs got cheap enough to throw at every single listing title. Both of those turned out to matter a lot. eBay does not want to be scraped by robots that look like robots The 2024 approach is completely dead in 2026. Plain HTTP clients like requests do not even get to say hello anymore – eBay identifies them as robots essentially instantly and serves a 403 or the “Pardon Our Interruption” page. My first attempts with an automated browser got generic eBay error pages on search URLs too, while the exact same URLs worked fine by hand. That one had me confused for a while. I am going to spare you the play-by-play here, partly because it would be a bot-evasion cookbook published by a site that participates in eBay’s own affiliate program, which seems unwise. The short version: the fix was embarrassingly simple, and it amounted to using a real browser Playwright driving full Chromium and having it behave like a polite human instead of a robot in a hurry. Take the path a person would take, slow down, keep the footprint small. No proxies, no stealth plugins, one IP, 3-6 second randomized delays between pages, and eBay has been perfectly happy serving me 240 listings per page ever since – a few hundred page loads a day, total. The query matrix or: making the search do half the parsing Instead of one broad “ddr4 rdimm” search, DIMMsum runs 51 very specific queries, one per capacity + speed + module type combo: 32gb 2666,pc4-21300,2666v rdimm -2x16 -4x8 -8x4 The parenthesized part is eBay OR syntax covering the speed synonyms, and the negative terms exclude kit notation so results skew toward true single sticks. The neat part is that each query doubles as a weak label: if a listing was found by the 32GB 2666 RDIMM query but parses out as a 16GB stick, something is off a lot, a mislabel, or a parse bug , and it gets flagged with a little warning icon in the UI instead of silently polluting the chart. LLM title parsing for $0.09 per thousand listings Here is a real title from the database: 2048GB 128x16GB DDR3 PC3L-10600R ECC Reg Server Memory RAM That is 128 sticks of 16GB low-voltage DDR3-1333 RDIMM. My 2024 regex parser had no chance. The domain rules are genuinely fiddly: a PC3L prefix means low voltage, but a trailing L on the PC number PC3-14900L means LRDIMM, and both can appear in the same token. Kit notation states the total first. “LOT” without a count does not mean quantity greater than one. Part numbers are more authoritative than the title text around them. Rather than encoding all that in regex, every title goes through DeepSeek deepseek-v4-flash, their cheap model with a system prompt full of those domain rules, returning structured JSON validated by a pydantic schema: class RamSpec BaseModel : is ram: bool False for trays, heat spreaders, "for parts" boards qty: Optional int lot/kit aware stick count per stick gb: Optional int total gb: Optional int ddr gen: Optional int 3, 4, 5 module type: Optional str RDIMM | LRDIMM | UDIMM | SODIMM speed mts: Optional int PC4-21300 - 2666 ... rank, voltage, ECC, part number Titles are batched 25 per API call with an index round-trip check so a misaligned response fails loudly instead of assigning specs to the wrong listings. Against a hand-labeled fixture set it scored 97.4% field accuracy on the first eval run, and the misses were fields that only existed encoded inside part numbers a future deterministic PN-decode layer will catch those . The economics are the part that still makes me smile. At roughly $0.09 per 1,000 titles, the total LLM bill for parsing every listing DIMMsum has ever seen is about two dollars. This pipeline was not possible on a hobby budget three years ago; now it is basically free. The plumbing Everything lands in Postgres on my Proxmox cluster one VM for the scraper + web app, one for the database . A systemd timer scrapes every 6 hours, and each run records a price snapshot per listing, which means DIMMsum builds its own price history for every item it tracks. The web side is FastAPI plus one vanilla JavaScript file. No framework. The whole site is a scatter chart, a table, and some server-rendered spec pages. Current state of the database after a few days of running: | Metric | Count | |---|---| | RAM listings tracked | 10,697 | | Price snapshots | 104,475 | | Search queries per run | 51 | | Scrape frequency | every 6 hours | | LLM parse cost, lifetime | ~$2 | Claude Fable 5, via Claude Code wrote most of this code with me over a few evenings. The architecture arguments were real arguments and it lost some of them, but I will happily credit it with the claim-column work queue pattern that lets me run parallel parse workers against Postgres without them stepping on each other. Sold prices the part I am most excited about Active listing prices tell you what sellers are asking. Sold prices tell you what buyers actually paid, and those are very different numbers on eBay. I assumed for months that scraping sold/completed listings was off the table and never actually tested it. Turns out the same polite-human browsing approach handles the sold/completed view just fine, and eBay hands you sold prices with dates, 240 per page. I was wrong for months for no reason. Test your assumptions, folks. So as of this week DIMMsum also harvests sold listings weekly into their own table. The first sweep pulled in over 8,000 real sales, and the sold history goes back further than the ~90 days I expected most of the usable volume reaches back to late 2025 . That data is going to power a monthly “state of the used RAM market” report: median $/GB by SKU, month over month, from real transactions. The June data already shows 8GB DDR4-2133 RDIMMs sliding from $3.50/GB in April to $3.12 in June, and that is exactly the kind of thing I want a monthly email about. There is a signup box at the bottom of dimmsum.com https://dimmsum.com for exactly that report. One email a month, actual data, no other nonsense. Disclosure and what’s next The site is monetized with eBay Partner Network affiliate links: if you click through and buy, eBay pays a commission. That is the entire business model. Free site, no ads, no accounts, and the full disclosure lives in the footer. Next up: the monthly sold-price report, a storage version same idea, $/TB for used enterprise SSDs and HDDs, already in progress as a separate project , and a part-number decode table to squeeze out the last few percent of parse accuracy. Go find some cheap RDIMMs at dimmsum.com https://dimmsum.com . My benchmark SKU 32GB DDR4-2666 RDIMM https://dimmsum.com/ddr4/32gb-2666-rdimm singles has a median around $132 a stick right now with the floor meaningfully below that, and now I get to watch the market instead of refreshing eBay searches like an animal.