# Which Problems Are Solved The Vercel `docs` project generated ~64M ISR writes over 30 days (99.5% of ISR writes across all projects, ~\$258/month). Root causes in the Next.js 16 docs app: - `apps/docs/app/[[...slug]]/page.tsx` had `dynamicParams = true` + `revalidate = 3600`. Bot traffic hitting unknown URLs (`/docs/wp-admin`, `/docs/.env`, fuzzed paths) got rendered via \`notFound()\`, and the 404 response was cached as an ISR entry — 1 write per unique bad URL. Known pages were also rewritten hourly for no reason since content only changes on deploy. - `apps/docs/app/og/docs/[...slug]/route.tsx` had `revalidate = false` + empty `generateStaticParams()` + implicit `dynamicParams = true`. Every unique OG URL (including bot probes) was cached forever — writes accumulated permanently. # How the Problems Are Solved Switch the docs routes to pure SSG (content is static and only changes on deploy, so ISR provides no value): - `app/[[...slug]]/page.tsx`: `dynamicParams = false`, `revalidate = false`, `dynamic = 'force-static'`. Unknown URLs now return a static 404 at the CDN — no function invocation, no ISR write. All 390 pages from `source.generateParams()` are still pre-rendered. - `app/og/docs/[...slug]/route.tsx`: `generateStaticParams()` now returns all 390 pages via the existing `getPageImage(page).segments` helper, so every OG image is pre-built as a static asset. `dynamicParams = false` + `dynamic = 'force-static'` locks it down. - `app/llms-full.txt/route.ts`: added `dynamic = 'force-static'` as a safety net (already `revalidate = false`, single URL). The tradeoff is longer CI builds (~40s–2min for 390 OG image generations, paid on every preview deploy) in exchange for eliminating ~\$258/month in ISR writes plus associated function invocations and CPU time. # Additional Changes None. # Additional Context - No changes to `next.config.mjs`, `vercel.json`, or redirects. - Existing `apps/docs/redirects.json` (3,261 entries) covers legacy URLs so `dynamicParams = false` won't 404 moved pages linked from elsewhere. - Versioned routes: `content/versions.json` and `v*/` folders don't exist yet. When versioning is activated, `generateStaticParams()` in both files must also include `versionSource.generateParams()` — otherwise versioned URLs will 404 under `dynamicParams = false`. ## Test plan - [ ] CI build succeeds (expect modest build-time increase for OG pre-generation) - [ ] Inspect `apps/docs/.next/prerender-manifest.json` — all 390 doc routes + 390 OG routes listed with `initialRevalidateSeconds: false` - [ ] Local smoke: `/docs` → 200, `/docs/wp-admin` → 404 (static, no function), `/docs/og/docs/guides/start/image.png` → PNG, `/docs/og/docs/bogus/image.png` → 404 - [ ] Post-deploy: Vercel **ISR Writes** metric drops to near-zero within 24h - [ ] Post-deploy: Vercel **Function Invocations** for `/og/docs/*` drop to zero - [ ] Verify no legitimate docs pages 404 (cross-check logs against `apps/docs/app/sitemap.ts`) --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
The Identity Infrastructure for Developers
ZITADEL is an open-source identity and access management platform built for teams that need more than basic auth. Whether you're securing a SaaS product, building a B2B platform, or self-hosting a production IAM stack — ZITADEL gives you everything out of the box: SSO, MFA, Passkeys, OIDC, SAML, SCIM, and a battle-tested multi-tenancy model.
No vendor lock-in. No compromise on control. Just a robust, API-first identity platform you can own.
🏡 Website | 💬 Chat | 📋 Docs | 🧑💻 Blog | 📞 Contact
Why ZITADEL
We built ZITADEL to handle the hardest IAM challenges at scale — starting with multi-tenancy.
| ZITADEL | FusionAuth | Keycloak | Auth0/Okta | |
|---|---|---|---|---|
| Open-source | ✅ | ❌ | ✅ | ❌ |
| Self-hostable | ✅ | ✅ | ✅ | ❌ |
| Infrastructure-level tenants | ✅ Instances (High scale) | ✅ Tenants | 🟡 Realms (Scaling limits) | ❌ (Multi-tenant = multi-account) |
| B2B Organizations | ✅ Native & Unlimited | 🟡 via Entity Management | ✅ (Recent addition) | 🟡 (Plan/Account dependent) |
| Full audit trail | ✅ Comprehensive Event Stream* | 🟡 Audit logs | 🟡 Audit logs | 🟡 Audit logs |
| Passkeys (FIDO2) | ✅ | ✅ | ✅ | ✅ |
| Actions / webhooks | ✅ | ✅ | 🟡 via SPI | ✅ |
| API-first (gRPC + REST) | ✅ | 🟡 REST only | 🟡 REST only | 🟡 REST only |
| SaaS + self-host parity | ✅ | ✅ | ➖ N/A | ➖ N/A |
ZITADEL Cloud and self-hosted ZITADEL run the same codebase.
Key differentiators for architects:
- Relational core, event-driven soul — every mutation is written as an immutable event for a complete, API-accessible audit trail. Unlike systems that log only select activities, ZITADEL provides a comprehensive event stream that can be audited or streamed to external systems via Webhooks.
- Strict multi-tenant hierarchy — Identity System → Organizations → Projects, with isolated data and policy scoping at multiple levels
- API-first design — every resource and action is available via connectRPC, gRPC, and HTTP/JSON APIs
- Zero-downtime updates and horizontal scalability without external session stores
Get Started in 3 Minutes
ZITADEL Self-Hosted
# Docker Compose — up and running in under 3 minutes
curl -LO https://raw.githubusercontent.com/zitadel/zitadel/main/deploy/compose/docker-compose.yml \
&& curl -LO https://raw.githubusercontent.com/zitadel/zitadel/main/deploy/compose/.env.example \
&& cp .env.example .env \
&& docker compose up -d --wait
Full deployment guides:
Need professional support for your self-hosted deployment? Contact us.
ZITADEL Cloud (SaaS)
Start for free at zitadel.com — no credit card required. Available in US · EU · AU · CH. Pay-as-you-go pricing.
Integrate with the V2 API
ZITADEL exposes every capability over a typed API. Here's how to create a user with the V2 REST API:
curl -X POST https://$ZITADEL_DOMAIN/v2/users/human \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"username": "[email protected]",
"profile": { "givenName": "Alice", "familyName": "Smith" },
"email": { "email": "[email protected]", "sendCode": {} }
}'
Explore the full API reference — including connectRPC and gRPC transports — or jump straight to quickstart examples.
Features
Authentication
- Single Sign On (SSO) · Username/Password · Passkeys (FIDO2 / WebAuthn)
- MFA: OTP, U2F, OTP Email, OTP SMS
- LDAP · Enterprise IdPs and social logins
- OpenID Connect certified · SAML 2.0 · Device authorization
- Machine-to-machine: JWT Profile, PAT, Client Credentials
- Token exchange and impersonation
- Custom sessions for flows beyond OIDC/SAML
- Hosted Login V2
Multi-Tenancy
- Identity brokering with pre-built IdP templates
- Customizable B2B onboarding with self-service for customers
- Delegated role management to third parties
- Domain discovery
Integration
- gRPC, connectRPC, and REST APIs for every resource
- Actions: webhooks, custom code, token enrichment
- RBAC · SCIM 2.0 Server
- Audit log and SOC/SIEM integration
- SDKs and example apps
Self-Service & Admin
- Self-registration with email/phone verification
- Administration Console for orgs and projects
- Custom branding per organization
Deployment
- PostgreSQL (≥ 14) · Zero-downtime updates · High scalability
Track upcoming features on our roadmap and follow our changelog for recent updates.
Showcase
Login V2
Our new, fully customizable login experience — documentation
Adopters & Ecosystem
Used in production by organizations worldwide. See the full Adopters list — and add yours by submitting a pull request.
- SDKs: All supported languages and frameworks
- Examples: Clone and use our examples
How To Contribute
ZITADEL is built in the open and welcoming to contributions of all kinds.
- 📖 Read the Contribution Guide to get started
- 💬 Join the conversation on Discord
- 🐛 Report bugs or request features via GitHub Issues
Contributors
Made with contrib.rocks.
Security
Security policy: SECURITY.md
Vulnerability Disclosure Policy — how to responsibly report security issues.
Technical Advisories are published for major issues that could impact security or stability in production.
License
AGPL-3.0 — see LICENSING.md for the full licensing policy, including Apache 2.0 and MIT exceptions for specific directories.


