Selected workOYSTER / ENGINEERING CASE STUDY

FULL STACK × APPLIED AI

Engineering the system
around the model.

Finding relevant products, keeping generated routines consistent, and checking what reaches the user.

Oyster turns skin-analysis results into product recommendations and morning-and-evening skincare routines.

MY WORK
Skin analysis & recommendations.
JSON-to-pgvector search migration.
WHAT CHANGED
Faster search. Room to consider more candidates.
FROM CONSTRAINT TO DELIVERY

The improvement had to reach the routine.

After a skin scan, a person needs a routine drawn from products the catalog can actually offer. Search determines what the generator has to work with.

  1. The bottleneck

    Comparing vectors in PHP was slow and hit memory limits. A small candidate pool kept the work manageable, but narrowed the products available to the generator.

  2. My decision

    I moved ranking into PostgreSQL with pgvector, then checked whether routine generation used the new search path. Its old candidate limit still constrained what the faster search could consider.

  3. What changed

    Search became faster and could consider more candidates. That gave routine generation a wider pool to work with; recommendation quality still needed separate evaluation.

FOUR DECISIONS / ONE SYSTEM
01 / 04

Search limits become product limits.

Search supplies the products used to generate a routine. If it considers too few, a useful option may never reach the model.

IN OYSTER

The PHP path reads stored vectors in batches, compares them, and sorts the scores. The pgvector path ranks inside the database and returns matching IDs before the application loads the selected products.

The application decides which products are eligible. The database ranks within that boundary. Faster ranking does not remove the need to choose the right candidates.

MOVE THE WORK
APPLICATION
POSTGRESQL
Candidate
window
Filters stay here
Vector rankingOrder + limit in SQL
A04A11A28Selected IDsThen load products
↳

The ranking moves. The candidate boundary stays under application control.

Illustrative IDs · movement shows responsibility, not elapsed time.

Illustrative walkthroughs of a real implementation.