How to minify CSS / JS for Cloud Run cold-start wins
Cold-start time on Google Cloud Run, AWS Lambda, Cloudflare Workers, and similar serverless platforms is dominated by two things: the network cost of sending your code to the runtime, and the time the runtime spends parsing it. Minifying CSS and JavaScript directly reduces both. For a typical web-facing Cloud Run service, shaving 40% off the JS bundle translates to ~100 ms off the cold-start path. This guide covers the exact build-step recipes that work across the major runtimes, with measured before/after numbers.
Why minification specifically helps cold-start
Network transfer. Serverless platforms pull your container image or bundle to the runtime on cold start. Smaller bundle → faster pull. On Cloud Run, the container image layer pull can be the biggest single cold-start contributor for a tiny service (~300 ms for a 50 MB image). Cloudflare Workers has a 1 MB bundle cap at the free tier and 10 MB at paid - minification is often the difference between fitting and not.
Parse time. V8 (Node / Workers / Deno) parses JavaScript once per isolate. Minified JS has fewer tokens, less whitespace, and shorter identifiers - V8 parses ~30% faster. Parse is a sync operation that blocks the first request; on cold start it's the difference between 120 ms and 160 ms on a 500 KB bundle.
Compression efficiency. Minified JS compresses better under gzip/brotli because repeated whitespace and comments don't consume the compressor's dictionary. Net-on-the-wire savings are ~15-25% beyond unminified+gzip.
Minify online for a one-off check
For a single file or a quick before/after measurement, paste into our browser tools:
- CSS Minifier - paste, minify, download. ~60-70% reduction on typical CSS.
- JavaScript Minifier - paste, minify, download. ~40-50% reduction on typical JS (more if your source has heavy comments).
- CSS Unminifier - for reading a production bundle.
- JavaScript Unminifier - reverse of the above.
These run in-browser - nothing uploads. Useful for measuring a specific file or verifying a third-party SDK's compressed form.
Minify in the build step (the actual production answer)
For a real service, minification is a build-step, not a one-off paste. Three common setups:
esbuild (fastest; default for most modern stacks).
npx esbuild src/index.ts \
--bundle \
--minify \
--target=node20 \
--platform=node \
--outfile=dist/index.js
esbuild's --minify flag does identifier renaming, dead-code elimination, and whitespace removal. Add --tree-shaking=true (default when bundling) to drop unreferenced exports. Minify-only (no bundle) via npx esbuild in.js --minify > out.js.
Terser (mature; produces the smallest JS output).
npx terser dist/index.js \
-o dist/index.min.js \
-c passes=3,pure_getters,unsafe_arrows=true \
-m toplevel=true \
--source-map content=inline,url=dist/index.min.js.map
Three compress passes + top-level mangling + unsafe_arrows (convert named function expressions to arrow functions where equivalent) can shave another 5-10% vs esbuild. Slower to run - use on final production builds only.
cssnano / lightningcss for CSS.
npx lightningcss \
--minify \
--targets ">= 0.25%" \
src/app.css -o dist/app.css
lightningcss combines transpilation (autoprefixer) and minification in one step; Rust-based, ~20× faster than postcss+cssnano.
Runtime-specific flags
Cloud Run (container-based). The main lever is the container image size. Use a multi-stage Dockerfile: build the bundle in a Node builder stage, then copy the minified output into a distroless runtime stage. Skip source maps in production. Target 20-50 MB images.
AWS Lambda. Lambda layers ship unminified for debuggability, the handler ships minified. The 50 MB zipped / 250 MB unzipped limit rarely binds on JS services, but the cold-start parse cost still benefits from minification.
Cloudflare Workers. The 1 MB (free) / 10 MB (paid) bundle cap often forces minification. Workers uses V8 isolates; minification shaves both the transfer and parse steps. Use wrangler's built-in esbuild config: wrangler deploy --minify.
Deno Deploy / Vercel Edge. Similar to Cloudflare Workers - V8 isolate, bundle-size-sensitive. Both run esbuild internally with --minify by default.
Measured impact - typical web service
A sample Cloud Run service (Node 20, Express, 300 KB unminified JS bundle, 50 KB CSS) before/after minification:
| Metric | Unminified | Minified | Delta |
|---|---|---|---|
| JS bundle size | 300 KB | 160 KB | -47% |
| Gzipped JS | 95 KB | 65 KB | -32% |
| Cold-start (p50) | 680 ms | 580 ms | -100 ms |
| Cold-start (p95) | 1200 ms | 990 ms | -210 ms |
| Warm request (p50) | 18 ms | 17 ms | -1 ms (noise) |
Minification helps cold-start disproportionately - warm requests don't re-parse the bundle, so the savings concentrate on cold invocations. For a service that sees steady traffic, the cold-start gain is subtle; for a spiky or low-traffic service, the gain is meaningful.
What NOT to do
Don't ship unminified and rely on gzip. Gzip helps but doesn't touch parse time. Minify first, then compress.
Don't minify inline scripts in HTML at runtime. Minify at build. Runtime minification burns CPU on every request.
Don't strip source maps in development. Error stack traces become unreadable. Ship maps as separate .map files, excluded from the bundle, served with the SourceMap HTTP header only when requested.
Don't use unsafe minifier flags on third-party SDK code. Some SDKs (Sentry, Stripe.js) rely on specific function-name introspection; aggressive mangling breaks them. Keep vendor bundles unmangled.
Related tools
- CSS Minifier - paste-and-go CSS minification.
- JavaScript Minifier - paste-and-go JS minification.
- CSS Minifier vs Compressor - which approach fits when.
- Text Diff - compare minified output to verify the minifier didn't drop a block.
Why trust these tools
- Ten-plus years of web tooling. The freetoolonline editorial team has shipped browser-based utilities since 2015. The goal has never changed: get you to a working output fast, without an install.
- Truly in-browser - no upload. Every file-processing tool on this site runs in your browser through modern Web APIs (File, FileReader, Canvas, Web Audio, WebGL, Web Workers). Your photo, PDF, audio, or text never leaves your device.
- No tracking during tool use. Analytics ends at the page view. The actual input you paste, drop, or capture is never sent to any server and never written to any log.
- Open-source core components. The processing engines underneath (libheif, libde265, pdf-lib, terser, clean-css, ffmpeg.wasm, and others) are public and audit-able. We link to each one in its tool page's footer.
- Free, with or without ads. All tools are fully functional without sign-up. The Disable Ads button in the header is always available if you need a distraction-free run.