All work
Live Grocery price comparison

besparro: the cheapest basket across 13 Dutch supermarkets

A grocery price comparison I designed, built and run on my own, from the nightly data pipeline to the optimiser that splits your list across stores.

Role
Solo founder and engineer
Year
2026 — now
Stack
NestJS · PostgreSQL · pgvector
Link
besparro.com ↗
besparro search results for olijfolie: 240 products with live prices compared across Dutch supermarkets
01

The problem

Dutch shoppers choose between more than a dozen supermarket chains, each with its own prices, promotions and product names. Working out where a whole shopping list is cheapest means checking every chain by hand.

02

What I did

I built the product end to end and run it alone. Three parts carry it:

Pipeline Nightly ETL

Refreshes ~150k listings from 13 chains every night into PostgreSQL. Price history is written only when a price or promotion changes.

Matching Layered matching

Barcodes (EAN) match 67.5%; synthetic keys, pgvector embeddings and an LLM handle the rest. Only 2.4% are matched by hand.

Product Basket optimiser

Takes a shopping list and finds the cheapest way to fill it across stores.

Matching is the hard part: every chain names and sizes the same product differently. Barcodes settle most of it, so the embedding and LLM tiers only decide the products a barcode can't link.

03

The result

128k+ products tracked across 13 chains
16.9k products matched across 2+ chains
90% of nightly store crawls healthy, last 30 nights

Splitting a basket across up to three stores saves 4–9% in simulation. With the app's default of €3 per extra stop, a typical 20-item basket comes out about 4.4% cheaper.

Those are upper bounds: the simulation assumes perfect picks and ignores pack sizes and promotions.

04

What I'd do next

Measure match precision. I record how every product was matched, but not yet how often a match is wrong.

Harden the weakest crawler. Albert Heijn causes most failed runs; fewer of them means more nights with every store fresh.

Track real savings. Logging baskets compared would let me report what users actually save, not a simulation.

Visit site More work All projects
Top