Skip to main content

Production Setup

As soon as you successfully deployed ZITADEL as a proof of concept using one of our deployment guides, you are ready to configure ZITADEL for production usage.


We created a Production Checklist as a technical step by step guide.

High Availability

We recommend running ZITADEL highly available using an orchestrator that schedules ZITADEL on multiple servers, like Kubernetes. For keeping startup times fast when scaling ZITADEL, you should also consider using separate jobs with zitadel init and zitadel setup, so your workload containers just have to execute zitadel start. Read more about separating the init and setup phases on the Updating and Scaling page.


Read on the configure page about the available options you have to configure ZITADEL.



By default, metrics are exposed at /debug/metrics in OpenTelemetry (otel) format.

Also, you can enable tracing in the ZITADEL configuration.

# Choose one in "otel", "google", "log" and "none"
Type: google
Fraction: 1
MetricPrefix: zitadel


Prefer CockroachDB

ZITADEL supports CockroachDB and PostgreSQL. We highly recommend using CockroachDB, as horizontal scaling is much easier than with PostgreSQL. Also, if you are concerned about multi-regional data locality, the way to go is with CockroachDB.

Configure ZITADEL

Depending on your environment, you maybe would want to tweak some settings about how ZITADEL interacts with the database in the database section of your ZITADEL configuration. Read more about your database configuration options.

Host: localhost
Port: 26257
Database: zitadel
MaxOpenConns: 20
MaxConnLifetime: 30m
MaxConnIdleTime: 30m
Options: ""

You also might want to configure how projections are computed. These are the default values:

RequeueEvery: 60s
RetryFailedAfter: 1s
MaxFailureCount: 5
ConcurrentInstances: 1
BulkLimit: 200
MaxIterators: 1
BulkLimit: 2000

Manage your Data

When designing your backup strategy, it is worth knowing that ZITADEL is event sourced. That means, ZITADEL itself is able to recompute its whole state from the records in the table The timestamp of your last record in the events table defines up to which point in time ZITADEL can restore its state.

The ZITADEL binary itself is stateless, so there is no need for a special backup job.

Generally, for maintaining your database management system in production, please refer to the corresponding docs for CockroachDB or for PostgreSQL.

Data Initialization

  • You can configure instance defaults in the DefaultInstance section. If you plan to eventually create multiple virtual instances, these defaults take effect. Also, these configurations apply to the first instance, that ZITADEL automatically creates for you. Especially the following properties are of special interest for your production setup.
AccessTokenLifetime: 12h
IdTokenLifetime: 12h
RefreshTokenIdleExpiration: 720h #30d
RefreshTokenExpiration: 2160h #90d
# this configuration sets the default email configuration
# configuration of the host
#for example
# if the host of the sender is different from ExternalDomain set DefaultInstance.DomainPolicy.SMTPSenderAddressMatchesInstanceDomain to false