The Lighthouse CI link in the PR is dead
A pull request from last month says "Performance dropped to 61, see
report" and links to a storage.googleapis.com URL. It returns an error
now. Nobody deleted it — it was built to disappear.
What temporary-public-storage is
lhci upload --target=temporary-public-storage is the default in most
Lighthouse CI setup guides because it needs no account and no server.
It uploads each report to public storage Google runs for the project
and prints a link. Two properties come with it:
| Property | What it means |
|---|---|
| Temporary | Reports are deleted after a few days. LHCI's docs describe it as for trying out |
| Public | Anyone with the link can open it — URL, screenshots, request list, console log |
So every link you pasted into a PR, a Jira ticket or a client email has a lifetime of days. The second property matters for staging and internal pages: the report lists every resource URL the page requested, including internal API hosts.
Can you recover it?
From temporary storage, no. Look in two places before re-running:
- The CI artifact. If the job uploaded
.lighthouseci/(or youroutputDir), thelhr-*.jsonandlhr-*.htmlfiles are in it — while the artifact is inside its retention window. - Your terminal or CI log. LHCI prints a short score summary per URL. It is not the report, but it is the number someone quoted.
Re-running Lighthouse on the old commit gives you a report, not the report: third-party scripts, the CDN and the runner have all changed, and Lighthouse varies by several points between identical runs anyway.
Keeping the next one
Option 1: run the LHCI server
lhci server (Node, with SQLite, Postgres or MySQL) stores every build,
draws score history per URL and compares any build against its base
branch. Upload with --target=lhci --serverBaseUrl=…. It is the
complete answer if you will operate one more service — it needs a host,
a database, backups and an upgrade path, and it is a dashboard for the
team, not something to send a client.
Option 2: filesystem plus artifacts
# lighthouserc.yml
ci:
collect:
url: [https://staging.example.com/]
numberOfRuns: 3
upload:
target: filesystem
outputDir: ./lhci-report
Then upload lhci-report/ as a CI artifact. Private, free, and still
temporary — GitHub keeps artifacts 90 days by default, GitLab 30 — and a
zip is not a link anyone outside CI will open.
Option 3: publish the representative run
Write to the filesystem as above, then publish the median run's HTML to
an address that does not expire. Create the report once, keep its id in
a CI variable, and PATCH it every build:
HTML=$(jq -r '.[] | select(.isRepresentativeRun) | .htmlPath' lhci-report/manifest.json | head -1)
curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$COMMA_REPORT_ID" \
-H "Authorization: Bearer $COMMA_API_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n --rawfile html "$HTML" '{html: $html}')"
One URL per page for the life of the project, each build kept as a revision you can diff, access limited to named people or your email domain, and comments on the specific audit ("this one first"). Setup per CI provider is in publish from CI.
If the people reading it are not engineers, the full Lighthouse report
is a lot. The Lighthouse report viewer
turns any lhr-*.json into a shorter page — scores, Core Web Vitals,
and only the audits that failed, ordered by savings — and copies a
Markdown summary for the PR comment.
Which to choose
| You need | Use |
|---|---|
| To try LHCI on a public site this afternoon | temporary-public-storage |
| Score history and base-branch comparison in CI | LHCI server |
| Raw results for a later job | filesystem + artifact |
| A link a client, PM or future you can open | Publish the report |
Related
- Lighthouse report viewer — Lighthouse JSON to a readable report
- Core Web Vitals — LCP, INP, CLS and the Lighthouse score weights
- The CI artifact link expired — retention and the other three deleters
- Publish from CI — one curl per provider