docs/sources/reference-pyroscope-v2-architecture/components/query-frontend.md
The query-frontend is a stateless component that serves as the entry point for the query path. It handles query planning and routes requests to query-backend instances for execution.
The query-frontend is responsible for:
When a query arrives, the query frontend:
Because the metastore serves block metadata from memory with linearizable reads, query planning is fast and does not require the query frontend to maintain any local state about blocks.
The query-frontend is completely stateless:
The query-frontend can scale independently of the write path:
Query-frontends can be load balanced using standard HTTP load balancers. Each instance can handle any query, making round-robin load balancing effective.
Profiles collected from native code (for example, eBPF-based profiling) can contain stack frames that only carry a build ID and an address, without a resolved function name. Pyroscope resolves these frames using debuginfod: it fetches debug information for the build ID, extracts function names from it, and caches the result in object storage for reuse.
Symbolization is disabled by default. -symbolizer.enabled=true turns it on — the flag sets the default for all tenants and can be overridden per tenant — and -symbolizer.debuginfod-url selects the debuginfod server to fetch debug information from (default https://debuginfod.elfutils.org).
With symbolization enabled, the per-tenant flag symbolizer.symbol-ref-trees-enabled (default false) makes the query backend emit tree-query results with unresolved native frames carried in the tree itself, and has the query frontend resolve them once after merging results from all query backends. Resolution of a single binary's addresses is bounded by the global symbolizer.resolve-timeout setting (default 20s).