Methodology

How the leaderboard imports data, prices offers, applies guardrails, caches responses, and reports freshness.

Leaderboard Missions

What This Tool Ranks

The calculator ranks NPC LP-store offers by realistic ISK per LP. It compares selling into Jita buy orders with listing against Jita sell orders, after taxes, broker fees, required item costs, and — when blueprint manufacture rows are shown — material costs and the manufacturing job installation fee.

The default leaderboard:

The Space control can narrow results to highsec-accessible stores or show all known access tiers. The Level 5 Missions control can show all corporations, only corporations with level 5 agents, or hide them. Ranking controls can choose the valuation basis, scale runs, set LP/hour, require minimum 28-day market volume, and optionally hide rows above a maximum packaged cargo volume in m3. Quality toggles control Jita-only pricing, suspicious rows, vanity rows, no-Security-L4+ corporations, faction warfare, special LP stores, and duplicate store rows. The BPC control picks which blueprint-copy rows appear: none, direct contract sales, manufacture conversions, or both.

Data Sources

Refresh Cadence

The scheduler refreshes:

Startup warmup fills missing or stale SDE, LP, market, and history data before normal cadence takes over. Fetchers honor ESI Expires headers through the SQLite ESI cache, retry transient upstream failures carefully, and pause before exhausting the ESI error-limit budget.

The leaderboard header reports hot and cold market-price ages separately, LP offer freshness as a daily feed, and an overall Updates OK or Needs attention state from /api/health. A daily LP timestamp that is a few hours old is expected; hot prices are the freshness signal that should normally move every 15 minutes.

Core Calculation

buy_order_sell = sell products into buy orders, pay sales tax
sell_order_listing = list products near sell orders, pay sales tax plus one broker-fee pass

input_cost = LP-store ISK cost + required items bought from sell orders
build_cost = BPC materials (after Material Efficiency) bought from sell orders
job_cost = manufacturing job installation fee on built rows (see BPC Manufacturing)
net_buy_order = product_value_buy_order * (1 - sales_tax_rate) - input_cost - build_cost - job_cost
net_sell_order = product_value_sell_order * (1 - sales_tax_rate - broker_fee_rate) - input_cost - build_cost - job_cost
isk_per_lp = selected net_profit / LP cost
capital_required = input_cost + build_cost + job_cost
roi = selected net_profit / capital_required

The valuation basis can use buy-order cashout, sell-order listing, or the higher of both. runs scales LP, ISK, required items, manufacturing materials, cargo, and order-book depth. When lpBudget or iskBudget is provided, the calculator chooses the maximum feasible run count for that row. The ISK/hour display multiplies the selected ISK/LP basis by the URL-backed lpPerHour value. Contract-priced rows show a dash instead: their ISK/LP is a real one-off conversion rate, but public contracts for such items sell at most a few times per day game-wide, so extrapolating by LP/hour would invent income the market cannot absorb. These rows also sort last when the leaderboard is sorted by ISK/hour.

Fees And Skills

sales_tax_rate = 0.075 * (1 - 0.11 * Accounting)
broker_fee_rate = max(
  0.03
  - 0.003 * BrokerRelations
  - 0.0003 * factionStanding
  - 0.0002 * corporationStanding,
  0.01
)

These are the Tranquility NPC-station rates: sales tax starts at 7.5% and falls to 3.375% at Accounting V; the broker fee starts at 3%, drops 0.3 percentage points per Broker Relations level plus up to 0.3 from faction and 0.2 from corporation standing, and never goes below 1%. Accounting, Broker Relations, Advanced Broker Relations, faction standing, and corporation standing are URL-backed filters. Defaults are zero so the default view is pessimistic for a fresh character. Advanced Broker Relations only affects relist fees in Realistic patient mode.

The optional No market fees (contract sale) channel — bundled into Manufacturer mode — models selling through item-exchange contracts instead of the market. A contract charges only a flat creation fee (about 10k ISK, noise at faction-item prices), so this channel zeroes both the sales tax and the broker fee. It is the only way to reach a true 0%: the skill sliders above floor at 3.375% sales tax and 1% broker. This is how serious LP farmers actually move high-value faction implants and modules, and it matches the fee-free treatment contract-priced rows already receive.

Depth Walking

Every priced leg walks the persisted Jita order book for the full requested quantity instead of using only top-of-book. Products sold through buy orders walk buy orders — but only buy orders a seller standing at Jita 4-4 could actually fill: region-range orders, plus station- or system-range orders that sit at Jita 4-4 or in the Jita system. Products listed through sell orders, required items, and build materials walk sell orders. If the saved top 50 orders do not cover the requested fill, the row is flagged as insufficient depth and the missing quantity is extrapolated at the last consumed price.

Patient Listing Realism

The sell-order (patient) basis above assumes a listing fills in full at the walked prices. In reality a listing joins a queue and waits. Every row therefore carries an estimated fill time for the primary output, shown in the detail drawer:

queue_ahead  = sell-book units listed at or below the volume-weighted list price
sell_rate    = 0.5 * avg_daily_volume_28d
days_to_fill = (queue_ahead + quantity) / sell_rate

The 0.5 factor exists because ESI daily volume mixes both trade directions and only buyer-initiated trades consume the sell book; with no public split, half is the symmetric prior. Items with no market history get no estimate. The SLOW_FILL flag uses this queue-aware estimate for the output leg: warn past 7 days, strong past 28.

The optional Realistic patient quality toggle (off by default, URL-backed) goes further and discounts the sell-order valuation itself:

relist_discount  = 0.5 + 0.06 * AdvancedBrokerRelations          (80% at V)
expected_relists = ceil(days_to_fill / 2) - 1, floored at 0
relist_cost      = expected_relists * (1 - relist_discount) * broker_fee_rate * product_value
patient_effective = net_buy_order + (net_sell_order - relist_cost - net_buy_order)
                    * exp(-days_to_fill / 7)

The exponential decay pulls slow fills toward the guaranteed buy-order cashout: a fill estimated a week out keeps about 37% of the patient premium, and a month-long fill keeps almost none. Relist fees model staying competitive against undercutting, using the Tranquility relist mechanic where modifying an order down costs the undiscounted share of the broker fee on the new price; Advanced Broker Relations is a URL-backed skill filter next to the other fee skills. With the toggle off, nothing changes — the patient and best columns keep the optimistic immediate-fill values.

BPC Manufacturing

When an offered product is a blueprint copy with a manufacturing recipe in the SDE, the calculator can value the manufactured output and subtract material costs ("manufacture" rows), and when fresh public-contract asks exist it can value the copy as a direct contract sale ("sell" rows). Both are hidden by default because blueprint rows can dominate the table with assumptions that are more sensitive to build settings, material liquidity, and contract depth. The four-position BPC control in the Quality filters picks which rows appear: None (default), Sell, Build (manufacture conversions), or All. Build is a buildables-only lens: it shows manufacture conversion rows alone and hides plain direct-item LP offers, because the facility, Material Efficiency, and job-cost settings act only on built rows — those direct items stay in the default None view.

LP-store blueprint copies are unresearched (Material Efficiency 0), so the default view buys the full base material quantities — matching a build in an NPC station with no rigs. Manufacturer mode's Facility preset instead models a rigged structure: a T2 ME rig in highsec (about 3.2% material savings) or in null / wormhole space (about 5.8%), applying EVE's per-material round-then-ceil ME formula. Manufacturer mode is a standalone top-bar toggle that bundles these blueprint build rows — and only those, so every row responds to the build settings; plain direct-item offers are hidden — this facility, the job installation fee below, and the no-market-fees contract channel, and tints the workspace to signal it is not the default view.

Built rows also carry the manufacturing job installation fee, which is on by default. EVE charges this per job as a percentage of the job's Estimated Item Value (EIV = the sum of each base material quantity times CCP's daily adjusted reference price, ignoring Material Efficiency):

job_cost = EIV * (system_cost_index * structure_bonus + 0.0025 facility_tax + 0.04 SCC)

The facility tax and SCC surcharge (about 4.25% together) are location-independent; only the system cost index varies, so Manufacturer mode exposes it as a single configurable percent (default 2.5% for an NPC station, where structure_bonus is 1). The fee is real ISK the builder fronts, so unlike the LP-paid blueprint it lowers net profit and raises capital_required and the ROI denominator. Adjusted reference prices come from public ESI /latest/markets/prices/, refreshed daily; a material CCP does not price is skipped from EIV, so job cost is understated rather than wrong.

Risk And Access

Space filtering and row risk icons use practical LP-store access risk, derived from the least risky known NPC station owned by the corporation. The corporation HQ system is still shown as location metadata, but it does not by itself make a highsec-accessible corporation look like a nullsec-only store. Highsec is security 0.5 and above, lowsec is 0.0 through 0.4, and nullsec covers below 0.0 plus any wormhole or unknown-security store access.

DED, CONCORD, and similar special-source LP stores are marked as special LP and excluded from the global default leaderboard. Faction warfare offers are also opt-in. Choosing a specific corporation or faction in the Corporation / Faction filter overrides these global exclusions and the no-Security-agent filter, so the selected owner's full catalog is shown even when the matching toggles are off — for example picking a faction-warfare militia returns its offers instead of an empty table. LP-store corporations with no earnable LP source, such as event or placeholder LP stores without agents, are excluded before these user-facing filters are applied. Risk chips are visual warnings on the row; highsec-accessible rows do not get a risk chip.

Quality Flags

FlagRuleSeverity
LOW_VOLUME28-day average daily volume is below 100 units and below 250m ISK; expensive items that move serious ISK on few units are not flagged.Warn; shown as a yellow flag.
SLOW_FILLThe estimated sell-order fill of the output — queue ahead at the walked list price plus the requested quantity, against the sell-side half of daily volume (see Patient Listing Realism) — exceeds 7 days. Cost legs keep the plain quantity-versus-volume rule.Warn; strong above 28 days.
HEAVYPackaged cargo volume is above 100 m3 and at or below 500 m3.Warn; shown as a yellow flag.
VERY_HEAVYPackaged cargo volume is above 500 m3.Strong visual; shown as a red flag.
THIN_BOOKSell order count is 2 or less, or the top sell order has more than 80% of sell quantity.Warn
WIDE_SPREADSell minimum is more than 50% above buy maximum.Warn
PRICE_SPIKECurrent sell minimum is more than twice the 28-day median price.Strong
BUY_SPIKECurrent buy maximum on the output is more than 1.5x the 28-day median price. Buy maxima normally sit below the median, so this usually means a seeded buy wall is inflating the buy-order valuation.Strong
OFF_HUBCheapest sell order is not at Jita 4-4.Warn, or strong when multiple significant cost legs are off-hub.
NO_HISTORYMarket history has fewer than seven days.Warn
INSUFFICIENT_DEPTHPersisted order-book depth does not cover the requested fill.Strong
CONTRACT_PRICEDThe product cannot be listed on the regular market (no market group, typically a faction blueprint copy) and is valued from scam-filtered public-contract asks in The Forge: blueprint copies are normalized to price per run, decoy listings are screened by a recipe cap (a copy's per-run value cannot exceed what the built product sells for) and a band anchored on the cheapest credible ask, and at least two independent asks must survive. The patient basis skips the sales tax and broker fee because item-exchange contracts pay only a flat creation fee; no instant-sell value exists. Blueprint offers with both a manufacture recipe and a contract price appear twice — a (sell) row for the direct contract sale and a (manufacture) conversion row whose net profit keeps total-realization math; the consumed copy is paid for in LP, so its contract value is excluded from net profit, capital required, and ROI alike, and the (sell) row is where that value surfaces. The (sell) row's only ISK cost is the token LP-store fee, so it shows no ROI (like ISK/hour): its return is measured per LP, not per ISK. Both are hidden until the BPC control enables them.Warn
NICHE_DEMANDA contract-priced blueprint copy where one copy covers at least half a day of the built product's entire Jita demand (copy runs against the product's 28-day average daily volume). The whole market absorbs only a handful of fresh copies per day, so sale velocity — not LP/hour — caps what the offer can actually earn; the flag message states the copy-to-demand ratio.Warn
VANITYThe product is a vanity or cosmetic item: SDE apparel, SKIN, or personalization categories and groups, or a SKIN-named type.Warn; frontend chip from row metadata.
RISK_LOWSECBest known LP-store access is a low security station (see Risk And Access); highsec-accessible rows get no chip.Warn; frontend chip from row metadata.
RISK_NULLSECBest known LP-store access is null security or wormhole space.Strong; frontend chip from row metadata.
RISK_UNKNOWNNo known NPC station for the corporation, so the access risk tier is unknown.Strong; frontend chip from row metadata.

Tapping or clicking a flag chip on the leaderboard expands it into its full message; the ? inside links back to this section. Cargo-volume, vanity, and access-risk chips are added by the frontend from row metadata so they remain visible even when the persisted market-quality flags are otherwise clean.

Three quality filters interact with these flags:

Search And Grouping

The compute step materializes offer names, product signatures, risk/source fields, flag counts, ratios, and compact API summaries into calc, then rebuilds SQLite FTS search for offer and product names. Corporation filtering uses a name autocomplete: typing a corporation or faction name resolves it to a hidden corporation ID, and selecting one scopes the leaderboard to that single owner (relaxing the faction-warfare, special-source, and no-Security-agent guardrails for that owner, as noted under Risk and Access). Identical offer economics are grouped by default so duplicate corporation stores do not crowd out distinct opportunities; "Show duplicate stores" returns each store row.

Frontend Loading And Diagnostics

The LP page starts the rows, corporations, and health requests without blocking the browser page-load event. It renders skeleton rows for a first load, reuses session-cached rows immediately for repeated filters, ignores stale filter responses, and shows a compact topbar loading state only while the current request is still active.

A persistent browser client ID is shown in the header and sent as X-EVE-Client-Id on API calls. The server also returns a fresh X-Request-Id for every request and writes problem-only JSON lines for 4xx and 5xx responses to logs/http-problems.log. The visible client ID helps correlate a player report without exposing request IDs in the UI.

API And Health

Read endpoints are rate-limited to 180 requests per minute per IP and set permissive CORS. Public LP API paths work at both /api/* and /lp/api/*. /api/health reports fetcher freshness, empty core tables, database size, last compute time, and SDE import metadata. POST /api/refresh recomputes the leaderboard and requires X-Admin-Token.

After each compute, canonical leaderboard, CSV, and corporation responses are materialized into SQLite with ETags and Brotli bodies. Dynamic read responses use short browser caching and longer CDN caching, while health stays short-lived. When Cloudflare credentials are configured, compute purges the LP API prefixes; deploys that change unhashed LP HTML/CSS/JS should run the static purge helper after build.

Known Limitations