Leftovers from the performance work merged on 2026-07-30 (#4519, #4520, #4521, #4527). None are urgent; all were found by review after the respective PR was already merged, or measured afterwards in production.
1. Is the new log index worth its cost?
IDX_b7eda1156aca7b2a1302cdf88f was added by #4519 to serve the overview chart query. Production, ~2 h after deploy:
| Index |
Size |
idx_scan |
IDX_b7eda1156aca7b2a1302cdf88f (new) |
42 MB |
20 |
IDX_log_financial_query (existing) |
46 MB |
16,672 |
The planner overwhelmingly picks the existing index. The measured win of #4519 came from no longer reading the ~43 kB message column (465 buffers instead of ~89,000), not from the new index — the chart query runs in 6.0 ms via IDX_log_financial_query.
Worth deciding whether 42 MB plus write cost on every log insert is justified for the remaining share, or whether the index should be dropped again.
2. Ledger master switch: test gaps (#4521)
crypto-input-cutover.integration.spec.ts:55 sets Config.ledger.enabled = true and never resets it. Its sibling staleness-cutover.integration.spec.ts does (afterEach). Not currently exploitable — each beforeEach builds a fresh ConfigService — but inconsistent.
ledger-master-switch.spec.ts discovers cron entry points via @DfxCron metadata only. A ledger job written with Nest's native @Cron would not be discovered and would silently escape the completeness check. transaction-request.service.ts:52 shows native @Cron is in use elsewhere in the codebase.
- The same discovery uses
getOwnPropertyNames(prototype), while the production scanner walks the prototype chain. A cron on an inherited method would be missed. No ledger service uses extends today.
3. Non-finite prices pass through the dashboard aggregation silently (#4520)
buildLatestBalance multiplies plusBalance.total by priceChf. Moving off the JSON round-trip means a non-finite price now reaches the arithmetic directly instead of being normalised to null on the way.
Production check at the time: of 430 asset rows, 0 hold NaN or Infinity, 144 hold NULL — and NULL multiplies to zero, same as before. So this is not reachable today.
A Number.isFinite guard was deliberately rejected: booking a broken price as zero is exactly the masking this codebase avoids. Logging loudly when a non-finite price enters the aggregation would close the gap without inventing a value.
4. AsyncCache.invalidate() can be outlived by an in-flight refresh
async-cache.ts:42-56: a refresh started before invalidate() writes its result back afterwards, with a fresh timestamp. In a narrow window an invalidation can therefore be undone for up to a full TTL.
Pre-existing, and it applies to every CachedRepository consumer, not to one call site. Relevant because FiatService.updatePrice() relies on invalidation taking effect immediately. A generation counter incremented on invalidate(), checked before the write-back, would fix it.
Leftovers from the performance work merged on 2026-07-30 (#4519, #4520, #4521, #4527). None are urgent; all were found by review after the respective PR was already merged, or measured afterwards in production.
1. Is the new
logindex worth its cost?IDX_b7eda1156aca7b2a1302cdf88fwas added by #4519 to serve the overview chart query. Production, ~2 h after deploy:idx_scanIDX_b7eda1156aca7b2a1302cdf88f(new)IDX_log_financial_query(existing)The planner overwhelmingly picks the existing index. The measured win of #4519 came from no longer reading the ~43 kB
messagecolumn (465 buffers instead of ~89,000), not from the new index — the chart query runs in 6.0 ms viaIDX_log_financial_query.Worth deciding whether 42 MB plus write cost on every
loginsert is justified for the remaining share, or whether the index should be dropped again.2. Ledger master switch: test gaps (#4521)
crypto-input-cutover.integration.spec.ts:55setsConfig.ledger.enabled = trueand never resets it. Its siblingstaleness-cutover.integration.spec.tsdoes (afterEach). Not currently exploitable — eachbeforeEachbuilds a freshConfigService— but inconsistent.ledger-master-switch.spec.tsdiscovers cron entry points via@DfxCronmetadata only. A ledger job written with Nest's native@Cronwould not be discovered and would silently escape the completeness check.transaction-request.service.ts:52shows native@Cronis in use elsewhere in the codebase.getOwnPropertyNames(prototype), while the production scanner walks the prototype chain. A cron on an inherited method would be missed. No ledger service usesextendstoday.3. Non-finite prices pass through the dashboard aggregation silently (#4520)
buildLatestBalancemultipliesplusBalance.totalbypriceChf. Moving off the JSON round-trip means a non-finite price now reaches the arithmetic directly instead of being normalised tonullon the way.Production check at the time: of 430
assetrows, 0 holdNaNorInfinity, 144 holdNULL— andNULLmultiplies to zero, same as before. So this is not reachable today.A
Number.isFiniteguard was deliberately rejected: booking a broken price as zero is exactly the masking this codebase avoids. Logging loudly when a non-finite price enters the aggregation would close the gap without inventing a value.4.
AsyncCache.invalidate()can be outlived by an in-flight refreshasync-cache.ts:42-56: a refresh started beforeinvalidate()writes its result back afterwards, with a fresh timestamp. In a narrow window an invalidation can therefore be undone for up to a full TTL.Pre-existing, and it applies to every
CachedRepositoryconsumer, not to one call site. Relevant becauseFiatService.updatePrice()relies on invalidation taking effect immediately. A generation counter incremented oninvalidate(), checked before the write-back, would fix it.