# EPS calculator - Logmanager

:root {
      --lm-accent: rgb(15, 15, 215);
      --lm-bg-block: rgb(245, 245, 245);
      --lm-text-main: rgba(4, 28, 53, 1);
    }

    /* Wrapper */
    .lm-estimator {
      font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
      padding: 64px 16px 80px;
      background: var(--lm-bg-block);
      color: var(--lm-text-main);
    }

    .lm-estimator-inner {
      max-width: 1120px;
      margin: 0 auto;
    }

    .lm-estimator-header {
      text-align: center;
      margin-bottom: 40px;
    }

    /* Eyebrow */
    .lm-estimator-eyebrow {
      font-size: 0.875rem;
      line-height: 1.25rem;
      font-weight: 700;
      letter-spacing: 0.0em;
      text-transform: uppercase;
      color: var(--lm-accent);
      margin-bottom: 8px;
    }

    @media (min-width: 1024px) {
      .lm-estimator-eyebrow {
        font-size: 1.125rem;
        line-height: 1.75rem;
      }
    }

    /* Title */
    .lm-estimator-title {
      font-family: Sora, sans-serif;
      font-weight: 700;
      text-align: center;
      padding-bottom: 1.25rem;
      font-size: 1.5rem;
      line-height: 2rem;
    }

    @media (min-width: 768px) {
      .lm-estimator-title {
        font-size: 1.875rem;
        line-height: 2.25rem;
      }
    }

    @media (min-width: 1024px) {
      .lm-estimator-title {
        font-size: 48px;
        line-height: 54px;
      }
    }

    .lm-estimator-subtitle {
      font-size: 1rem;
      line-height: 1.5rem;
      color: var(--lm-text-main);
      max-width: 720px;
      margin: 0 auto;
    }

    @media (min-width: 1024px) {
      .lm-estimator-subtitle {
        font-size: 1.25rem;
        line-height: 1.75rem;
        text-align: center;
      }
    }

    /* Layout grid */
    .lm-grid {
      display: grid;
      grid-template-columns: minmax(0, 2fr) minmax(0, 1.6fr);
      gap: 32px;
    }

    @media (max-width: 980px) {
      .lm-grid {
        grid-template-columns: minmax(0, 1fr);
      }
    }

    /* Cards */
    .lm-card {
      background: #ffffff;
      border-radius: 28px;
      box-shadow: 0 18px 45px rgba(15, 23, 42, 0.08);
      padding: 28px 28px 24px;
    }

    .lm-card h3 {
      font-size: 18px;
      font-weight: 600;
      margin-bottom: 16px;
    }

    /* Data sources table */
    .lm-data-table {
      width: 100%;
      border-collapse: collapse;
      margin-bottom: 12px;
      font-size: 13px;
    }

    .lm-data-table thead th {
      text-align: left;
      font-weight: 600;
      color: #6b7280;
      padding: 6px 4px;
      border-bottom: 1px solid #e5e7eb;
      font-size: 12px;
    }

    .lm-data-table tbody td {
      padding: 6px 4px;
      vertical-align: middle;
    }

    .lm-group-label {
      font-size: 11px;
      font-weight: 600;
      text-transform: uppercase;
      color: #9ca3af;
      padding: 8px 4px 2px;
    }

    .lm-data-label {
      font-weight: 500;
      color: #111827;
    }

    .lm-eps-badge {
      display: inline-flex;
      padding: 2px 8px;
      border-radius: 999px;
      font-size: 11px;
      background: rgba(15, 15, 215, 0.08);
      color: var(--lm-accent);
      font-weight: 500;
    }

    .lm-input {
      width: 80px;
      max-width: 100%;
      padding: 6px 9px;
      font-size: 13px;
      border-radius: 999px;
      border: 1px solid #e5e7eb;
      text-align: right;
      outline: none;
      transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;
      background: #ffffff;
    }

    .lm-input:focus {
      border-color: var(--lm-accent);
      box-shadow: 0 0 0 1px rgba(15, 15, 215, 0.35);
      background: #f9fafb;
    }

    .lm-input-wide {
      width: 100%;
    }

    .lm-input-row {
      display: flex;
      flex-wrap: wrap;
      gap: 10px;
      margin-top: 12px;
      font-size: 13px;
      align-items: center;
    }

    .lm-input-row label {
      color: #4b5563;
      font-weight: 500;
    }

    .lm-input-row select {
      padding: 6px 10px;
      border-radius: 999px;
      border: 1px solid #e5e7eb;
      font-size: 13px;
      outline: none;
      background: #ffffff;
    }

    .lm-input-row select:focus {
      border-color: var(--lm-accent);
      box-shadow: 0 0 0 1px rgba(15, 15, 215, 0.35);
    }

    .lm-input-note {
      font-size: 11px;
      color: #9ca3af;
      margin-top: 4px;
    }

    .lm-outputs-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      gap: 8px;
      margin-bottom: 12px;
    }

    .lm-badge {
      display: inline-flex;
      padding: 3px 10px;
      border-radius: 999px;
      font-size: 11px;
      text-transform: uppercase;
      letter-spacing: 0.08em;
      font-weight: 600;
    }

    .lm-badge-purple {
      background: rgba(15, 15, 215, 0.08);
      color: var(--lm-accent);
    }

    /* Metrics */
    .lm-metrics {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 10px;
      margin-bottom: 4px;
      font-size: 13px;
    }

    .lm-metric {
      background: #f9fafb;
      border-radius: 16px;
      padding: 10px 12px;
    }

    .lm-metric-label {
      color: #6b7280;
      font-size: 12px;
      margin-bottom: 4px;
    }

    .lm-metric-value {
      font-weight: 600;
      font-size: 15px;
    }

    /* Export button */
    .lm-button-export {
      margin-top: 16px;
      padding: 10px 18px;
      border-radius: 999px;
      border: none;
      cursor: pointer;
      font-size: 13px;
      font-weight: 600;
      background: var(--lm-accent);
      color: #ffffff;
      box-shadow: 0 10px 25px rgba(15, 15, 215, 0.25);
      transition: transform 0.1s ease, box-shadow 0.1s ease, opacity 0.1s ease;
    }

    .lm-button-export:hover {
      transform: translateY(-1px);
      box-shadow: 0 14px 30px rgba(15, 15, 215, 0.3);
      opacity: 0.95;
    }

    .lm-button-export:active {
      transform: translateY(0);
      box-shadow: 0 6px 15px rgba(15, 15, 215, 0.25);
    }
  Estimator

##  Estimate your EPS and log volume 

 Enter your data sources, average event size, and retention. The calculator will estimate EPS, daily log volume and total stored data for capacity planning. Results are rough estimates only and do not represent any guaranteed capacity commitment.

 

 ### 1. Data sources

    Group / system Avg EPS \# of sources     Windows   Windows Server 30 EPS      Windows Active Directory 100 EPS      Windows Desktop 2 EPS      UNIX / Linux   UNIX / Linux servers 10 EPS      Security   Firewall zones – internal 200 EPS      Firewall zones – external 400 EPS      IPS 5 EPS      Vulnerability scanners 1 EPS      VPN 5 EPS      Antivirus 30 EPS      Infrastructure   Routers 2 EPS      Switch / SCCM 1 EPS      Proxy server 300 EPS      Wi-Fi AP 5 EPS      Load balancer 5 EPS      Servers   Database servers 5 EPS      Web servers 5 EPS      Mail servers 40 EPS      Other   Other sources (total EPS)       Average event size  bytes 

 Defaults to 700 bytes. Adjust if your events are larger or smaller. 

 Retention   days months (30 days) years (365 days)  

 We’ll multiply your daily volume by retention to estimate total stored data. 

 

 ### 2. Estimate

 Live estimate 

Estimated EPS

0

 

Volume per day

0 GB / day

 

Retention

0 days

 

Total stored data

0 GB

 

 

 This estimate is for rough capacity planning only and is not a guaranteed value. 

  Export to XLSX  

 

 

   
    (function () {
      const BYTES_PER_GB = 1073741824;

      const deviceInputs = Array.from(
        document.querySelectorAll(".lm-input-devices")
      );
      const otherEpsInput = document.getElementById("lm-other-eps");
      const eventSizeInput = document.getElementById("lm-event-size");
      const retentionInput = document.getElementById("lm-retention");
      const retentionUnitSelect = document.getElementById("lm-retention-unit");

      const epsDisplay = document.getElementById("lm-eps-display");
      const gbDayDisplay = document.getElementById("lm-gbday-display");
      const retentionDisplay = document.getElementById("lm-retention-display");
      const totalGbDisplay = document.getElementById("lm-totalgb-display");

      function formatNumber(num, decimals) {
        if (!isFinite(num) || num === 0) return "0";
        const n = decimals != null ? num.toFixed(decimals) : Math.round(num);
        return Number(n).toLocaleString(undefined, {
          minimumFractionDigits: decimals || 0,
          maximumFractionDigits: decimals || 0,
        });
      }

      function formatStorageGB(gb) {
        if (!isFinite(gb) || gb <= 0) return "0 GB";
        if (gb >= 1024) {
          const tb = gb / 1024;
          return formatNumber(tb, 2) + " TB";
        }
        return formatNumber(gb, 2) + " GB";
      }

      function recalc() {
        const eventSize = parseFloat(eventSizeInput.value) || 0;

        let totalEps = 0;
        deviceInputs.forEach((input) => {
          const count = parseFloat(input.value) || 0;
          const epsPer = parseFloat(input.dataset.eps) || 0;
          totalEps += count * epsPer;
        });

        const otherEps = parseFloat(otherEpsInput.value) || 0;
        totalEps += otherEps;

        const gbPerDay =
          (totalEps * eventSize * 60 * 60 * 24) / BYTES_PER_GB || 0;

        const retentionValue = parseFloat(retentionInput.value) || 0;
        const unit = retentionUnitSelect.value;

        let retentionDays;
        if (unit === "months") {
          retentionDays = retentionValue * 30;
        } else if (unit === "years") {
          retentionDays = retentionValue * 365;
        } else {
          retentionDays = retentionValue; // days
        }

        const totalGb = gbPerDay * retentionDays;

        // Update metric display
        epsDisplay.textContent = formatNumber(totalEps, 0);
        gbDayDisplay.textContent = formatNumber(gbPerDay, 2) + " GB / day";
        retentionDisplay.textContent = formatNumber(retentionDays, 0) + " days";
        totalGbDisplay.textContent = formatStorageGB(totalGb);
      }

      function collectDataForExport() {
        const rows = [];

        // Header row
        rows.push(["Group / system", "EPS per source", "# of sources", "Total EPS"]);

        deviceInputs.forEach((input) => {
          const tr = input.closest("tr");
          if (!tr) return;

          const labelCell = tr.querySelector(".lm-data-label");
          if (!labelCell) return;

          const label = labelCell.textContent.trim();
          const epsPer = parseFloat(input.dataset.eps) || 0;
          const count = parseFloat(input.value) || 0;
          const total = epsPer * count;

          rows.push([label, epsPer, count, total]);
        });

        // Other sources
        rows.push([]);
        const otherEps = parseFloat(otherEpsInput.value) || 0;
        rows.push(["Other sources (total EPS)", "", "", otherEps]);

        // Input parameters
        rows.push([]);
        rows.push(["Average event size (bytes)", eventSizeInput.value]);
        rows.push([
          "Retention (input unit)",
          retentionInput.value + " " + retentionUnitSelect.options[retentionUnitSelect.selectedIndex].text
        ]);

        // Retention in days
        const retentionValue = parseFloat(retentionInput.value) || 0;
        const unit = retentionUnitSelect.value;
        let retentionDays;
        if (unit === "months") {
          retentionDays = retentionValue * 30;
        } else if (unit === "years") {
          retentionDays = retentionValue * 365;
        } else {
          retentionDays = retentionValue;
        }
        rows.push(["Retention (days)", retentionDays]);

        // Output metrics
        rows.push([]);
        rows.push(["Estimated EPS", epsDisplay.textContent]);
        rows.push(["Volume per day", gbDayDisplay.textContent]);
        rows.push(["Total stored data", totalGbDisplay.textContent]);

        return rows;
      }

      function exportToXlsx() {
        if (typeof XLSX === "undefined") {
          alert("XLSX (SheetJS) library not loaded.");
          return;
        }

        const data = collectDataForExport();

        const worksheet = XLSX.utils.aoa_to_sheet(data);
        const workbook = XLSX.utils.book_new();
        XLSX.utils.book_append_sheet(workbook, worksheet, "Estimate");

        XLSX.writeFile(workbook, "eps-estimator.xlsx");
      }

      // Event listeners
      [
        ...deviceInputs,
        otherEpsInput,
        eventSizeInput,
        retentionInput,
        retentionUnitSelect,
      ].forEach((el) => {
        el.addEventListener("input", recalc);
      });

      const exportBtn = document.getElementById("lm-export-xlsx");
      if (exportBtn) {
        exportBtn.addEventListener("click", exportToXlsx);
      }

      // Initial calculation
      recalc();
    })();
