
:guide-id: single-cluster-introduction
:guide-parent: single-cluster
:guide-title: Single-cluster deployments
:guide-summary: Deploy a single Keycloak cluster, optionally across multiple availability-zones
:guide-priority: 999
:guide-tile-visible: true
:version: 26.4.0

include::../../attributes.adoc[]

[[single-cluster-introduction]]
= Single-cluster deployments

ifeval::["" == "true"]
WARNING: This {section} is describing a feature which is currently in preview.
ifeval::["" == ""]
Please provide your feedback while we’re continuing to work on this.
endif::[]
ifeval::["" != ""]
Please provide your feedback by link:[joining this discussion] while we’re continuing to work on this.
endif::[]
endif::[]


== When to use a single-cluster setup

The {project_name} single-cluster setup is targeted at use cases that:

* Deploy to an infrastructure with transparent networking, like for example a single {kubernetes} cluster.
* Desire all healthy {project_name} instances to handle user requests.
* Are constrained to a single
ifeval::[{project_product} == true]
region (e.g. a single AWS region)
endif::[]
ifeval::[{project_product} != true]
AWS Region or an equivalent low-latency setup.
endif::[]
* Permit planned outages for maintenance.
* Fit within a defined user and request count.
* Can accept the impact of periodic outages.
* Deployed in data centers with the required network latency and database configuration

[#single-cluster-tested-configuration]
== Tested Configuration

We regularly test {project_name} with the following configuration:

* An OpenShift cluster deployed across three AWS availability zones in the same region.
** Provisioned with https://www.redhat.com/en/technologies/cloud-computing/openshift/aws[Red Hat OpenShift Service on AWS] (ROSA),
using ROSA HCP.

** At least one worker node for each availability-zone
** OpenShift version 4.17.

* Amazon Aurora PostgreSQL database
** High availability with a primary DB instance in one availability zone, and synchronously replicated readers in the other availability zones
** Version 17.5

ifeval::[{project_product} == true]
* Support for {project_name} in these configurations may require replicating issues in this tested set up.
endif::[]

[#single-cluster-configuration]
== Configuration

ifeval::[{project_product} == true]

* {project_name} deployed on an OpenShift cluster version 4.17 or later
** For cloud setups, Pods can be scheduled across up to three availability zones within the same region
if OpenShift supports spanning multiple availability zones in that environment and {project_name}'s latency requirements are met.
** For on-premise setups, Pods can be scheduled across up to three datacenters
if OpenShift supports spanning multiple datacenters in that environment and {project_name}'s latency requirements are met.

endif::[]

ifeval::[{project_product} != true]

* {project_name} deployed on a {kubernetes} cluster
** For cloud setups, Pods can be scheduled across multiple availability zones within the same region
if {project_name}'s latency requirements are met.
** For on-premise setups, Pods can be scheduled across multiple datacenters
if {project_name}'s latency requirements are met.
* {project_name} deployed on virtual machines or bare metal
** Instances can be scheduled across multiple availability zones within the same cloud-provider region or multiple datacenters if {project_name}'s latency requirements are met.

endif::[]

* Deployments require a round-trip latency of less than 10 ms between {project_name} instances.

* Database
** For a list of supported databases, see link:{links_server_db_url}[{links_server_db_name}].
** Deployments spanning multiple availability zones must utilize a database that can tolerate zone failures
and synchronously replicates data between replicas.

ifeval::[{project_product} == true]
Any deviation from the configuration above is not tested and any issue with {project_name} may need to be replicated in a tested environment for support.
endif::[]
ifeval::[{project_product} != true]
While equivalent setups should work, you will need to verify the performance and failure behavior of your environment.
We provide functional tests, failure tests and load tests in the https://github.com/keycloak/keycloak-benchmark[Keycloak Benchmark Project].
endif::[]

Read more on each item in the link:{links_high-availability_single-cluster-building-blocks_url}[{links_high-availability_single-cluster-building-blocks_name}] {section}.

[#single-cluster-load]
ifeval::[{project_product} == true]

== Maximum load

* 100,000 users
* 300 requests per second

endif::[]
ifeval::[{project_product} != true]

== Tested load

We regularly test {project_name} with the following load:

* 100,000 users
* 300 requests per second

endif::[]

ifeval::[{project_product} != true]

We have successfully scaled to the following load:

* 100,000 users
* 1,000 logins, with 20,000 token refreshes per second.

We used the following setup for this:

* Single-cluster setup consisting of 6 Pods, spread across 3 availability zones in a single AWS region.
** Each Pod with limits of 40 vCPU and 8 GB memory
* Amazon Aurora PostgreSQL multi-az database deployed in two availability zones
** Instance type: `db.r8g.16xlarge` for both reader and writer instance

As the load increased, the CPU usage increased linearly.

endif::[]

See the link:{links_high-availability_single-cluster-concepts-memory-and-cpu-sizing_url}[{links_high-availability_single-cluster-concepts-memory-and-cpu-sizing_name}] {section} for more information.

[#single-cluster-limitations]
== Limitations

ifeval::[{project_product} != true]
Even with the additional redundancy of three availability-zones, downtime can still occur when:
endif::[]

* Simultaneous node failures occur
* Rolling out {project_name} upgrades
* Infrastructure fails, for example the {kubernetes} cluster

For more details on limitations see the link:{links_high-availability_single-cluster-concepts_url}[{links_high-availability_single-cluster-concepts_name}] {section}.

== Next steps

The different {sections} introduce the necessary concepts and building blocks.
For each building block, a blueprint shows how to deploy a fully functional example.
Additional performance tuning and security hardening are still recommended when preparing a production setup.

ifeval::[{project_product} != true]
== Concept and building block overview

* link:{links_high-availability_single-cluster-concepts_url}[{links_high-availability_single-cluster-concepts_name}]
* link:{links_high-availability_single-cluster-building-blocks_url}[{links_high-availability_single-cluster-building-blocks_name}]
* link:{links_high-availability_single-cluster-concepts-database-connections_url}[{links_high-availability_single-cluster-concepts-database-connections_name}]
* link:{links_high-availability_single-cluster-concepts-threads_url}[{links_high-availability_single-cluster-concepts-threads_name}]
* link:{links_high-availability_single-cluster-concepts-memory-and-cpu-sizing_url}[{links_high-availability_single-cluster-concepts-memory-and-cpu-sizing_name}]

== Blueprints for building blocks
* link:{links_high-availability_single-cluster-deploy-aurora_url}[{links_high-availability_single-cluster-deploy-aurora_name}]
* link:{links_high-availability_single-cluster-deploy-keycloak_url}[{links_high-availability_single-cluster-deploy-keycloak_name}]
endif::[]


