Scale-to-zero Next.js on Knative
How a custom Operator, a declarative CRD, and Node.js bytecode compilation get production cold starts under a second — without locking you to a single cloud.
Serverless and Next.js have an awkward relationship. The framework wants a long-lived Node process; serverless platforms want to scale that process to zero when nobody's looking. knext-platform is my attempt to make the two get along on top of Knative, with no proprietary glue and no vendor lock-in.
The problem with cold starts
When a Knative service scales to zero, the next request pays for a full container start plus framework boot. For a naive Next.js image that's several seconds — unacceptable for user-facing traffic. The fix is to attack both halves: shrink the container start, and shrink the framework boot.
Scale-to-zero is only worth it if the first request after zero is fast enough that nobody notices it was ever zero.
A declarative deployment surface
Rather than hand-writing Knative YAML, knext-platform ships a Kubernetes Operator with a single custom resource. You describe intent; the operator reconciles the rest — Knative Service, scaling bounds, cache wiring, and storage adapters.
apiVersion: knext.dev/v1
kind: NextApp
metadata:
name: marketing-site
spec:
image: registry/marketing:v2.4.1
scaleToZero: true
cache:
backend: redis
invalidation: tag # O(1) tag-based
storage: gcs # or s3 | azure | minioThe operator follows a GitOps model: commit the NextApp manifest, and the cluster converges. No imperative kubectl apply dances at deploy time.
Sub-second boots with Node.js bytecode
The framework-boot half is solved by compiling the server to Node.js bytecode and warming Knative's resource cache. The combined effect is a first-request latency that stays in the same league as an always-on instance. A few principles guided the design:
- Precompile everything that can be precompiled; never parse on the hot path.
- Keep the image minimal — fewer layers, faster pulls, faster starts.
- Make caching a first-class spec field, not an afterthought bolted on later.
Does it hold up under load?
Load-tested to 100,000 requests at 100-way concurrency with a 0% error rate, scaling from zero and back without dropping a request. Portability is the other half of the story: the same manifest runs on GKE, EKS, AKS, or a bare on-prem cluster, with storage adapters for GCS, S3, Azure, and MinIO.
If you're running Next.js on Kubernetes and paying for idle, knext-platform is worth a look. It's open source — issues and PRs welcome.