From 875b7f17dab576557e0bc47106c5a2458cd6b86a Mon Sep 17 00:00:00 2001 From: Md-Humair-KK Date: Thu, 16 Oct 2025 13:06:14 +0530 Subject: [PATCH] resource calculator Signed-off-by: Md-Humair-KK --- .../resource_calculator.md | 95 ++++++++++++++++++ .../resource_calculator.xlsx | Bin 0 -> 15665 bytes 2 files changed, 95 insertions(+) create mode 100644 performance-test/resource-calculator/resource_calculator.md create mode 100644 performance-test/resource-calculator/resource_calculator.xlsx diff --git a/performance-test/resource-calculator/resource_calculator.md b/performance-test/resource-calculator/resource_calculator.md new file mode 100644 index 000000000..88f3b79e4 --- /dev/null +++ b/performance-test/resource-calculator/resource_calculator.md @@ -0,0 +1,95 @@ +# eSignet Resource Calculator - Mock IDA + +This Resource Calculator is designed to help estimate the CPU, RAM, and Storage required for deploying the eSignet system in a given country or environment. The calculator leverages key assumptions, performance data, and buffer considerations to provide a comprehensive and scalable resource plan. + +--- + +## 1. Overview + +The **eSignet Resource Calculator** is intended to guide the teams in planning and provisioning resources for eSignet deployments. The data is based on: +- Country-specific population and usage metrics. +- Performance benchmarks from the eSignet team. +- Calculations for necessary buffers (monitoring, logging, Kubernetes overhead, etc.). + +> **Legend:** +> - Blue: Data added by country +> - Green: Data added by performance team +> - Orange: Data calculated as per country input + +--- + +## 2. Data Inputs + +### To Be Provided by Country + +| Assumptions | Example Value | +|--------------------------------------------------------------------------------|:--------------:| +| Total Population Having Registered National ID | 4,000,000 | +| Percentage of Population using National ID for authentication | 50% | +| Percentage of Population using National ID for authentication during peak hour | 50% | + +These values should be customized for your country's context. + +--- + +## 3. Population based on the data provided + +- **Total Population using National ID for authentication:** + `Registered Population × % Using for Authentication` + _Example:_ 4,000,000 × 50% = 2,000,000 + +- **Total Population using National ID for authentication during peak hour:** + `Population using for Authentication × % During Peak Hour` + _Example:_ 2,000,000 × 50% = 1,000,000 + +- **Expected Peak Hour TPS (Transactions Per Second):** + `Total Population using National ID for authentication during peak hour/3600` + _Example:_ 1,000,000 / 3600 = 277.77 = 278(approx.) + +--- + +## 4. Total TPS and Resources Used during eSignet Performance execution +This section is about the performance baselines considerations for 100TPS performance run. + +i.e for the current resource calculator it is 106 virtual users and 1 relying party completing 25000 OIDC flows, matching the expected peak hour TPS of 278 with a factor of 3. + +--- + +## 5. Computations for the total resources required +To support a workload of 100 transactions per second (TPS) and accommodate peak hour demands, a comprehensive service-wise resource breakdown is shown in the report. + +To ensure system reliability and operational readiness, buffer allocations were added to +Monitoring, Logging, and Alerts, Kubernetes Infrastructure, System Buffer. + +Combining all components, the total resources required ensuring robust performance and scalability under peak conditions are shown. + +--- + +## 6. Storage +The Postgres DB size is computed considering, 1 user per relying party consumes 2.5KB of size to store user consent for total OIDC flows and factor to match peak hour TPS (OIDC flows x 2.5 KB x factor) + +Maximum memory recorded in redis cache for total OIDC flows along with 20% buffer is considered for redis cache computations. + +Logs size is computed considering logs generated for total OIDC flows and calculated per OIDC flow. + +Startup & Liveness Logs is the logs generated while bringing up the esignet service. + +> **Note:** Additional storage may be required for infra logging and system buffer. The calculator provides estimates, but actual sizing should be validated in production or enterprise environments. + +--- + +## 7. Usage Instructions + +1. **Input Data:** + Update the input assumptions according to your country's statistics. + +2. **Review Calculations:** + The calculator will automatically compute the required resources based on your inputs. + +3. **Interpret Results:** + Use the computed vCPU, RAM, and storage requirements to plan your cloud or on-premise infrastructure. + +4. **Buffer Appropriately:** + The calculator includes buffer recommendations, but you may adjust them based on your operational policies. + +--- \ No newline at end of file diff --git a/performance-test/resource-calculator/resource_calculator.xlsx b/performance-test/resource-calculator/resource_calculator.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..116eb3b3ce83f445cab246388c713547974e600d GIT binary patch literal 15665 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

U>o|@@ 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