Resolve the org's icons on the server and preconnect the origin
Lighthouse named theme.kamocrm.com as an unconnected origin worth 300 ms while also reporting no origins preconnected, and last round I read that as a stale com...
Stop three route bundles being prefetched onto the homepage
Lighthouse's 103 KiB of "unused JavaScript" named four chunks, two of them essentially 100% unused. None of them appear in the homepage's HTML — they are other ...
Name the backdrop widths, and read the theme config on the server
Two findings, both of which were doing something other than what the code said. THE BACKDROP WAS FETCHING THE 1920 CANDIDATE. 149 KB, for a decorative picture ...
Compress the images harder, hold the cards still, drop duplicate requests
Images. Every quality setting on the page goes down a step, and the allow-list in next.config.ts goes to [30, 50] so nothing can quietly ask for more: hero...
Split the hero, and take the last two libraries off the page
Step C. Neither GSAP nor Framer Motion is on the homepage any more, and the `home` message namespace is no longer sent to the browser at all. JS 24...
Seven sections stop hydrating
Step B. TrustBar, WhatReplacesWhat, HowItWorks, UseCases, Features, CTAStrip and Pricing are server components now. They render to HTML and ship no JavaScript. ...
Take the animation runtime off the homepage entirely
Step A of the hydration work. Framer Motion is gone from the homepage's eager bundle: 798,723 -> 687,593 bytes raw, 245,367 -> 209,422 gzip. That is 35,945 fewe...
Stop rendering eight off-screen sections before the hero can paint
LCP was 4.4 s, and its breakdown said where: 120 ms to first byte, 290 ms of load delay, 390 ms actually downloading the image — and then 1,810 ms of "element r...
Undo the two changes that cost 380ms of blocking time, and quiet the phone
The last two rounds took the score from 87 to 67. Total Blocking Time went from 80 ms to 460 ms and LCP from 3.9 s to 4.4 s. Two of my own changes did that, and...
Move the headline sweep onto the compositor, and the chat widget off load
Two things left over from the last round, both flagged rather than done because each trades something. Doing them now. THE HEADLINE'S LIGHT PASS. It was a seco...
Inline the stylesheet, and drop polyfills nothing can reach
Two Lighthouse findings, both of which stayed open after the last round because I had concluded they were not addressable. They were; I had not looked hard enou...
Stop shipping 1.8 MB of unresized backgrounds after hydration
ThemedBackground was the most expensive thing left on the homepage, and none of it looked like a bug. It rendered a raw <img> straight at the theme bucket, so t...
Stop the fold waiting on hydration, and clear the load window
The homepage shipped its whole fold invisible. Framer Motion serialises an `initial` prop into the prerendered HTML as an inline style, so the markup arrived wi...
Seek the one candidate block instead of scanning back to the table start
/api/send took 1.8-7.9 s for most addresses and single-digit ms for a few, which is not a load problem — it is the shape of the geolite query. getLocation() is ...
Stop the analytics tracker hijacking every link but Home
Every page except the homepage took seconds to open, and the reason was never in this app's own navigation path: the server prerenders, prefetch payloads are co...
Drop the sitewide loading boundary that only secondary pages paid for
Every page except the homepage felt slow, which points straight at the (pages) subtree — and at something I put there. When 4fae924 added (pages)/loading.tsx ev...
Prerender the changelog count, refresh it on publish instead of on visit
Every visitor was fetching this number themselves. PreviewBanner lives in the shared layout, so on every page it hit /api/changelog/today after hydration, waite...
Stop prefetching a megabyte per page, and stop calling the backend for free
Two costs that were paid on every page, both found by following the reporter's own hunch about i18n and needless backend calls. PREFETCH VOLUME — a regression ...
Stop every page switch waiting on a redirect and a 2s fade-in
The prerendering work in 4fae924 fixed the server and the router, and the site still felt like it took 1-2 seconds to change pages. It was never the network. Tw...
Prerender the routes again and give a navigation something to paint
The locale layout resolved its messages with a bare getMessages(), which reads request headers and so opted the ENTIRE app out of static rendering. With no load...
Resolve each handler's platform annotation once
The interceptor is registered for /** so the annotation lookup ran on every request this service serves, sign-in included, and AnnotatedElementUtils walks the m...
Ask for the unread count, not the whole folder tree
The mail badge needs one integer and was fetching every folder in the mailbox to find it, which on the IMAP providers is the most expensive call the mail backen...
Stop making the inbox wait on two lookups it can see the answer to
Two round trips still sat in front of a rendered inbox, and by this point they were the only thing left there — the folder tree and the first page already arriv...
Ask earlier, ask once, and stop asking for what has not changed
Three more things standing between opening /messages and seeing mail. Nothing was requested until the bundle had landed. /messages pulls several megabytes of J...
Stop paying for a key nothing reads, and stop waiting to ask
Three things were slowing /messages down before a single message was fetched. Every email call made a round trip to /api/generate-otk first and sent the result...
Stop opening every folder, and stop refetching every message
Two round-trip problems on the /messages critical path, both invisible in the code that caused them. listFolders opened each folder read-only to read two integ...
Fetch the summary slices' to-one associations and count instead of scanning
The Overview's attention and recent slices read a title per row off a LAZY @ManyToOne, costing up to 16 extra selects per block under open-session-in-view. All ...
Refresh planner statistics after the weekly GeoLite rebuild
YugabyteDB does not auto-analyze, and the staging+rename swap replaces geolite_blocks wholesale -- so after every Sunday sync the planner had no statistics for ...
Geolite range index must be ASC, not YugabyteDB's default HASH
The IP lookup is a range scan: WHERE network_start <= ? ORDER BY network_start DESC LIMIT 1 YugabyteDB partitions the LEADING index column by HASH unless tol...
Geolite range index must be ASC, not YugabyteDB's default HASH
The IP lookup is a range scan: WHERE network_start <= ? ORDER BY network_start DESC LIMIT 1 YugabyteDB partitions the LEADING index column by HASH unless tol...
Give YugabyteDB real resources and pin its memory
It was running on LESS than the CockroachDB it replaced -- 20Gi/6cpu against CockroachDB's 32Gi/8cpu -- while needing more, because YSQL runs a separate Postgre...
Give YugabyteDB real resources and pin its memory
It was running on LESS than the CockroachDB it replaced -- 20Gi/6cpu against CockroachDB's 32Gi/8cpu -- while needing more, because YSQL runs a separate Postgre...
Hash with BLAKE3 only, so skipping the upload actually saves time
Dedup worked — the server logged 'linked WITHOUT upload' and 358 MB never left the machine — but the member still waited, because computing SHA3-256 alongside B...
Accept a BLAKE3-only claim so dedup is faster than uploading
The link endpoint demanded both hashes. A browser has no fast SHA3-256, so proving it already had a 358 MB file took ~20 seconds against an 18.8 second upload —...
Match stored content on BLAKE3 alone, so a browser can afford to ask
Proving possession required both hashes, and a browser has no fast SHA3-256 — js-sha3 is pure JavaScript at ~25 MB/s. Measured on a 358 MB video that was ~20 se...
Read the latest snapshot date without loading the history
A summary needs one date. It was reading it by loading a two-year range of snapshots and taking the max — five domains times every day of history, on every page...
One plan-matrix scan per app-catalog request
Also drops the now-unused DevelopmentStageType import and corrects the auto-provision comment, which still described the stage rule the catalog replaced.
Answer the plan-matrix question for every app in one pass
The Apps & Features tab asks whether each app appears in the plan matrix, and the per-app form scans the plan-feature and add-on tables once per app — two dozen...
Stop re-querying call history per extension when the provider is instance-wide
RingCentral's endpoint is extension/~ and ignores the argument, so it returns the same log for every extension. Once a page adds nothing new, the remaining exte...
Create mlos_doc_req_borrower_idx for the vault cross-loan reuse query
Index (borrower_uid, organization_id) for vault cross-loan reuse query
Stop per-boot customer_id FK tug-of-war in SchemaCleanupRunner
Remove the stale RetailCustomer->Account cleanup drops of commerce_carts.customer_id, **************** and **************** Those columns are now live, Hibernat...
Lower PoW difficulty (cost 1000, counter 2000-4000)
Solve cost is the product of CHALLENGE_COST x counter range; both were over-cranked (~37.5M PBKDF2 rounds, ~40-75x a stock Capcha), making the widget slow on lo...
Tier 2 — Hikari + RestTemplate timeouts + Stripe SDK + Redis cache
- RestClientConfig: single shared RestTemplate bean with 5s connect / 30s read timeouts. MediaServiceClient / NotificationDispatchService / OfacSanctionsSer...
Paged repo queries + countByStatus for hot paths
- LoanRepository: countByStatus / countByOrganizationAndStatus + Page<Loan> findByStatus(...) / **************** / **************** + **************** for...
Merge partial DTOs into local state, drop refetch-after-patch
Every edit-style autosave (name fields, employment, assets, liabilities, REO, declarations, military, HMDA demographics, originator) used to issue a full mortga...
Collapse pipeline kanban N+1 to a single grouped count query
listForOrganization() used to issue one condition-fetch per loan (201 queries at 200 loans). Now a single grouped JPQL aggregate keyed by loanFile.uid projects ...
Store geo on ticket at creation, drop GeoLite reads
**************** now captures the visitor's geo once (via GeoLookupService) and persists ip/country/city/subdivision on the SupportTicket itself. SupportTicket...
Bulk-load visitors and skip GeoLite lookup in list
The /api/support/tickets list endpoint was running, per page of 20 rows: - 20 **************** calls (N+1) - 20 calls into GeoLookupService.lookup, each of ...
Add findBySessionGuidIn for bulk loading
Used by the support-ticket list endpoint to fetch all visitors for a page in one query instead of N separate findBySessionGuid calls.
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.