{
  "version": "1.0.0",
  "lastUpdated": "2026-05-08",
  "description": "Omnicore dimensioning rules. Self-contained — a third-party tool can reproduce the dimensioning calculator's output using only this file plus the input values. Source of truth for src/components/DimensioningCalculator/index.js.",
  "url": "https://docs.omnitouch.com.au/dimensioning-rules.json",

  "inputs": {
    "voiceDataSubscribers": {
      "default": 400000,
      "unit": "subscribers",
      "description": "Subscribers using both voice and data. Drives IMS/voice infrastructure."
    },
    "dataOnlySubscribers": {
      "default": 100000,
      "unit": "subscribers",
      "description": "Subscribers using data only (IoT, data tablets)."
    },
    "billedCustomers": {
      "default": 500000,
      "unit": "customers",
      "description": "Total billable customer accounts. Drives OmniCRM and OmniCharge."
    },
    "occupancy": {
      "default": 0.7,
      "unit": "fraction",
      "min": 0,
      "max": 1,
      "description": "Fraction of subscribers active during the busy hour. ITU-T E.500 methodology. Mature 0.6–0.8, emerging 0.5–0.7."
    },
    "talkTimePercentage": {
      "default": 0.04,
      "unit": "fraction",
      "min": 0,
      "max": 1,
      "description": "Fraction of an hour an active subscriber spends on a voice call during the busy hour. 0.04 ≈ 40 mErl/sub."
    },
    "smsPerHour": {
      "default": 2,
      "unit": "messages/active-sub/hour",
      "description": "Average P2P SMS per active subscriber during the busy hour."
    },
    "downlinkGbps": {
      "default": 10,
      "unit": "Gbps",
      "description": "Total downlink throughput. Auto-calculated by default — see autoCalculations.downlinkGbps."
    },
    "uplinkGbps": {
      "default": 2,
      "unit": "Gbps",
      "description": "Total uplink throughput. Auto-calculated by default — see autoCalculations.uplinkGbps."
    },
    "uniquePdnSessions": {
      "default": null,
      "unit": "sessions",
      "description": "Simultaneous PDN sessions. Auto-calculated by default — see autoCalculations.uniquePdnSessions."
    },
    "redundancyFactor": {
      "default": 0.3,
      "unit": "fraction",
      "description": "Extra compute for failover and growth. 1.0 = N+1 with two hosts, 0.5 = three hosts, 0.33 = four hosts."
    },
    "networkType": {
      "default": "MNO",
      "enum": ["MNO", "MVNO"],
      "description": "MNO has its own RAN/EPC anchor; MVNO defers MME and SGW-C to the host operator."
    }
  },

  "derivedSubscribers": {
    "formula": "voiceDataSubscribers + dataOnlySubscribers",
    "description": "Total active subscribers — used everywhere capacity scales with subscriber count."
  },

  "autoCalculations": {
    "uniquePdnSessions": {
      "formula": "round(subscribers * occupancy * 1.8)",
      "description": "1.8x multiplier for multi-PDN devices (default APN + IMS APN + tethering, etc.)."
    },
    "downlinkGbps": {
      "formula": "subscribers * occupancy * 0.00005",
      "description": "50 Kbps per active subscriber during the busy hour. Ericsson Mobility Report / 3GPP TR 36.942 typical."
    },
    "uplinkGbps": {
      "formula": "downlinkGbps * 0.2",
      "description": "Typical mobile uplink:downlink ratio."
    }
  },

  "signalingTraffic": {
    "description": "Real-world signaling rates measured from a 1M-subscriber network over 1 hour. The calculator sums all message types per protocol, applies a 2x safety margin, then divides by 3600 and 1,000,000 to get TPS-per-subscriber.",
    "safetyMargin": 2,
    "diameterMessagesPer1MSubsPerHour": {
      "Authentication-Information": 836930,
      "Update-Location": 389401,
      "Cancel-Location": 248053,
      "Notify": 215781,
      "Purge-UE": 43425,
      "Insert-Subscriber-Data": 624
    },
    "c7MessagesPer1MSubsPerHour": {
      "SendAuthenticationInfo": 389559,
      "UpdateLocation": 346759,
      "CancelLocation": 270378,
      "UpdateGprsLocation": 137338,
      "MT-ForwardSM": 35468,
      "MO-ForwardSM": 10572,
      "PurgeMS": 10075,
      "MT-ForwardSM-2": 1481,
      "ReadyForSM": 934,
      "AuthenticationFailureReport": 457,
      "ProvideSubscriberInfo": 202,
      "InsertSubscriberData": 196,
      "DeleteSubscriberData": 130,
      "ProvideRoamingNumber": 100,
      "InterrogateSS": 90,
      "ProcessUnstructuredSS-Request": 18,
      "SendParameters": 5,
      "ActivateSS": 1,
      "DeactivateSS": 1
    },
    "derivations": {
      "tpsDiameter": "subscribers * (sum(diameterMessagesPer1MSubsPerHour) * safetyMargin) / 3600 / 1_000_000",
      "tpsC7": "subscribers * (sum(c7MessagesPer1MSubsPerHour) * safetyMargin) / 3600 / 1_000_000",
      "tpsOCS": "tpsC7 * 2 (zero if billedCustomers == 0)"
    }
  },

  "vmTemplates": {
    "base": {
      "cpu": 4,
      "ramMB": 8192,
      "storageGB": 50,
      "description": "Standard VM template — used by all 'standard' tier components."
    },
    "highPerf": {
      "cpu": 8,
      "ramMB": 32768,
      "storageGB": 50,
      "description": "High-performance VM template — used by all 'highPerformance' tier components."
    }
  },

  "capacityConstants": {
    "hss_tps": 400,
    "upf_gbps": 8,
    "tas_minutes": 6000,
    "crm_subscribers": 100000,
    "charge_tps": 200,
    "dra_tps": 1000,
    "stp_tps": 500,
    "hlr_tps": 500,
    "pgwc_sessions": 100000,
    "sgwc_sessions": 100000,
    "mme_subscribers": 200000,
    "scscf_subscribers": 32000,
    "icscf_subscribers": 32000,
    "pcscf_subscribers": 32000,
    "smsc_sms": 180000
  },

  "vmComponents": {
    "description": "Each component's 'required' instance count is its load divided by its capacity. 'recommended' = max(ceil(required), 2) — minimum two for HA. Some components are static (fixed at 2).",
    "highPerformance": [
      {
        "name": "OmniHSS",
        "link": "/docs/repos/OmniCore/hss",
        "loadFormula": "tpsDiameter + tpsC7",
        "capacityKey": "hss_tps",
        "storageGB": 50,
        "additionalStorageGB": 50
      },
      {
        "name": "OmniUPF",
        "link": "/docs/repos/OmniCore/omniupf",
        "loadFormula": "downlinkGbps + uplinkGbps",
        "capacityKey": "upf_gbps",
        "storageGB": 50,
        "additionalStorageGB": 0
      },
      {
        "name": "OmniTAS",
        "link": "/docs/repos/OmniCall/IMS-ApplicationServer",
        "loadFormula": "voiceDataSubscribers * occupancy * talkTimePercentage * 60",
        "loadFormulaNote": "Minutes/hour — calculator uses voiceDataSubscribers (not total subscribers).",
        "capacityKey": "tas_minutes",
        "storageGB": 50,
        "additionalStorageGB": 50
      },
      {
        "name": "OmniCRM",
        "link": "/docs/repos/OmniCharge/OmniCRM",
        "loadFormula": "subscribers",
        "capacityKey": "crm_subscribers",
        "storageGB": 50,
        "additionalStorageGB": 150,
        "excludeIf": "billedCustomers == 0"
      },
      {
        "name": "OmniCharge",
        "link": "/docs/repos/OmniCharge",
        "loadFormula": "tpsOCS",
        "capacityKey": "charge_tps",
        "storageGB": 50,
        "additionalStorageGB": 50,
        "excludeIf": "billedCustomers == 0"
      }
    ],
    "standard": [
      {
        "name": "OmniDRA",
        "link": "/docs/repos/OmniCore/dra",
        "loadFormula": "tpsDiameter",
        "capacityKey": "dra_tps",
        "storageGB": 30,
        "excludeIf": "subscribers < 1000"
      },
      {
        "name": "OmniSS7 (STP)",
        "link": "/docs/repos/OmniCall/elss7",
        "loadFormula": "tpsC7",
        "capacityKey": "stp_tps",
        "storageGB": 30,
        "excludeIf": "subscribers < 1000 || voiceDataSubscribers == 0"
      },
      {
        "name": "OmniSS7 (HLR)",
        "link": "/docs/repos/OmniCall/elss7",
        "loadFormula": "tpsC7",
        "capacityKey": "hlr_tps",
        "storageGB": 30,
        "excludeIf": "voiceDataSubscribers == 0"
      },
      {
        "name": "OmniPGW (Control)",
        "link": "/docs/repos/OmniCore/pgw_c",
        "loadFormula": "uniquePdnSessions",
        "capacityKey": "pgwc_sessions",
        "storageGB": 30
      },
      {
        "name": "OmniSGW (Control)",
        "link": "/docs/repos/OmniCore/sgw_c",
        "loadFormula": "uniquePdnSessions",
        "capacityKey": "sgwc_sessions",
        "storageGB": 30,
        "excludeIf": "networkType == 'MVNO'"
      },
      {
        "name": "MME",
        "loadFormula": "subscribers",
        "capacityKey": "mme_subscribers",
        "storageGB": 30,
        "excludeIf": "networkType == 'MVNO'"
      },
      {
        "name": "S-CSCF",
        "link": "/docs/repos/OmniCall/cscf_UI",
        "loadFormula": "subscribers",
        "capacityKey": "scscf_subscribers",
        "storageGB": 30,
        "excludeIf": "voiceDataSubscribers == 0"
      },
      {
        "name": "I-CSCF",
        "link": "/docs/repos/OmniCall/cscf_UI",
        "loadFormula": "subscribers",
        "capacityKey": "icscf_subscribers",
        "storageGB": 30,
        "excludeIf": "voiceDataSubscribers == 0"
      },
      {
        "name": "P-CSCF",
        "link": "/docs/repos/OmniCall/cscf_UI",
        "loadFormula": "subscribers",
        "capacityKey": "pcscf_subscribers",
        "storageGB": 30,
        "excludeIf": "voiceDataSubscribers == 0"
      },
      {
        "name": "OmniSEP",
        "link": "/docs/repos/OmniCall/OmniSEP",
        "static": 2,
        "storageGB": 30,
        "excludeIf": "voiceDataSubscribers == 0"
      },
      {
        "name": "VisualVoicemail",
        "link": "/docs/repos/OmniCall/VisualVoicemail",
        "static": 2,
        "storageGB": 30,
        "excludeIf": "voiceDataSubscribers == 0"
      },
      {
        "name": "DNS Server",
        "static": 2,
        "storageGB": 30
      },
      {
        "name": "OmniMessage",
        "link": "/docs/repos/OmniCall/sms_c",
        "loadFormula": "voiceDataSubscribers * occupancy * smsPerHour",
        "loadFormulaNote": "SMS/hour — calculator uses voiceDataSubscribers (not total subscribers).",
        "capacityKey": "smsc_sms",
        "storageGB": 50,
        "additionalStorageGB": 0,
        "excludeIf": "voiceDataSubscribers == 0"
      },
      {
        "name": "Monitoring / OAM",
        "static": 2,
        "storageGB": 30,
        "additionalStorageGB": 220
      }
    ]
  },

  "smallDeployment": {
    "threshold": "subscribers < 1000",
    "cpuRamScale": 0.25,
    "description": "Below 1000 subscribers, total CPU & RAM are scaled to 1/4 since each VM is sized down. Storage is unchanged. OmniDRA and OmniSS7 (STP) are also excluded — see vmComponents.standard.excludeIf."
  },

  "totalsDerivation": {
    "description": "Per-server-type aggregation. The recommended (rounded-up) totals drive sizing displays; the required (un-rounded) totals drive redundancy math.",
    "totalHpVms": "sum(highPerformance.recommended)",
    "totalStandardVms": "sum(standard.recommended)",
    "totalVCpu": "(totalHpVms * vmTemplates.highPerf.cpu + totalStandardVms * vmTemplates.base.cpu) * smallDeploymentScale",
    "totalRam": "(totalHpVms * vmTemplates.highPerf.ramMB + totalStandardVms * vmTemplates.base.ramMB) / 1024 * smallDeploymentScale",
    "totalStorage": "sum over all VMs of recommended * (storageGB + (additionalStorageGB || 0))",
    "totalVCpuWithRedundancy": "totalVCpuRequired * (1 + redundancyFactor)",
    "totalRamWithRedundancy": "totalRamRequired * (1 + redundancyFactor)"
  },

  "serverSizing": {
    "bareMetal": {
      "description": "Pack many Omnitouch VMs onto each physical host via Proxmox. Servers needed = max across CPU, RAM, storage dimensions.",
      "serversByCpu": "ceil(totalVCpuWithRedundancy / server.cpu)",
      "serversByRam": "ceil(totalRamWithRedundancy / server.ram)",
      "serversByStorage": "ceil(totalStorage / server.storage)",
      "serversRequired": "max(serversByCpu, serversByRam, serversByStorage)",
      "totalCost": "serversRequired * server.price"
    },
    "cloud": {
      "description": "Per-NF: each Omnitouch VM = one cloud instance (no nested virt on standard EC2/Compute Engine). Standard-tier VMs use the 'base' instance; high-perf VMs use the 'highPerf' instance.",
      "instancesRequired": "totalStandardVms + totalHpVms",
      "totalCost": "totalStandardVms * perNfInstances.base.monthlyPrice + totalHpVms * perNfInstances.highPerf.monthlyPrice"
    }
  },

  "serverOptions": [
    {
      "id": "dell-r650",
      "vendor": "Dell",
      "model": "PowerEdge R650",
      "type": "Purchase",
      "cpu": 128,
      "ram": 512,
      "storage": 4000,
      "price": 15000,
      "priceUnit": "one-time",
      "description": "2U, 2x Intel Xeon Gold 6338, 512GB RAM, 4TB NVMe"
    },
    {
      "id": "dell-r750",
      "vendor": "Dell",
      "model": "PowerEdge R750",
      "type": "Purchase",
      "cpu": 160,
      "ram": 1024,
      "storage": 8000,
      "price": 25000,
      "priceUnit": "one-time",
      "description": "2U, 2x Intel Xeon Platinum 8380, 1TB RAM, 8TB NVMe"
    },
    {
      "id": "dell-r660",
      "vendor": "Dell",
      "model": "PowerEdge R660",
      "type": "Purchase",
      "cpu": 96,
      "ram": 384,
      "storage": 2000,
      "price": 12000,
      "priceUnit": "one-time",
      "description": "1U, 2x Intel Xeon Gold 6326, 384GB RAM, 2TB NVMe"
    },
    {
      "id": "dell-r7625",
      "vendor": "Dell",
      "model": "PowerEdge R7625",
      "type": "Purchase",
      "cpu": 192,
      "ram": 1536,
      "storage": 10000,
      "price": 35000,
      "priceUnit": "one-time",
      "description": "2U, 2x AMD EPYC 9654, 1.5TB RAM, 10TB NVMe"
    },
    {
      "id": "hivelocity-e5",
      "vendor": "Hivelocity",
      "model": "Bare Metal E5-2690v4",
      "type": "Monthly Rental",
      "cpu": 56,
      "ram": 256,
      "storage": 2000,
      "price": 299,
      "priceUnit": "monthly",
      "description": "2x E5-2690v4 (28 cores), 256GB RAM, 2TB SSD"
    },
    {
      "id": "hivelocity-gold",
      "vendor": "Hivelocity",
      "model": "Bare Metal Gold 6248R",
      "type": "Monthly Rental",
      "cpu": 96,
      "ram": 384,
      "storage": 4000,
      "price": 499,
      "priceUnit": "monthly",
      "description": "2x Gold 6248R (48 cores), 384GB RAM, 4TB NVMe"
    },
    {
      "id": "hivelocity-platinum",
      "vendor": "Hivelocity",
      "model": "Bare Metal Platinum 8380",
      "type": "Monthly Rental",
      "cpu": 160,
      "ram": 768,
      "storage": 8000,
      "price": 899,
      "priceUnit": "monthly",
      "description": "2x Platinum 8380 (80 cores), 768GB RAM, 8TB NVMe"
    },
    {
      "id": "hivelocity-epyc",
      "vendor": "Hivelocity",
      "model": "Bare Metal EPYC 7763",
      "type": "Monthly Rental",
      "cpu": 128,
      "ram": 512,
      "storage": 8000,
      "price": 699,
      "priceUnit": "monthly",
      "description": "2x EPYC 7763 (128 cores), 512GB RAM, 8TB NVMe"
    },
    {
      "id": "aws-per-nf",
      "vendor": "AWS",
      "model": "EC2 (per-NF instances)",
      "type": "Cloud",
      "cpu": 8,
      "ram": 32,
      "storage": 100,
      "price": 181,
      "priceUnit": "monthly",
      "perNfInstances": {
        "base":     { "instance": "m6i.xlarge",  "cpu": 4, "ram": 16, "monthlyPrice": 92  },
        "highPerf": { "instance": "m6i.2xlarge", "cpu": 8, "ram": 32, "monthlyPrice": 181 }
      },
      "description": "Each Omnitouch NF deploys as its own EC2 instance: m6i.xlarge for base NFs (4 vCPU / 16 GB), m6i.2xlarge for high-perf NFs (8 vCPU / 32 GB). 1yr Reserved Instance (no upfront), us-east-1, shared tenancy."
    },
    {
      "id": "gcp-per-nf",
      "vendor": "Google Cloud",
      "model": "Compute Engine (per-NF instances)",
      "type": "Cloud",
      "cpu": 8,
      "ram": 32,
      "storage": 100,
      "price": 204,
      "priceUnit": "monthly",
      "perNfInstances": {
        "base":     { "instance": "n2-standard-4", "cpu": 4, "ram": 16, "monthlyPrice": 104 },
        "highPerf": { "instance": "n2-standard-8", "cpu": 8, "ram": 32, "monthlyPrice": 204 }
      },
      "description": "Each Omnitouch NF deploys as its own Compute Engine VM: n2-standard-4 for base NFs (4 vCPU / 16 GB), n2-standard-8 for high-perf NFs (8 vCPU / 32 GB). 1yr Committed Use Discount, us-central1."
    }
  ]
}
