Cut the cloud bill by 90%
Moved search from an expensive in-memory vector database to PostgreSQL. The archive can now grow far beyond the server’s memory, and each image’s data takes a third of the space it used to.
Case study · SAUERESSIG Group · 2023 → 2026
From a prototype that couldn’t ship to a secure AI platform that customers rely on. Matches lets a print company search years of artwork by picture, and answers one question in seconds: have we made something like this before?
Before → after
Highlights
Moved search from an expensive in-memory vector database to PostgreSQL. The archive can now grow far beyond the server’s memory, and each image’s data takes a third of the space it used to.
It finds the actual design on a crowded print sheet, splits a layout into logos, illustrations and text, and reads text and barcodes. A cut-out of a single logo is enough to find every file that contains it.
For checking wood and stone surfaces, custom computer-vision rules beat the AI model: 7.5 s → 0.6 s per sheet, with no GPU needed. Every flaw also comes back with a name, such as knot, crack or dark mark. Sometimes the best AI decision is to not use AI.
It spots designs that differ by one tiny mark, across the whole archive. Comparing every file pixel by pixel would take hours to days.
See how it works ↓It went from an open port with no login to secure accounts, three user roles and a separate database for every customer. One customer’s search can never reach another customer’s data.
See how it works ↓Setting up a customer system used to mean a long manual checklist. Now it takes one command. Every release builds automatically, and 600+ tests check every endpoint before anything goes out.
Architecture
At the start, one container ran almost everything, and tasks waited in line one after another. Today every layer is split into parts that scale, restart and deploy on their own, and the AI models run in their own GPU services.
Image understanding
An upload isn’t just stored. The system works out what the image contains: where the design is, which text and barcodes are on it, and how it looks as numbers a computer can compare. None of these steps existed at the start.
Pixel-exact search
Two versions of a packaging design can be almost identical: one is missing a tiny technical mark, the other has one extra logo. Matches finds the closest design in the archive and shows exactly what differs, down to a single pixel.
It works across the whole archive and answers in seconds. Comparing every file by hand, or even pixel by pixel by computer, would take hours to days.
Users and access
At the start there was no login: anyone who could reach the server could add, search and delete. Access was built up step by step, from a simple login to secure tokens on every endpoint, then user management with three roles (super admin, tenant admin, user), and finally full separation of customer data.
Tenant admins manage their own users and decide who may edit entries. Every customer gets their own database and search index, so one customer’s query can never reach another customer’s data.
Module map
22 modules in four groups. Pick a group to see what’s inside.
Click a group to open it.
Region of interest
Finds the part of the image that is the actual design. Repeated print sheets are handled by finding the grid, single items by a small trained model.
Element segmentation
Splits one image into its separate graphical elements with the Grounding DINO model, so a logo, an illustration and a legend are each embedded and found on their own.
OCR text
Reads the text on the artwork with Tesseract, per region and at the right rotation. The result feeds the text search.
Barcode reading
Detects and decodes the codes on packaging, so an entry can be found by its code as well as by its picture.
Material check
Sorts a surface design into wood, stone or something else, with a small trained model on top of the image vector. Low and high resolution scans get a model each, because one model does not hold up across both.
Surface regions
Marks the spots on a decor sheet worth a second look and names each one: knot, crack, dark mark, bent grain, patch, edge. Image processing rules written in millimetres, under a second on one processor core. The first version used an AI model and was dropped — ten times slower, and it could not say what it had found.
AI service
Turns an image region into a vector with CLIP, on a graphics card when there is one, and runs Grounding DINO to split an image into its elements. The small trained models all sit on top of those vectors. It is a service of its own with its own queues, so the models load once and the whole thing can be moved to another machine.
PostgreSQL core
One row per image, one per element found in it, and the searchable fields beside them. The picture comparison runs inside the database, so a filter can cut the archive down before anything is compared.
Similarity search
Image in, ranked matches out. Tries four rotations, re-scores on look, texture and optionally colour, and returns the coordinates of the element that matched — so a crop of one element finds the file it belongs to.
Commonality search
Compares several images and shows what they have in common.
Text search
Looks in three places at once: the fields and barcodes in the database, the full text in Solr, and the meaning of the words. So an exact code and a half-remembered description both work, and the three sets of results are put on one scale before they are ranked.
Entry management
Editing, deleting and listing entries, including which fields callers are allowed to change and who changed an entry last.
Authentication
Short-lived access tokens with refresh tokens, checked on every endpoint. Logout revokes the token straight away instead of waiting for it to expire.
Users and roles
Three roles: super admin, tenant admin, user. Tenant admins manage their own users and set the default search settings that new accounts start with.
Editing rights
Editing entries is a permission, not a role. A tenant admin can allow it for some accounts and not others.
Tenant isolation
A database and text index per customer, created when the customer is created. Only a super admin can read across them, and only by asking each one in turn.
Queues and workers
Seven queues: four for the main workers — fast jobs, long jobs, logging and surface work — and three more for the AI services. Each has its own containers and memory limits, so a long upload cannot block a quick search, and AI machines can be added or restarted on their own.
Migration tooling
Moves existing archives between stores and between customers, with progress tracking and the option to rebuild the vectors under new rules.
Installer and updater
A bash script sets up a customer machine from nothing: Docker, the licence container, the monitoring, and all the Matches containers with their settings. The same script updates an installation that already exists, to whichever version is asked for. Setting up or upgrading a machine is now one command and a few answers instead of a long list of manual steps.
Build pipeline
Docker images used to be built by hand. Now one version number, pushed once, starts a GitHub Actions pipeline that builds all six Docker images — API and workers, AI service, search index, queue, cleanup, metrics — each published under that version number, with the protected build shipping the core logic as encrypted libraries behind a hardware licence check. The test suite runs on every push, on every branch.
Monitoring and cleanup
Queue and worker monitoring, metrics for external dashboards, and scheduled cleanup of temporary data and old job results.
Test suite
600+ tests covering every endpoint, including permissions, empty results and error paths. Built to make further changes safe.
Toolkit
Want the full story? I’m happy to walk you through it.
Get in touch →