Back to Blog
Tutorial10 min read2026-07-31

Deploying an Astro Site with Faster Builds Through Caching

Speed up Astro static site builds by 60% with dependency caching—how PandaStack's build cache works and how to verify it's active.

Ajay Kumar
Ajay Kumar
Founder & DevOps, PandaStack

Astro is a static site generator optimized for performance, but when your site grows to hundreds of pages or uses heavy integrations (React, Vue, Tailwind), builds can take 2-3 minutes. Most of that time is spent installing dependencies, not generating pages. PandaStack caches node_modules between builds, cutting install time from 90 seconds to under 10 on subsequent deploys.

This post shows how to deploy an Astro site to PandaStack, how the build cache works, and how to verify it's speeding up your builds.

A minimal Astro site

Start with a fresh Astro project:

npm create astro@latest
cd my-astro-site
npm install

Run the dev server:

npm run dev

Build the static site:

npm run build

Astro generates a dist/ directory containing the static HTML, CSS, and JS. This is what you deploy to the CDN.

Deploying to PandaStack

Create a pandastack.json at the repo root:

{
  "type": "static",
  "language": "nodejs",
  "buildCommand": "npm run build",
  "outputDir": "dist"
}

Push the repo to GitHub, then deploy via the API:

curl -X POST https://api.pandastack.io/v1/projects \
  -H "Authorization: Bearer psk_live_your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "static",
    "name": "astro-site",
    "repositoryName": "yourusername/astro-site",
    "branch": "main",
    "autoDeploy": true
  }'

The build runs, the dist/ directory is uploaded to the CDN, and you get a live URL like https://astro-site-xyz.pandastack.app.

Alternatively, use the deploy button:

[![Deploy to PandaStack](https://dashboard.pandastack.io/deploy-button.svg)](https://dashboard.pandastack.io/deploy?repo=yourusername/astro-site&type=static)

How build caching works

PandaStack runs builds in ephemeral Kubernetes Job pods. After the first build, the builder archives node_modules/ and uploads it to Google Artifact Registry. On the next build:

  1. 1The builder downloads the cached node_modules.tar.gz
  2. 2Extracts it to the build directory
  3. 3Runs npm install (which detects the cache and skips unchanged packages)
  4. 4Runs npm run build

If package-lock.json hasn't changed, npm install completes in under 10 seconds instead of 90. The build time drops from 2 minutes to under 40 seconds—most of the remaining time is Astro generating pages.

The cache is project-specific and branch-specific. Deploying a different branch starts with a cold cache. Changing package-lock.json invalidates the cache, and the next build reinstalls all dependencies.

Verifying the cache is active

Check the build logs in the dashboard (Logs tab). The first build shows:

Installing dependencies...
npm install
...
added 1234 packages in 87s

The second build (same package-lock.json) shows:

Restoring cached dependencies...
npm install
...
up to date, audited 1234 packages in 8s

The "Restoring cached dependencies" line confirms the cache was used. If you don't see this, the cache may be disabled or the package-lock.json changed between builds.

Forcing a fresh build

If you suspect the cache is stale (e.g., a package updated but the lock file didn't change), clear the cache in the dashboard:

Project Settings → Clear Build Cache

The next build reinstalls all dependencies from scratch and rebuilds the cache.

Package manager support

PandaStack detects the package manager from the lock file:

  • package-lock.json → npm
  • pnpm-lock.yaml → pnpm
  • yarn.lock → yarn
  • bun.lockb → bun

Caching works for all four. Pnpm and Yarn have built-in caching mechanisms, so the cache is especially effective with those.

If you're using pnpm and want to override the install command (e.g., to skip optional dependencies), set it in pandastack.json:

{
  "type": "static",
  "buildCommand": "pnpm install --frozen-lockfile && pnpm run build",
  "outputDir": "dist"
}

But the default auto-detection is usually sufficient.

When caching doesn't help

The build cache only speeds up dependency installation. If your build is slow because:

  • Astro is generating 10,000 pages
  • You're compiling Tailwind CSS with a massive config
  • You're processing large images with Sharp

Then caching node_modules won't help much. The install step is already fast (10 seconds), and the slow part is page generation. In that case, optimize the build itself—enable Astro's experimental build caching, reduce the number of generated pages, or use a faster image processor.

Comparing build times

Here's a real example from an Astro blog with 200 pages and React integration:

BuildInstall timeBuild timeTotal
First (cold cache)87s54s141s
Second (warm cache)9s54s63s
Third (warm cache, no code changes)9s54s63s

Caching cuts total build time by 55%. The install step drops from 87s to 9s, while the build step (page generation) stays constant at 54s.

For a Next.js static export with a similar page count, the improvement is even larger because Next.js has more dependencies.

Why this matters

Netlify, Vercel, and Cloudflare Pages all cache dependencies between builds, but they don't document how it works or give you manual cache invalidation. PandaStack's cache is explicit: you see "Restoring cached dependencies" in the logs, and you can clear it if needed.

The free tier includes 300 build pipeline minutes per month. With caching, a 2-minute build becomes a 1-minute build, effectively doubling your build quota. Paid plans increase the quota to 1000+ minutes, but caching reduces the need to upgrade.

Multi-framework support

The same caching logic works for any framework that uses node_modules:

  • Astro, Next.js, Nuxt, Gatsby (static site generators)
  • Vite, Parcel, Webpack (bundlers)
  • React, Vue, Svelte (component frameworks)

The only requirement is that the build installs dependencies before running npm run build. If you're using a custom build script that skips npm install, the cache won't help.

Deploy button with caching

The deploy button automatically benefits from caching. No additional config needed:

[![Deploy to PandaStack](https://dashboard.pandastack.io/deploy-button.svg)](https://dashboard.pandastack.io/deploy?repo=yourusername/astro-site)

The first user to click it gets a cold build (90 seconds). The second user (if they deploy the same commit) gets a warm build (10 seconds). This makes open-source starters and templates deploy faster for everyone.

Common issues

Cache not restored: Verify package-lock.json exists and is committed to the repo. If it's missing, npm generates a new one on every build, invalidating the cache.

Install still slow: Check the logs for errors like "peer dependency warnings" or "postinstall scripts". Some packages run slow postinstall hooks that can't be cached.

Build fails after clearing cache: The cache may have hidden a dependency issue (e.g., a package that's installed but not in package.json). Fix the dependency and rebuild.

Full example repo

package.json:

{
  "name": "astro-site",
  "scripts": {
    "dev": "astro dev",
    "build": "astro build"
  },
  "dependencies": {
    "astro": "^4.0.0"
  }
}

pandastack.json:

{
  "type": "static",
  "buildCommand": "npm run build",
  "outputDir": "dist"
}

README.md:

# Astro Site

[![Deploy to PandaStack](https://dashboard.pandastack.io/deploy-button.svg)](https://dashboard.pandastack.io/deploy?repo=yourusername/astro-site)

An Astro static site with fast cached builds.

Push this to GitHub, click the deploy button, and the first build takes ~90 seconds. The second build takes ~30 seconds.

References

  • [Astro Documentation](https://docs.astro.build/)
  • [npm Cache Documentation](https://docs.npmjs.com/cli/v10/commands/npm-cache)
  • [PandaStack Build System](https://docs.pandastack.io/projects/builds)

Ready to deploy?

Start free on PandaStack.

Start free on PandaStack

More in Tutorial

Browse all Tutorial articles →

See also