This page maps the end-to-end pipeline to the tables and indexes that matter most for performance.
- Reads provider payloads and rewrites provider slices in
provider_exchange - Upserts canonical rows in
exchange - Critical structures:
provider_exchangeunique(provider_id, provider_exchange_code)idx_provider_exchange_exchange
- Review focus:
- full-slice replace cost is small today, but the FK from
provider_listingmeans provider exchanges with listings cannot be removed blindly
- full-slice replace cost is small today, but the FK from
- Reads provider catalog input and rewrites provider slices in
provider_listing - Reads and writes
listing,issuer, andprovider_exchange - Critical structures:
provider_listingunique(provider_exchange_id, provider_symbol)listingunique(exchange_id, symbol)idx_provider_listing_listing
- Review focus:
provider_listingis the root table for provider-scoped work- bare provider symbols are only unique within one provider exchange
- migration 054 dropped
provider_listing.provider_idand its supporting index; the owning provider is reached viaprovider_exchange.provider_idthroughprovider_exchange_id
- Reads
provider_listing - Reads and writes
fundamentals_fetch_state - Upserts
fundamentals_raw - Updates
listing.primary_listing_status - Critical structures:
provider_listingunique(provider_exchange_id, provider_symbol)fundamentals_rawprimary keyprovider_listing_idfundamentals_fetch_stateprimary keyprovider_listing_id(the join driver — migration 067 dropped thenext_eligible_atandlast_fetched_atindexes since they were never picked)
- Review focus:
fundamentals_raw.datais the widest operational row in the schemafundamentals_fetch_statestores only active failures; successful fetch progress is derived from raw payload presence and age
- Reads
fundamentals_raw - Reads and writes
fundamentals_normalization_state - Rewrites canonical rows in
financial_facts - Updates
financial_facts_refresh_state - Critical structures:
fundamentals_rawprimary keyprovider_listing_idfundamentals_raw.payload_hashfinancial_factsPK andidx_fin_facts_security_concept_latest
- Review focus:
financial_factsis the main fact table for metrics- normalization freshness compares payload hashes, not fetch timestamps
- unnecessary columns or duplicate fact rows compound downstream cost quickly
- Reads
fundamentals_raw - Writes display fields on
issuer - Critical structures:
fundamentals_rawlookup by provider listinglisting -> issuerjoin
- Review focus:
- issuer metadata is separate from listing identity; avoid pushing provider-specific fields into
listing
- issuer metadata is separate from listing identity; avoid pushing provider-specific fields into
- Reads
provider_listing - Applies primary-listing filter through
listing.primary_listing_status - Reads and writes
market_data_fetch_state - Dual-upserts
provider_market_data(keyed by theprovider_listing_idthreaded from the eligibility query) and canonicalmarket_data, in one transaction - Critical structures:
idx_provider_listing_listingmarket_dataprimary key(listing_id, as_of)(latest-snapshot probes traverse the PK backwards; migration 067 dropped the redundantidx_market_data_latest)provider_market_dataprimary key(provider_listing_id, as_of)(dual-write conflict target)market_data_fetch_stateprimary keyprovider_listing_id
- Review focus:
- latest-snapshot queries should resolve against the
market_dataPK in a single seek per scoped row - stale planning aggregates by
listing_id, makingmarket_dataa hotspot on large universes
- latest-snapshot queries should resolve against the
- Discovers currencies from
listingandfinancial_facts - Reads and writes
fx_supported_pairsandfx_refresh_state; dual-upsertsprovider_fx_ratesand canonicalfx_ratesin one transaction - Critical structures:
- partial currency indexes on
listingandfinancial_facts idx_fx_supported_pairs_refreshablefx_refresh_statePKprovider_fx_ratesPK(provider_id, base, quote, rate_date)(coverage seeks);fx_ratesPK(base, quote, rate_date)(converter reads)
- partial currency indexes on
- Per-pair coverage cost:
- one
pair_coverageread per refreshable pair (to plan missing ranges), issued as split MIN/MAX index-endpoint seeks off theprovider_fx_ratesPK autoindex rather than a full-group scan - after each range upsert, coverage is widened in-process from the upserted batch's own dates, so there is no second coverage scan per range
- one
- Review focus:
- check whether the separate FX state tables are justified by the refresh algorithm complexity
- Resolves the canonical scope to
(listing_id, canonical_symbol)pairs and carries thelisting_idthrough every read and write (no symbol->id re-resolution):- full / by-exchange scope scans the supported universe (
list_supported_listings:provider_listing -> listing -> exchange) - an explicit
--symbolsscope seeks only the requested tickers (list_supported_listings_for_symbols):exchangebyexchange_code, thenlistingby(exchange_id, symbol)— never a whole-universe scan
- full / by-exchange scope scans the supported universe (
- Bulk-reads
financial_facts - Bulk-reads latest
market_datawhen required - Writes
metricsandmetric_compute_status - Critical structures:
listingunique(exchange_id, symbol)andexchangeuniqueexchange_code(the targeted--symbolsseek)idx_provider_listing_listing(scope joins back into provider rows)idx_fin_facts_security_concept_latestmarket_dataprimary key(listing_id, as_of)metricsPK(listing_id, metric_id)metric_compute_statusPK(listing_id, metric_id)(migration 067 dropped the(metric_id, status)secondary because every read matches the PK)
- Review focus:
- this is the hottest read path in the system
financial_factsrow width and index fit dominate runtime more than almost any other table
- Resolves the canonical scope to
(listing_id, canonical_symbol)pairs fromprovider_listing,listing, andexchange, then carries thelisting_idinto the metric/fact/market reads (same two scope modes as Compute Metrics: full/by-exchange scan vs targeted--symbolsseek vialist_supported_listings_for_symbols) - Reads
metrics - Reads
metric_compute_statusfor diagnostics - Critical structures:
provider_listingjoins back tolisting;listing (exchange_id, symbol)+exchange (exchange_code)for the targeted--symbolsseekmetricsPK(listing_id, metric_id)(migration 067 dropped the baremetric_idindex since it was never picked)metric_compute_statusPK(listing_id, metric_id)
- Review focus:
- screening depends on
metricsbeing a compact cache; if the table grows wider or more history is added, read costs change materially
- screening depends on
financial_facts: largest analytical read surface and most index-sensitive query pathprovider_listing: root of many scope-building joins and provider-stage scansmarket_data: latest-row access pattern must remain cheap as history growsfundamentals_raw: JSON payload width can dominate I/O even when only a small subset of columns is needed