Building a Scalable Retriever-Ranker Architecture: Malt's Journey with Vector Databases and LLM-Powered Freelancer Matching

malt · Tech · 2024 · source Agentic: no · promotional bias: low · source-backed · extracted with prompt 0.5.4 (schema v2)

Generated from extraction.json — do not edit by hand. Every claim cites verbatim source evidence; stated means the quote directly asserts the claim, implied means it supports it indirectly.

Problem

Domain: Freelancer-project matching and recommendation

Malt needed to replace a slow monolithic matching model with a scalable matching architecture that could search more than 700,000 freelancer profiles, keep recommendation quality high, support business filters such as location and availability, and prepare for more complex rankers.

Constraints:

Architecture

Malt moved to a retriever-ranker architecture. The retriever encodes projects and precomputed freelancer embeddings with bi-encoder models, stores vectors in Qdrant, uses ANN search and business filters to quickly return a manageable candidate set, then sends that subset to the existing matching model acting as a ranker. Qdrant runs self-hosted on Kubernetes with clustering, sharding, replication, Prometheus/OpenMetrics, and Grafana monitoring.

Diagram confidence: explicit (topology described by the source).

flowchart LR
  project-intake[Project Intake] --> project-encoder[Project Encoder]
  freelancer-profiles[Freelancer Profiles] --> freelancer-encoder[Freelancer Encoder]
  project-encoder[Project Encoder] --> qdrant[Qdrant]
  freelancer-encoder[Freelancer Encoder] --> qdrant[Qdrant]
  qdrant[Qdrant] --> retriever[Retriever]
  retriever[Retriever] --> ranker[Ranker]
  ranker[Ranker] --> recommendation-results[Recommendation Results]
  qdrant[Qdrant] --> kubernetes[Kubernetes]
  kubernetes[Kubernetes] --> monitoring[Monitoring]
Drag to pan · scroll or use +/− to zoom · reconstructed from the source's described component topology

Components

Component Role Interacts with
Project Intake New project description and attributes submitted by a client. Project Encoder
Project Encoder Bi-encoder path that embeds the new project in real time. Project Intake, Qdrant
Freelancer Encoder Bi-encoder path that precomputes freelancer profile embeddings. Freelancer Profiles, Qdrant
Freelancer Profiles Malt freelancer database with skills, experience, location, availability, and other attributes. Freelancer Encoder
Qdrant Vector database providing ANN search, filtering, sharding, replication, and vector storage. Project Encoder, Freelancer Encoder, Retriever, Kubernetes
Retriever Fast recall-oriented candidate generator using bi-encoder embeddings and Qdrant. Qdrant, Ranker
Ranker Precision-oriented matching model that ranks retrieved candidates. Retriever, Recommendation Results
Recommendation Results Ordered freelancer recommendations returned to the product. Ranker
Kubernetes Self-hosted deployment platform for Qdrant with Helm, sharding, replication, and monitoring. Qdrant, Monitoring
Monitoring Prometheus/OpenMetrics and Grafana dashboards for Qdrant health, performance, and availability. Kubernetes

Data flow

Freelancer profiles are encoded ahead of time and stored as vectors. When a project is posted, Malt computes the project embedding in real time, queries Qdrant with ANN plus filtering to retrieve a relevant subset such as 1,000 candidate profiles, then ranks that subset with the current matching model and returns near-real-time recommendations.

3 supporting quotes
“Freelancer profiles can be encoded ahead of time and stored, ready to be compared against any new project that comes in.”article, stated
“When a new project is posted, its details are encoded into a vector in real-time. This project vector is then compared against the precomputed freelancer vectors using a similarity measure, like cosine similarity.”article, stated
“keyword along with other project attributes). * Apply a KNN (k-nearest neighbors) search to retrieve the top K freelancers according to our similarity measure. In practice, a KNN search is too slow when there are too many vectors (as is the case with our 700,000+ freelancers), that is why we”article, stated

Why this architecture

Malt chose a two-step retriever-ranker because cross-encoders were accurate but too slow across hundreds of thousands of profiles, while bi-encoders were fast but less precise. The vector database made ANN retrieval, filtering, scalability, and up-to-date vectors practical in production.

3 supporting quotes
“we aimed to find a balance between speed and accuracy, ensuring that our system could handle the scale of our platform”article, stated
“The Retriever is built for recall, ensuring that we do not miss out on potential matches, even if, at this step, we are not yet state of the art in terms of quality.”article, stated
“Here, the focus shifts to precision, by using a cross-encoder model where the representations of the project and freelancer are combined and fed into a network.”article, stated

Models used: bi-encoder models · cross-encoder models · transformers · BERT · GPT

Scale

Alternatives considered (roads not taken)

Use a cross-encoder for all pairs

Rejected because: It was highly precise but required scoring every project against 700,000+ freelancers.

“In our search for the most effective way to match freelancers and projects, we explored several methodologies, including cross-encoders and bi-encoders, each with its own benefits and drawbacks. ### Cross-encoder: The most accurate, but too slow to scale”article, stated
“However, it is slow: for each project we receive (for instance, a client seeking a Java developer), we need to create a pairing with each freelancer (over 700,000 at the time of writing) and process each project-freelancer pair through the model, thus computing over 700,000 pairs!”article, stated

Use only a bi-encoder

Rejected because: Bi-encoders are fast but lose some pairwise relationship quality, so Malt retained a ranking stage for precision.

“The results of this method are not as good as the cross-encoder, as we lose the relationship between the freelancer and the project, but it is fast.”article, stated
“* Following the initial pre-selection, the Ranker phase kicks in. Here, the focus shifts to precision, by using a cross-encoder model where the representations of the project and freelancer are combined and fed into a network.”article, stated

Use Elasticsearch or PGVector

Rejected because: Elasticsearch underperformed for high-dimensional vector search, and PGVector missed speed and precision benchmarks.

“While Elasticsearch provided a familiar environment with good filtering options, its performance in high-dimensional vector searches lagged behind Qdrant.”article, stated
“PGVector presented an intriguing blend of relational and vector database features, but its overall performance and ANN quality did not meet our benchmarks”article, stated

Patterns

retrieval-ranking (retrieval)

Malt splits matching into recall-oriented retrieval and precision-oriented ranking.

“That is why we decided to build a two-step process called”article, stated

latency-optimization (performance)

The retriever reduces the candidate pool before ranking, cutting p95 latency to at most 3 seconds.

“The first step, the retriever, will quickly return a relevant subset, for example, 1,000 profiles with Java expertise out of our 700,000+ freelancers.”article, stated

eval-driven-development (evaluation)

Malt benchmarked vector databases and validated production quality through AB testing.

“We benchmarked several vector databases, testing their performance, ANN quality, and filtering capabilities under conditions that mimicked our real-world use case.”article, stated
“confirmed by an increase in the conversion of projects in our AB test.”article, stated

hybrid-search (future-direction)

The team calls out hybrid semantic and keyword search as an important future feature for cases where keyword search is better.

“vector databases are beginning to support hybrid searches that combine semantic and keyword searches.”article, stated

Tradeoffs

Use retriever-ranker instead of one model

Chose Bi-encoder retriever plus ranker over A single monolithic matching model.

Rationale: The two-stage design balances recall, precision, latency, and future extensibility.

“Recognizing the limitations of our model (slowness, inflexibility, etc.) led us to explore alternative solutions in 2023.”article, stated
“we aimed to find a balance between speed and accuracy”article, stated

Self-host Qdrant on Kubernetes

Chose Self-hosted Qdrant with Helm on Kubernetes over Familiar databases or managed alternatives that lacked fit.

Rationale: Qdrant met speed, ANN, filtering, and geo-spatial requirements while Kubernetes gave reproducible deployment.

“We decided to self-host the solution on our Kubernetes clusters.”article, stated
“Qdrant emerged as the optimal choice for our system, offering the best blend of speed, accuracy, and functionality.”article, stated

Deploy retriever first before the next-generation ranker

Chose Retriever before the existing matching model over Waiting for the full new retriever-ranker stack.

Rationale: This let Malt validate scalability and performance while the more complex ranker remained in development.

“first by deploying a retriever that sits before our actual matching model (that acts as the ranker).”article, stated
“This setup allows us to validate the scalability and performance of the retriever.”article, stated

Gotchas (what bit them)

Filtering outside the vector database can damage performance or quality.

Root cause: Pre-filtering creates huge masks and can degrade ANN graph quality; post-filtering requires requesting many extra candidates.

Resolution: Malt selected a vector database with strong filtering, especially geo-spatial filtering.

“This could lead to huge payloads and impact performance and scalability.”article, stated
“This will impact the performance of the retriever, as it is correlated to the number of candidates requested.”article, stated

Cross-encoder quality did not make it production-scalable.

Root cause: The model would need to score each project against every freelancer.

Resolution: Use a fast retriever first, then a ranker on a narrowed subset.

“This approach works great; the quality (precision) is really good because the model can capture complex relationships between the two entities.”article, stated
“The first step (the Retriever) objective is to quickly narrow down the vast pool of freelancers to a more manageable subset”article, stated

Evaluation

Malt evaluated database candidates on query speed, ANN quality, and filtering under use-case-like conditions, then evaluated production impact with p95 latency and AB-test conversion.

Metrics: queries per second · ANN precision · filtering support · p95 latency · AB-test project conversion

3 supporting quotes
“testing their performance, ANN quality, and filtering capabilities under conditions that mimicked our real-world use case.”article, stated
“Queries per second were measured on a local laptop (Macbook pro with M1 pro chip) using l2 as the similarity measure and 100 candidates requested”article, stated
“confirmed by an increase in the conversion of projects in our AB test.”article, stated

Outcomes

The architecture handles 700,000+ freelancer profiles and retrieves approximately 1,000 candidates for ranking in the example.

3 supporting quotes
“we deployed our retriever-ranker architecture in 2023.”article, stated
“p95 latency dropping from tens of seconds (sometimes taking over a minute!) to a snappy 3 seconds at most.”article, stated
“without sacrificing the quality of our recommendations, which was confirmed by an increase in the conversion of projects in our AB test.”article, stated