Skip to content

perf(db): cache schema types between builds - #947

Merged
atinux merged 1 commit into
mainfrom
perf/db-schema-types-cache
Oct 27, 2026
Merged

atinux merged 1 commit into
mainfrom
perf/db-schema-types-cache

Conversation

@atinux

@atinux atinux commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

An alternative to #946 for comparison. Written by an AI agent (Amp) on behalf of @atinux.

Each nuxt dev start runs tsc to generate hub/db/schema.d.mts, even when the schema has not changed. This PR caches the declarations instead of moving tsc to the background:

  • After a full build, schema.d.mts is copied to <buildDir>/cache/nuxthub/db/. A hash of its inputs is stored next to it. Nuxt keeps cache/ when it clears the build directory on dev and prepare.

  • The hash covers:

    • every local file the JS and declaration builds read, including type-only imports such as a $type<Meta>() interface
    • the versions of the packages the builds import (for example drizzle-orm)
    • the aliases the schema imports actually use
    • the TypeScript version

    Only the used aliases are hashed, because Nuxt aliases such as #app-manifest change on every prepare/build.

  • When the hash matches, only schema.mjs is built and the cached declarations are copied back. Otherwise the build runs as before.

The change is contained in buildDatabaseSchema, so dev, prepare, build, nuxt db and the schema watcher use the same path. There is no background work and no extra CPU, and a schema edit refreshes the types as fast as before.

Numbers

Playground (SQLite, 3 schema files), Node 24, 4-CPU Amp orb. Each round deletes playground/.nuxt, then starts nuxi dev playground twice:

  • The first start rebuilds everything. This PR has no cache yet, so it runs tsc like main.
  • The second start reuses .nuxt, which is the usual restart. This PR hits the cache.

The rounds alternate between the three branches. Each value is the median of 5 rounds.

main #946 this PR
Second start
types phase 2.95 s 1.11 s 1.13 s
"Ready in" 8.49 s 7.15 s 6.46 s
First HTML 18.3 s 16.5 s 15.7 s
CPU to first HTML 27.3 s 27.2 s 22.5 s
First start (no .nuxt)
types phase 3.52 s 1.22 s 3.12 s
"Ready in" 10.8 s 8.74 s 9.47 s
First HTML 23.4 s 20.0 s 19.2 s
CPU to first HTML 33.5 s 31.6 s 28.5 s

"First HTML" is measured from process start until GET / returns 200. "CPU" is user plus system time of the nuxi process tree at that moment. The orb is noisy: single runs of the same branch differ by up to about 30%, so read the medians as trends.

On the second start, #946 and this PR cut the types phase by the same amount. #946 still runs tsc in the background during startup, while this PR skips it. On the first start, #946 is ahead on "Ready in" because this PR still runs tsc in the foreground.

buildDatabaseSchema alone, on a small schema: 1.5 s without the cache, about 7 ms with it, and 0.7 s to rebuild after a change to a file imported only for its types.

Checks

  • New test: the cached types are reused, and a change to a file imported only for its types invalidates them. The test fails if that file is not tracked.
  • pnpm lint, vue-tsc --noEmit and pnpm test pass locally (167 passed, 3 skipped).

Generating hub/db/schema.d.mts runs tsc on every nuxt dev start, even when
the schema did not change. The declarations are now cached in
<buildDir>/cache/nuxthub/db (Nuxt keeps it when it clears the build dir)
together with a hash of their inputs: the files both builds read, including
type-only imports, the versions of the packages they import, the aliases
they use and the TypeScript version. When the hash matches, only schema.mjs
is built and the cached declarations are copied back.

Amp-Thread-ID: https://ampcode.com/threads/T-01a17c6c-89ae-70c3-904f-443b6c55256f
Co-authored-by: Sébastien Chopin <atinux@gmail.com>
@vercel

vercel Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
nuxthub Ready Ready Preview Oct 27, 2026 8:50am UTC

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
playground 7cd0640 Commit Preview URL

Branch Preview URL
Oct 27 2026, 08:50 AM

@pkg-pr-new

pkg-pr-new Bot commented Oct 27, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/@nuxthub/core@947

commit: 7cd0640

@atinux
atinux merged commit 4d12236 into main Oct 27, 2026
10 checks passed
@atinux
atinux deleted the perf/db-schema-types-cache branch October 27, 2026 10:01
@github-actions github-actions Bot mentioned this pull request Oct 27, 2026

This branch was successfully deployed

1 active deployment
Preview — 7cd06402 Deployed Oct 27, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants