Reranking for RAG: Cohere Rerank vs Cross-Encoders vs ColBERT

Reranking for RAG: Cohere Rerank vs Cross-Encoders vs ColBERT (2026)

The short answer

Reranking boosts RAG quality by rescoring the top retrieved chunks with a more expensive model. Three options: Cohere Rerank-3 (managed API, best quality, easy to adopt), cross-encoders like ms-marco-MiniLM (open-source, self-hostable, cheaper), and ColBERT (highest-quality late-interaction model, higher inference cost). Reranking typically lifts retrieval precision by 15 to 30%. Cohere wins for most teams; cross-encoders win when latency and cost dominate.

Reranking is the cheapest, biggest quality upgrade a RAG system gets. Retrieve 20 candidates with a fast dense index, let a slow but accurate reranker reorder them, keep the top 5 for generation. Lifts top-5 recall 10-25% on realistic workloads, adds 50-200ms per query, costs pennies.

This guide covers the three reranker families in production use in 2026: Cohere Rerank, open-source cross-encoders (bge-reranker, Jina Reranker), and multi-vector late-interaction rerankers like ColBERT. It also shows how to measure which one wins on your workload.

Why reranking helps

Dense retrieval is fast because it reduces a chunk to a single vector and uses approximate nearest neighbor search. The compression loses information. Two chunks that are both roughly on-topic score similarly even if one directly answers the question and the other only mentions related terms.

A reranker scores each (query, chunk) pair with a model that reads both in full. More compute per pair, far better precision. The pattern:

  1. Dense retrieval returns 20-50 candidates (high recall, loose ranking).
  2. Reranker scores each candidate against the query (slow, precise).
  3. Keep the top 5-10 for the generation step.

You get retrieval that is both wide (dense index does the hard search) and precise (reranker fixes the ranking of the top candidates).

Cohere Rerank: the managed default

Cohere Rerank is the easiest option. One API call, no model management, strong quality out of the box.

import cohere
co = cohere.Client()

def rerank_cohere(query, candidates, top_n=5):
    result = co.rerank(
        model="rerank-english-v3.0",
        query=query,
        documents=[c["text"] for c in candidates],
        top_n=top_n,
    )
    return [
        {**candidates[r.index], "rerank_score": r.relevance_score}
        for r in result.results
    ]

Three variants of rerank-v3 are available: rerank-english-v3.0, rerank-multilingual-v3.0, and rerank-english-light-v3.0 (smaller, cheaper, slightly lower quality). Pricing is around $1 per 1,000 reranks of up to 100 documents each. For most RAG systems, cost is $5-50/mo total.

Rerank-v3 returns a relevance_score between 0 and 1 with real semantic meaning: above 0.5 means the document is clearly relevant, below 0.3 means it is probably not useful. That score is the right threshold to drive automatic escalation or “I don’t know” responses.

Open-source cross-encoders

Cross-encoders feed (query, chunk) pairs through a transformer and output a single score. Full attention between query and chunk gives much higher precision than dense retrieval; the cost is slower inference.

Three open-source options worth knowing:

  • bge-reranker-v2-m3 (BAAI). Multilingual, strong performance across 100+ languages, fast enough for production. Runs on a single GPU.
  • bge-reranker-large (BAAI). English-focused, slightly higher quality than v2-m3 on English benchmarks, slower.
  • Jina Reranker v2. Multilingual, with code and function-call fine-tuned variants. Competitive with Cohere Rerank on English and multilingual benchmarks.
from sentence_transformers import CrossEncoder

reranker = CrossEncoder("BAAI/bge-reranker-v2-m3", max_length=512)

def rerank_local(query, candidates, top_n=5):
    pairs = [(query, c["text"]) for c in candidates]
    scores = reranker.predict(pairs)
    ranked = sorted(
        zip(candidates, scores),
        key=lambda x: x[1],
        reverse=True,
    )
    return [
        {**c, "rerank_score": float(s)}
        for c, s in ranked[:top_n]
    ]

Self-hosted cross-encoders cost GPU time, not API calls. For teams already running a GPU for other inference, the marginal cost is near zero. For teams without inference infrastructure, Cohere Rerank is cheaper than running a GPU just for reranking.

ColBERT: late-interaction retrieval

ColBERT is a different animal. Instead of encoding each chunk as one vector, it encodes each token as its own vector (hundreds per chunk). Scoring sums token-level similarity across the query and chunk. Precision is higher than dense retrieval, and ColBERT scales to full-corpus retrieval, not just reranking.

from ragatouille import RAGPretrainedModel

RAG = RAGPretrainedModel.from_pretrained("colbert-ir/colbertv2.0")

RAG.index(
    collection=[c["text"] for c in all_chunks],
    document_metadatas=[c["metadata"] for c in all_chunks],
    index_name="my_colbert_index",
)

results = RAG.search(query="example query", k=10)

ColBERT uses more disk than dense retrieval (10-20x the storage for the same chunks). In exchange, you get retrieval quality that often beats dense + cross-encoder-rerank on hard queries.

bge-m3 supports multi-vector (ColBERT-style) mode alongside dense and sparse. For teams wanting ColBERT quality without a separate engine, bge-m3 with Qdrant or Vespa is a strong setup.

Quality comparison: what the benchmarks show

On BEIR (the standard retrieval benchmark), typical 2026 rankings on NDCG@10:

  • Dense (voyage-3) alone: baseline, around 50
  • Dense + Cohere Rerank v3: around 56-58
  • Dense + bge-reranker-v2-m3: around 55-57
  • ColBERT v2 alone: around 54-56
  • Dense + Jina Reranker v2: around 55-57
  • Dense + ColBERT (as reranker on top of dense): around 57-59

Numbers vary by domain. On your own test set the gap between Cohere, bge-reranker, and Jina Reranker is usually within 1-2 points. ColBERT as a reranker typically wins by another 1-2 points on hard queries at the cost of more compute.

Translating NDCG to practical outcome: a 5-point lift usually means 15-25% more correct top-5 retrievals on real workloads, which cascades into noticeably better generation quality downstream.

Latency and cost comparison

For reranking 20 candidates at 500 tokens each:

  • Cohere Rerank v3: 60-150ms, $0.001 per rerank.
  • bge-reranker-v2-m3 on L4 GPU: 40-80ms, GPU amortization only.
  • bge-reranker-large on L4 GPU: 80-180ms, GPU amortization only.
  • Jina Reranker v2 (hosted): 70-160ms, around $0.001 per rerank.
  • ColBERT on L4 GPU: 40-100ms, GPU amortization only.

Hosted options are convenient. Self-hosted cross-encoders win on cost at steady-state query volume (over 50,000 queries/mo) if you already run a GPU.

How to pick in 2026

Six questions, in order:

  1. Starting a new RAG system and want it to just work? Cohere Rerank v3.
  2. Data cannot leave your network? bge-reranker-v2-m3 self-hosted.
  3. Multilingual with non-Western languages? bge-reranker-v2-m3 or Jina Reranker v2.
  4. Highest-possible quality, willing to pay compute? ColBERT as reranker on top of dense retrieval.
  5. Code or structured-output retrieval? Jina Reranker code variant.
  6. Query volume is huge and cost dominates? Self-hosted bge-reranker on your own GPU.

Most teams end up on Cohere Rerank for 1-2 years, then migrate to self-hosted when volume grows past the point where API costs beat GPU amortization. The migration is a one-day job; the reranker interface is stable.

Measuring the actual lift on your workload

Build a 50-100 query test set with known-correct chunk IDs. Run three measurements:

  1. Top-5 recall with dense retrieval only.
  2. Top-5 recall with dense + candidate reranker.
  3. Latency added by the reranker.

Typical observations:

  • If dense-only top-5 recall is already 90%+, reranking adds 2-4%. Marginal.
  • If dense-only recall is 60-80%, reranking adds 10-20%. Big win.
  • If dense-only recall is under 50%, the bottleneck is probably chunking or embedding, not ranking. Reranking helps less until the base retrieval improves.

Teams that skip measurement and reach for reranking first often spend a month tuning a reranker when the fix is to re-chunk the corpus. Measure both before optimizing either.

Combining rerankers: cascade and ensemble

Two patterns that squeeze extra quality out of reranking:

Cascade. First rerank with a fast model (bge-reranker-light), keep top 10, then rerank again with a slow model (Cohere Rerank or bge-reranker-large). Twice the ranking cost but higher final quality.

Ensemble. Rerank with two different rerankers independently, combine scores (average or RRF). Catches cases where one reranker misses.

Both patterns add latency and cost, usually without matching the gain. For most teams, one good reranker is enough. Cascade and ensemble are tools for the last 2-5% of quality when nothing else moves the needle.

Frequently asked questions

Do I always need a reranker in RAG?

No, but almost. For small corpora (under 1,000 chunks) with simple questions, dense retrieval alone is often enough. For anything larger or with complex questions, a reranker typically adds 10-25% top-5 recall. The 50-150ms added latency is invisible compared to generation time.

What is the best reranker in 2026?

Cohere Rerank v3 is the easiest to use and strongest hosted option. bge-reranker-v2-m3 is the strongest open-source option for multilingual. ColBERT v2 as a reranker typically wins on quality for English retrieval at the cost of more compute. Pick based on hosting constraints and language mix.

How many candidates should I rerank?

20 to 50 is the sweet spot. Below 20, dense retrieval might not catch the right chunk at all, so reranking cannot fix it. Above 50, the extra candidates rarely contain the right answer and you spend compute for marginal gain. 20 is a defensible starting point.

How much does Cohere Rerank cost at scale?

At $1 per 1,000 reranks of up to 100 documents, a system doing 10,000 queries per day costs around $300/mo. Compared to Claude Opus 5.5 generation at $400-800/mo for the same volume, reranking is cheap. For over 50,000 queries per day, consider self-hosted alternatives.

Can I use a reranker as the only retriever, skipping dense retrieval?

Not practically. Cross-encoder rerankers score (query, chunk) pairs one at a time. For a corpus of 100,000 chunks, scoring all pairs per query is 100,000 inference calls, which takes minutes. The two-stage pattern (dense retrieval first, rerank the top 20-50) is the only viable approach at production scale.

Does reranking help if I’m already using hybrid search?

Yes. Hybrid search catches query-matching chunks that pure dense misses, but it does not improve ranking precision within the retrieved set. Reranking adds that precision layer on top. Hybrid + reranking is the current best-practice stack and typically improves top-5 recall another 5-10% over hybrid alone.

Reranking is the free upgrade of RAG optimizations. Dense retrieval alone, measure the gap, add Cohere Rerank or bge-reranker-v2-m3, measure the lift. If the lift is large, keep it. If the gap was elsewhere (chunking, embedding), you have cheap diagnosis and know what to fix next.

Angel Jude Suarez

Full-Stack Developer at PIES IT Solution

Focuses on Python development, machine learning, and AI integration. Has built production AI systems including OpenAI Whisper integration for medical transcription and GPT-4o-powered diagnosis assistance. Strong background in pandas, scikit-learn, and TensorFlow.

Expertise: Python · PHP · Java · VB.NET · ASP.NET · Machine Learning · AI Integration · OpenCV · Django · CodeIgniter  · View all posts by Angel Jude Suarez →

Leave a Comment