Open-Source Wikis

/

GitLab

/

Systems

/

Search

gitlab-org/gitlab

Search

GitLab has three search backends layered on top of Postgres trigram search.

Backends

Backend What it indexes Source
Postgres trigram Issues, MRs, snippets when no ES is configured inline ActiveRecord scopes
Elasticsearch Full-text issues, MRs, comments, code (legacy) ee/lib/elastic/, ee/lib/api/internal/elastic/
Zoekt Code search (high-scale) ee/lib/search/zoekt/, ee/lib/api/internal/search/zoekt/
Active Context (vector) Embeddings for retrieval and chat ee/lib/active_context/, gems/gitlab-active-context/

Source layout

app/services/search/
├── group_service.rb
├── project_service.rb
├── snippet_service.rb
└── ...
app/finders/issues_finder.rb (and friends)  # PG search fallback
lib/gitlab/search/
├── query_normalizer.rb
└── ...
ee/lib/elastic/                              # Elasticsearch indexing & query
ee/lib/search/zoekt/                         # Zoekt indexing & query
ee/lib/active_context/                       # Vector retrieval framework
ee/app/workers/elastic/                      # Indexing workers
ee/app/workers/search/                       # Cross-backend search workers

High-level flow

graph TD
    User -->|/search?q=...| Ctrl[SearchController]
    Ctrl --> SS[SearchService]
    SS --> Strat[Strategy resolver]
    Strat -->|advanced search| ES[Elasticsearch]
    Strat -->|code| Zoekt[Zoekt]
    Strat -->|fallback| PG[(Postgres)]
    ES --> Idx[gitlab-elasticsearch-indexer]
    Zoekt --> ZIdx[gitlab-zoekt-indexer]

Elasticsearch

The legacy advanced search uses Elasticsearch for issues, MRs, comments, wikis, and code (in projects below a size threshold).

  • Indexing is driven by Sidekiq workers in ee/app/workers/elastic/.
  • The actual indexer is the gitlab-elasticsearch-indexer Go binary (version pinned in GITLAB_ELASTICSEARCH_INDEXER_VERSION).
  • Reindexing migrations live in ee/elastic/migrate/.

Zoekt

Zoekt is a Go-based code search engine optimized for repository content. GitLab uses it for code search at scale.

  • Index management workers in ee/app/workers/search/zoekt/.
  • The indexer binary is gitlab-zoekt-indexer (version pinned in GITLAB_ZOEKT_VERSION).
  • Per-namespace enablement is tracked in ee/app/models/search/zoekt/*.

Active Context

A newer abstraction designed for retrieval-augmented generation (RAG) and Duo Chat:

  • gems/gitlab-active-context/ provides a backend-agnostic API.
  • ee/lib/active_context/ contains GitLab-specific collectors and queries.
  • Embeddings are stored in pgvector or in dedicated stores.

Search service entry point

SearchService (app/services/search_service.rb) picks the right strategy:

  • Tries Elasticsearch via Gitlab::SearchResults::Elastic if enabled.
  • Falls back to Postgres-based Gitlab::SearchResults.
  • Code search may delegate to Zoekt.

GraphQL search uses app/graphql/types/projects/searchable_* types, which thread through the same service.

Indexing

Each indexable model declares its mapping. Examples (EE):

  • ee/app/models/concerns/elastic/application_versioned_search.rb.
  • Per-model as_indexed_json.

When a model is created or updated, callbacks enqueue ElasticIndexerWorker (or its specialized variants).

Reindexing migrations

Like database migrations, search has its own migration mechanism (ee/elastic/migrate/) for incompatible mapping changes. Each migration runs on a Sidekiq worker and tracks progress.

Configuration

Admin Area → Settings → Search has:

  • Elasticsearch URLs.
  • Index limits per namespace.
  • Zoekt enablement.
  • Active Context backend.

The model ApplicationSetting (app/models/application_setting.rb) stores these.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Search – GitLab wiki | Factory