Deployment Recommendations
Overview
This document describes the Digital Identity Service deployment best practices. For detailed information on Digital Identity Service configuration, installation and features, please refer to our main technical documentation.
System requirements
| While the following requirements are minimal (e.g.: we require some disk space for the app itself, logging and configuration), please refer to the performance measurements page for detailed results on varying configurations. |
Rocky Linux 9.x (64-bit)
A CPU supporting the AVX2 instruction set
Unless agreed otherwise, the machine hosting the Digital Identity Service needs to be able to access the URL innovatrics.count.ly.
Minimal system requirements
CPU: 4 vCPU
RAM: 8 GB
DISK: 7 GB
GPU system requirements
Since version 1.71.0, the Digital Identity Service is also distributed as a GPU image, tagged <version>-gpu-amd64. To run it, the node needs:
An x86-64 (amd64) CPU. The GPU image is not built for ARM64.
An NVIDIA GPU supported by CUDA 11.8. Our measurements use the NVIDIA L4 (AWS g6 instances).
The NVIDIA driver and the NVIDIA Container Toolkit installed on the host. The image contains the CUDA 11.8 and cuDNN 8 runtime, but not the driver.
See GPU compute for configuration and sizing.
License
There are different methods for obtaining the license for Digital Identity Service below and above version 1.20.0 of the project. To access additional information, please refer to our technical documentation for detailed license information.
| If you want to exchange license, the Digital Identity Service instance needs to be restarted. The bearer token should not be hardcoded, new license will also change your token. |
Monitoring
To ensure the optimal performance and stability of Digital Identity Service and cache infrastructure, we strongly recommend to use a monitoring tool.
We have good experience with Prometheus for monitoring purposes and Apache JMeter, that we employed for our performance testing. However, the choice of monitoring and testing tools is ultimately up to you, based on your project’s specific requirements and preferences.
Digital Identity Service version upgrading
Upgrading the Digital Identity Service on live production may cause temporary cache inconsistencies. To avoid these issues, we strongly recommend scheduling a maintenance window for the upgrade.
Scaling
The Digital Identity Service is recommended to be scaled horizontally. Multiple service instances can utilize either a shared cache or a cache cluster. If the DIS service is scaled horizontally, you can usually achieve higher throughput or lower latency if your server is overloaded.
| We strongly recommend using compute-optimized instances (eg. AWS C6a.xlarge) for scaling. |
| We suggest deploying at least two instances of the Digital Identity Service and cache to enhance availability. |
| Maintain software version and configuration consistency across all Digital Identity Service within cluster. Different versions and configurations of Digital Identity Service instances within cluster might cause compatibility issues and unexpected behavior. |
| To minimize network latency and improve the overall performance of your application, we recommend hosting Digital Identity Service instances and Cache in the same (or nearest) region as middleware when using a cloud-based hosting solution like AWS. |
GPU compute
Since version 1.71.0, the Digital Identity Service can run its most demanding neural network models on an NVIDIA GPU. The GPU image is released alongside the CPU images, with the same version and the same API.
Runs on the GPU: face processing (detection, comparison, age estimation, passive and active liveness, deepfake detection) and document presentation attack detection (document liveness, portrait overlay).
Stays on the CPU: document classification, OCR, barcode reading and NFC evaluation.
On the GPU, face calls get much faster, while document calls take the same time as on CPU. For example, a trust evaluation with passive liveness took 6.2 s on a CPU-only deployment and 0.85–1.0 s on the GPU at twice the load. A document page upload took about 2 s in both setups.
GPU configuration
The GPU image runs on the CPU until the GPU backends are switched on. The face models and the document models are configured separately:
Property | Description |
|---|---|
innovatrics.dot.dis.internal.iface.global-parameters | |
| Backend of the face models. If |
| Index of the CUDA device. Default: |
innovatrics.dot.dis.internal.document.onnx.session | |
| Where the document models run. If |
| Index of the CUDA device. Default: |
| Optional limit of GPU memory for the document models, in bytes. |
| Optional cuDNN convolution algorithm search: |
The backend each model actually runs on is logged at start-up. We recommend enabling the model warm-up (available since version 1.70.0) on GPU instances, so that the first requests are not slowed down by model loading.
Scaling with CPU and GPU node pools
A GPU node is cost-efficient only for the work that runs on the GPU. Document processing does not get faster on a GPU node, so the most efficient deployment runs two node pools behind one Digital Identity Service address:
A CPU pool on compute-optimized instances serves documents, pages, NFC and customer management.
A GPU pool serves the face calls: selfie, liveness, customer inspection, trust evaluation, face similarity and the Faces API.
The client keeps calling a single URL. A layer 7 router (a service mesh, an ingress controller or a load balancer with path-based rules) sends each request to a pool by its URL path. This example rule matches the face calls. Everything else goes to the CPU pool:
^/api/v1/customers/[^/]+/(selfie|liveness|inspect|trust-evaluation|similarity)(/.*)?$ ^/api/v1/faces(/.*)?$
The rule matches only the path segment right after the customer ID. /api/v1/customers/{id}/inspect goes to the GPU pool, while /api/v1/customers/{id}/document/inspect stays on the CPU pool.
+----------------------+
Client ------------>| Layer 7 router |
(one DIS URL) | path-based rule |
+----------+-----------+
face calls | everything else
+--------------------+--------------------+
v v
+----------------------+ +----------------------+
| GPU pool | | CPU pool |
| DIS GPU image | | DIS CPU image |
| selfie, liveness, | | customers, documents,|
| inspect, trust eval. | | pages, NFC |
+----------+-----------+ +-----------+----------+
| |
+------------------+----------------------+
v
+-----------------------+
| Shared cache cluster |
+-----------------------+Both pools must use the same cache. One onboarding moves between the pools: the documents are processed on the CPU pool and the selfie on the GPU pool, and both read the same customer record.
| Both pools must run the same Digital Identity Service version and the same configuration, except for the image and the GPU properties above. |
| The CPU pool runs the full Digital Identity Service, so it can serve all requests on its own. A cost-efficient setup keeps the CPU pool for the base load and adds the GPU pool when the load grows, for example by autoscaling. When the GPU pool is scaled to zero, remove or disable its routing rule as well, so that face calls fall back to the CPU pool. |
Sizing for a desired throughput
The following measurements were made on AWS in eu-central-1 for an onboarding with a selfie and passive liveness, a two-sided ID document, NFC reading and a trust evaluation:
CPU pool: c7a.2xlarge (8 vCPU, AMD)
GPU pool: g6.2xlarge (8 vCPU, one NVIDIA L4)
| Work | Cost per onboarding |
|---|---|
Document work (CPU pool) | 6.4–6.8 CPU core-seconds with production-like documents |
Face work (GPU pool) | 0.25 CPU core-seconds and 0.044 GPU-seconds |
From these measurements:
One c7a.2xlarge in the CPU pool handles about 0.75 onboardings per second when the face work runs on the GPU pool. When it also runs the face work, it handles about 0.33 onboardings per second.
One g6.2xlarge handles the face work of about 17 onboardings per second with passive liveness.
Multi-range liveness is much more demanding on the GPU pool: one g6.2xlarge handles about 1.5 onboardings per second. Size the GPU pool for this method separately. Calls slow down sharply when more than about 30 requests are in flight on one instance, so scale out by instances rather than by load per instance.
To size the pools for a target throughput:
CPU pool: divide the target onboardings per second by 0.75, and round up.
GPU pool: divide the target by 17 for passive liveness, or by 1.5 for multi-range liveness, and round up. Add one instance so that the pool survives the loss of a node.
| Deployment | Instances | Relative compute cost |
|---|---|---|
CPU only | 37 × c7a.2xlarge | 100 % |
GPU only | 7 × g6.8xlarge | about 100 % |
CPU and GPU node pools | 16 × c7a.2xlarge + 2 × g6.2xlarge | about 57 % |
A GPU-only deployment costs about the same as a CPU-only one, because the document work does not get faster on the GPU. Splitting the work between two pools lowers the compute cost of the Digital Identity Service by about 43 %.
| The mix of work depends on your process. An authentication with a selfie only loads almost exclusively the GPU pool, while an onboarding with documents and NFC loads mainly the CPU pool. Measure your own process before you size the pools. |
Cache
The Digital Identity Service currently supports Redis, Memcached and EhCache as the cache options.
Redis is our preferred cache option over Memcached due to its high availability characteristics.
For development and test purposes, the embedded EhCache is also available. However, please note that this option is not suitable for production or an environment with multiple Digital Identity Service instances.
You can also use cloud-based cache service (e.g.: AWS Elasticache) to minimize the need for managing and maintaining a dedicated cache infrastructure.
| We recommend to use at least two cache instances to achieve higher availability. |
| Various tools exist to monitor the performance of your Redis or Memcached server, and we recommend using one to ensure the cache is performing as expected. |
| To maintain independence and optimize resource utilization, you should deploy different cache options on a separate cluster. Cache infrastructure and Digital Identity Service instances should also run on separate machines. |
Cache performance recommendations
For optimal performance, configure the expiration of records according to the nature of the implemented process:
Short expiration time causes smaller memory usage and higher throughput of short requests.
Long expiration time enables longer processing of cached records and higher memory requirements.
Memory consumption for longer processes can be lowered by cleaning records once no longer needed. The API provides deletion methods for each resource.
Size the network bandwidth of the cache, not only its memory and CPU. Every Digital Identity Service call reads the whole customer record from the cache, including its images. An onboarding with a two-sided ID document and NFC transfers about 29 MB between the Digital Identity Service and the cache, so 6 onboardings per second need about 1.4 Gbit/s. Burstable cache instances can sustain such traffic only until their burst credits run out.
Common cache record expiration configuration
Every cache option supports setting the expiration time for both customer and face records. The expiration time can be configured independently for all of these resources. The configuration is described in the table below:
Property | Description |
|---|---|
innovatrics.dot.dis.persistence.cache | |
The time in seconds to persist all data created and used by Onboarding API. Example value: 1800 | |
The time in seconds to persist face records created and used by Face API. | |
Redis
The Digital Identity Service supports Redis as a cache option in various setups which depend on the configuration of your environment. The Lettuce client is used for communication with Redis.
| We require the Redis server to be of version 7.x.x. Using older versions or a higher major version may result in an unexpected behavior. |
Minimal Redis requirements
Version: 7.x.x
We recommend two nodes with the following configuration:
CPU: 2 vCPU
RAM: 3 GB
Redis environments
The following Redis environment setups are supported:
Standalone - The standalone mode is the simplest mode of operation. It is suitable for development and testing environments.
Master/Replica - The master/replica mode is suitable for production environments. The client is configured in a way where the reads are set to be preferred on the replicas.
Cluster The cluster mode is suitable for high-performance production environments with the need for automatic failover.
| Ensure that the expiration time for Redis records is accurately configured to optimize memory usage. To access additional information, please refer to our technical documentation for Redis cache configuration properties. |
Memcached
Minimal Memcached requirements
We recommend two nodes with the following configuration:
CPU: 2 vCPU
RAM: 3 GB
| Ensure that the expiration time for Memcached records is accurately configured to optimize memory usage. To access additional information, please refer to our technical documentation for Memcached cache configuration properties. |
EhCache
This cache option intended for development and test purposes only. Each instance of Digital Identity Service runs its own embedded EhCache, which is not shared between other instances. This means that running multiple Digital Identity Service instances in cluster mode will lead to unexpected behavior.
You can set the maximum memory size for the embedded cache through configuration properties. This includes options for both Java heap and off-heap memory. While Java heap memory is faster for I/O operations, it incurs a performance cost due to Java garbage collection. For the Digital Identity Service, this performance difference is expected to be negligible.
| The off-heap-size property is used to set the maximum allocation size in megabytes for Java off-heap memory. If the off-heap-size property is not specified, the cache will exclusively utilize Java heap memory. To access additional information, please refer to our technical documentation for EhCache configuration properties. |
Docker
The Digital Identity Service running inside the container, built from Dockerfile, runs under dot-dis user and not as root user. This may cause issues with files and directories mounted from outside the docker container (e.g. logs directory). To overcome this issue, ensure that the user’s UID (User ID) on the host machine, who owns the file or directory, matches the UID of the dot-dis user, which is 1000.
Alternatively, you have the option to build the Docker container using the root-user.Dockerfile, which runs Digital Identity Service under the root user and does not have this limitation.
The JVM configuration can be customized using the JAVA_OPTS environment variable when running the Docker container. This can be useful when adjusting parameters like Java max heap memory size.
Example use:
docker run -e JAVA_OPTS="-Xmx1024m" -v /local/path/to/license/dir/:/srv/dot-digital-identity-service/license -v /local/path/to/config/dir/:/srv/dot-digital-identity-service/config -v /local/path/to/logs/dir/:/srv/dot-digital-identity-service/logs -p 8080:8080 dot-digital-identity-service
To access additional information, please refer to docker section in our technical documentation.
Conclusion and Final Recommendations for Deploying DIS
The Digital Identity Service is recommended to be scaled horizontally.
Cache clusters and Digital Identity Service instances should be on separate machines.
Different cache options should be on separate clusters.
Our caching options are Redis, Memcached and EhCache.
EhCache should be used for development and test purposes only.
Our preferred caching option is Redis.
If the off-heap-size property is not specified, the cache will exclusively utilize Java heap memory.
If you want to exchange license, the Digital Identity Service instance needs to be restarted.
The bearer token should not be hardcoded, new license will also change your token.
We highly suggest employing at least two Cache and Digital Identity Service instances to improve availability.
Software version and configuration of Digital Identity Service instances within a cluster should be consistent.
To ensure the optimal performance and stability of Digital Identity Service and cache infrastructure, we strongly recommend to use a monitoring tool.
The JVM configuration can be customized using the JAVA_OPTS environment variable when running the Docker container.
We strongly recommend using compute-optimized instances for scaling.
Since version 1.71.0, the GPU image runs face processing and document presentation attack detection on an NVIDIA GPU. OCR and document processing stay on the CPU.
For high throughput, run a CPU pool for document work and a GPU pool for face work behind one address, routed by URL path, with a shared cache.
Size the CPU pool by the document work and the GPU pool by the face work. Size the GPU pool separately for multi-range liveness.
Size the network bandwidth of the cache for the full customer record read on every call.
We recommend scheduling a maintenance window for the upgrade to avoid cache problems.