Microsoft 365 Plan-Mix Optimizer
The cheapest mix that still meets your controls. Tell us how many people work at a desk and how many work on the floor, tick the security and compliance controls you need, and get the lowest-cost plan for each group, with an all-E5 alternative beside it.
How the optimizer chooses
Cheapest plan per group
For each group it prices every Microsoft 365 plan plus the add-ons needed to cover the controls you ticked, and keeps the lowest total. Frontline workers never get desktop apps, so F3 is in play for them.
The 300-seat Business cap
Business Basic, Standard and Premium are limited to 300 seats in total per organization. Above that, the optimizer moves people to enterprise plans.
Why show all-E5
E5 includes every control on the list. If the optimized mix is close to all-E5, the simpler single plan may be worth the difference.
window.C2N = (function () { function esc(s) { return String(s).replace(/[&<>"]/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"' }[c]; }); } function fire(el) { el.dispatchEvent(new Event('input', { bubbles: true })); el.dispatchEvent(new Event('change', { bubbles: true })); } function enhance(form) { [].forEach.call(form.querySelectorAll('select[data-seg]'), function (sel) { var seg = document.createElement('div'); seg.className = 'c2n-seg'; seg.setAttribute('role', 'radiogroup'); seg.style.gridTemplateColumns = 'repeat(' + Math.min(sel.options.length, +sel.dataset.seg || sel.options.length) + ',1fr)'; [].forEach.call(sel.options, function (o) { var b = document.createElement('button'); b.type = 'button'; b.textContent = o.textContent; b.dataset.v = o.value; b.setAttribute('role', 'radio'); b.addEventListener('click', function () { sel.value = o.value; sync(form); fire(sel); }); seg.appendChild(b); }); sel.hidden = true; sel.parentNode.insertBefore(seg, sel.nextSibling); }); [].forEach.call(form.querySelectorAll('input[data-range]'), function (num) { var r = num.dataset.range.split(','), rg = document.createElement('input'); rg.type = 'range'; rg.min = r[0]; rg.max = r[1]; rg.step = r[2] || 1; rg.className = 'c2n-range'; rg.setAttribute('aria-label', num.name); rg.addEventListener('input', function (e) { e.stopPropagation(); num.value = rg.value; fire(num); }); num.parentNode.appendChild(rg); }); } function sync(form) { [].forEach.call(form.querySelectorAll('select[data-seg]'), function (sel) { [].forEach.call(sel.nextSibling.children, function (b) { var on = b.dataset.v === sel.value; b.classList.toggle('on', on); b.setAttribute('aria-checked', on); }); }); [].forEach.call(form.querySelectorAll('input[data-range]'), function (num) { num.parentNode.querySelector('.c2n-range').value = num.value; }); } function render(el, r) { var h = '<div class="c2n-cx-bar"><span>Results · ' + esc(r.title) + (r.unit === undefined ? ' · USD' : r.unit) + '</span><span class="c2n-cx-live">Live</span></div>'; if (r.lead) h += '<p class="c2n-cx-lead">' + r.lead + '</p>'; if (r.kpis) h += '<div class="c2n-cx-kpis">' + r.kpis.map(function (k, i) { return '<div class="c2n-cx-kpi' + (i ? '' : ' on') + '"><small>' + esc(k[0]) + '</small><b>' + k[1] + '</b><span>' + (k[2] || '') + '</span></div>'; }).join('') + '</div>'; if (r.rows) { var cell = function (tag) { return function (c, i) { return '<' + tag + (i ? ' class="n"' : '') + '>' + c + '</' + tag + '>'; }; }; h += '<div class="c2n-cx-scroll"><table class="c2n-cx-table">' + (r.head ? '<tr>' + r.head.map(cell('th')).join('') + '</tr>' : '') + r.rows.map(function (row) { return '<tr>' + row.map(cell('td')).join('') + '</tr>'; }).join('') + (r.total ? '<tr class="t">' + r.total.map(cell('td')).join('') + '</tr>' : '') + '</table></div>'; } h += '<div class="c2n-cx-foot"><p>' + (r.note || '') + '</p>' + (r.cta ? '<a class="c2n-cx-btn" href="' + esc(r.cta[1]) + '">' + esc(r.cta[0]) + '</a>' : '') + '</div>'; el.innerHTML = h; } function money(n, d) { return (n < 0 ? '-$' : '$') + Math.abs(n).toLocaleString('en-US', { minimumFractionDigits: d || 0, maximumFractionDigits: d || 0 }); } function values(form) { var v = {}; [].forEach.call(form.elements, function (el) { if (el.name) v[el.name] = el.type === 'number' ? Math.max(0, +el.value || 0) : el.value; }); return v; } function restore(form) { var q = new URLSearchParams(location.search); [].forEach.call(form.elements, function (el) { if (el.name) { if (q.has(el.name)) el.value = q.get(el.name); } }); } function save(form) { var o = {}; [].forEach.call(form.elements, function (el) { if (el.name) o[el.name] = el.value; }); history.replaceState(null, '', '?' + new URLSearchParams(o)); } function mount(form, calc) { enhance(form); restore(form); var run = function () { sync(form); calc(values(form)); save(form); }; form.addEventListener('input', run); form.addEventListener('submit', function (e) { e.preventDefault(); }); run(); } return { mount: mount, render: render, money: money, esc: esc, sync: sync, enhance: enhance }; })(); (function () { var P = {"Microsoft 365 Business Basic":{"c":[84,7.35,8.4]},"Microsoft 365 Business Standard":{"c":[168,14.7,16.8]},"Microsoft 365 Business Standard (Non-Profit Pricing)":{"n":[42,3.68,4.2]},"Microsoft 365 Business Premium":{"c":[264,23.1,26.4]},"Microsoft 365 Business Premium (Nonprofit Staff Pricing)":{"n":[66,5.77,6.6]},"Microsoft 365 E3":{"c":[468,40.95,46.8]},"Microsoft 365 E3 (Non-Profit Pricing)":{"n":[117,10.24,11.7]},"Microsoft 365 E5":{"c":[720,63,72]},"Microsoft 365 E5 (Non-Profit Pricing)":{"n":[288,25.2,28.8]},"Microsoft 365 F3":{"c":[120,10.5,12]},"Microsoft 365 F3 (Non-Profit Pricing)":{"n":[30,2.63,3]},"Microsoft Intune Plan 1":{"c":[96,8.4,9.6]},"Microsoft Intune (Non-Profit Pricing)":{"n":[24,2.1,2.4]},"Microsoft Entra ID P1":{"c":[84,7.35,8.4]},"Microsoft Entra ID P1 (Non-Profit Pricing)":{"n":[21,1.84,2.1]},"Microsoft Entra ID P2":{"c":[120,10.5,12]},"Microsoft Entra ID P2 (Non-Profit Pricing)":{"n":[48,4.2,4.8]},"Microsoft Defender for Endpoint P1":{"c":[36,3.15,3.6]},"Microsoft Defender for Endpoint P1 (Non-Profit Pricing)":{"n":[9,0.79,0.9]},"Microsoft Defender for Endpoint P2":{"c":[62.4,5.46,6.24]},"Microsoft Defender for Endpoint P2 (Non-Profit Pricing)":{"n":[25.2,2.21,2.52]},"Microsoft Defender for Office 365 (Plan 1)":{"c":[24,2.1,2.4]},"Microsoft Defender for Office 365 (Plan 1) (Non-Profit Pricing)":{"n":[9.6,0.84,0.96]},"Microsoft Defender for Office 365 (Plan 2)":{"c":[60,5.25,6]},"Microsoft Defender for Office 365 (Plan 2) (Non-Profit Pricing)":{"n":[24,2.1,2.4]},"Microsoft Purview Suite for Microsoft 365 Business Premium":{"c":[120,10.5,12]},"Microsoft Purview Suite for Microsoft 365 Business Premium (Non-Profit Pricing)":{"n":[48,4.2,4.8]},"Microsoft 365 E5 Information Protection and Governance":{"c":[84,7.35,8.4]},"Microsoft 365 E5 Information Protection and Governance (Non-Profit Pricing)":{"n":[33.6,2.94,3.36]},"Microsoft Teams Phone Standard":{"c":[120,10.5,12]},"Microsoft Teams Phone Standard (Non-Profit Pricing)":{"n":[48,4.2,4.8]},"Microsoft 365 Copilot (add-on)":{"c":[360,31.5,null]},"Microsoft 365 Copilot (Non-Profit Pricing) (add-on)":{"n":[306,26.78,null]},"Microsoft 365 Copilot Business (add-on)":{"c":[252,22.05,25.2]}}; var NP = { 'Microsoft 365 Business Premium': 'Microsoft 365 Business Premium (Nonprofit Staff Pricing)', 'Microsoft Intune Plan 1': 'Microsoft Intune (Non-Profit Pricing)', 'Microsoft 365 Copilot (add-on)': 'Microsoft 365 Copilot (Non-Profit Pricing) (add-on)' }; function mo(name, seg) { if (seg === 'n') { var np = P[NP[name] || name + ' (Non-Profit Pricing)']; if (np) return np.n[0] / 12; } return P[name] ? P[name].c[0] / 12 : null; } var REQ = [['intune', 'Device management (Intune)'], ['p1', 'Conditional Access (Entra ID P1)'], ['p2', 'Risk-based access and PIM (Entra ID P2)'], ['mde1', 'Endpoint protection (Defender P1)'], ['mde2', 'Endpoint detection and response (Defender P2)'], ['mdo1', 'Email threat protection (Defender for Office P1)'], ['mdo2', 'Email attack investigation (Defender for Office P2)'], ['purv', 'Automatic labeling and DLP (Purview)'], ['phone', 'Phone numbers in Teams (Teams Phone)']]; var PLANS = [ ['Microsoft 365 F3', 'F3', { intune: 1, p1: 1 }, false], ['Microsoft 365 Business Basic', 'Business Basic', {}, true], ['Microsoft 365 Business Standard', 'Business Standard', { desk: 1 }, true], ['Microsoft 365 Business Premium', 'Business Premium', { desk: 1, intune: 1, p1: 1, mde1: 1, mdo1: 1 }, true], ['Microsoft 365 E3', 'E3', { desk: 1, intune: 1, p1: 1, mde1: 1 }, false], ['Microsoft 365 E5', 'E5', { desk: 1, intune: 1, p1: 1, p2: 1, mde1: 1, mde2: 1, mdo1: 1, mdo2: 1, purv: 1, phone: 1 }, false]]; var ADD = { intune: 'Microsoft Intune Plan 1', p1: 'Microsoft Entra ID P1', p2: 'Microsoft Entra ID P2', mde1: 'Microsoft Defender for Endpoint P1', mde2: 'Microsoft Defender for Endpoint P2', mdo1: 'Microsoft Defender for Office 365 (Plan 1)', mdo2: 'Microsoft Defender for Office 365 (Plan 2)', phone: 'Microsoft Teams Phone Standard' }; var f = document.getElementById('po'), box = document.getElementById('po-req'), $ = C2N.money; box.innerHTML = REQ.map(function (r) { return '<label><input type="checkbox" data-k="' + r[0] + '"> ' + r[1] + '</label>'; }).join(''); box.addEventListener('input', function (e) { e.stopPropagation(); }); box.addEventListener('change', function (e) { e.stopPropagation(); f.req.value = [].filter.call(box.querySelectorAll('input'), function (c) { return c.checked; }).map(function (c) { return c.dataset.k; }).join(','); f.req.dispatchEvent(new Event('input', { bubbles: true })); }); function price(plan, need, desk, seg) { var has = plan[2], cost = mo(plan[0], seg), adds = []; if (cost === null) return null; if (desk) { if (!has.desk) return null; } var req = need.slice(); if (req.indexOf('p2') >= 0) req = req.filter(function (k) { return k !== 'p1'; }); if (req.indexOf('mde2') >= 0) req = req.filter(function (k) { return k !== 'mde1'; }); if (req.indexOf('mdo2') >= 0) req = req.filter(function (k) { return k !== 'mdo1'; }); for (var i = 0; i < req.length; i++) { var k = req[i]; if (has[k]) continue; var add = k === 'purv' ? (plan[1] === 'Business Premium' ? 'Microsoft Purview Suite for Microsoft 365 Business Premium' : plan[1] === 'E3' ? 'Microsoft 365 E5 Information Protection and Governance' : null) : ADD[k]; if (!add) return null; var p = mo(add, seg); if (p === null) return null; cost += p; adds.push(add.replace('Microsoft ', '').replace(' for Microsoft 365 Business Premium', '')); } return { name: plan[1], cost: cost, adds: adds, biz: plan[3] }; } function best(need, desk, seg, allowBiz) { return PLANS.map(function (pl, i) { var o = price(pl, need, desk, seg); if (o) o.rank = i; return o; }).filter(function (o) { return o ? (allowBiz || !o.biz) : false; }).sort(function (a, b) { return (Math.round(a.cost * 100) - Math.round(b.cost * 100)) || (b.rank - a.rank); })[0]; } C2N.mount(f, function (v) { var need = v.req ? v.req.split(',') : []; [].forEach.call(box.querySelectorAll('input'), function (c) { c.checked = need.indexOf(c.dataset.k) >= 0; }); var office = best(need, true, v.seg, true), front = best(need, false, v.seg, true); if (office.biz) { if (front.biz ? v.office + v.front > 300 : v.office > 300) office = best(need, true, v.seg, false); } if (front.biz) { if ((office.biz ? v.office : 0) + v.front > 300) front = best(need, false, v.seg, false); } var copName = office.biz ? 'Microsoft 365 Copilot Business (add-on)' : 'Microsoft 365 Copilot (add-on)', cop = mo(copName, v.seg); if (cop === null) cop = mo('Microsoft 365 Copilot (add-on)', v.seg); var e5 = mo('Microsoft 365 E5', v.seg), total = office.cost * v.office + front.cost * v.front + cop * v.cop, allE5 = e5 * (v.office + v.front) + cop * v.cop; var label = function (o) { return o.name + (o.adds.length ? ' + ' + o.adds.join(' + ') : ''); }; var rows = []; if (v.office) rows.push([v.office + ' office: ' + label(office), $(office.cost, 2), $(office.cost * v.office)]); if (v.front) rows.push([v.front + ' frontline: ' + label(front), $(front.cost, 2), $(front.cost * v.front)]); if (v.cop) rows.push([v.cop + ' x ' + copName.replace(' (add-on)', ''), $(cop, 2), $(cop * v.cop)]); C2N.render(document.getElementById('po-out'), { title: 'Plan mix', lead: 'The optimized mix costs <strong>' + $(total) + ' a month</strong>, ' + $(Math.max(0, allE5 - total)) + ' less than putting everyone on E5' + (allE5 - total < total * 0.1 ? ', close enough that all-E5 may be worth its extra controls.' : '.'), kpis: [['Optimized mix', $(total), 'per month, ' + $(total * 12) + ' a year'], ['Everyone on E5', $(allE5), 'per month, every control included']], head: ['Group and plan', 'Per user / mo', 'Monthly'], rows: rows.length ? rows : [['No users entered', '', '']], total: ['Total per month', '', $(total)], note: 'Microsoft US list price, annual commitment, current month. Feature mapping is simplified; confirm edge cases with us before buying.', cta: ['Request a quote', '/tools/forms/?f=quote&items=' + encodeURIComponent(rows.map(function (r) { return r[0]; }).join('; '))] }); }); })();