Vendic Strategy · Updates & Maintenance — the evidence base

A 4,000-hour recurring book of work, hiding in plain sight

Across 29 non-Elements clients over three years, 3,972 h — 9.8% of all billed hours went to keeping Magento current. It's steady, it scales with integration complexity (not shop size), and today we deliver it reactively, ticket-by-ticket, unpriced as a product. This is the evidence base for packaging it as a fixed-fee offering — and what to price.
29
non-Elements clients (3y Harvest)
3,972 h
updates & maintenance
9.8%
of 40,454 h billed (a floor)
2 → 1
work types, one offering
One-time events  2,633 h · 66% Continuous maintenance  1,338 h · 34%

The two kinds of work

Everything splits into two cost behaviours — and they price differently

One-time events

2,633 h · 6.5% of billed
Schedulable, lumpy, sized by complexity.
  • Magento major upgrades (2.4.6→2.4.7→2.4.8) + fallout
  • PHP major upgrades (8.2→8.3→8.4) + fallout
  • Hyvä theme / checkout version cycles

→ Price per event (planned, scoped project fee).

Continuous maintenance

1,338 h · 3.3% of billed
Always-on, small-ticket, unpredictable in timing.
  • Magento security patches (-pN, CVE-2025-54236)
  • composer / dependency CVE bumps (symfony, phpseclib, php-jwt)
  • routine 3rd-party module updates (Mollie, PostNL, Tweakwise…)

→ Price as a monthly retainer.

Two different cost behaviours → two different pricing mechanisms, bundled into one offering.

The money chart

Update load scales with complexity, not account size
0%10%20%30%40%501002505001,0002,0004,000Billed hours over 3y (log scale) — "account size"Update share of billed hoursS. van HuisstedenShogun — biggest account, only 3.7%Safety 4 YoU — 30%Snowcountry — tiny shop, 39%
LightStandardCoreHeavyCustom · hourlybubble size = update hours

There is no positive link between account size and update share — if anything it's mildly inverse (bigger accounts dilute updates with project work). Shogun is the largest account by hours yet sits at 3.7%; Snowcountry (237 h billed) and Safety 4 YoU (375 h) are tiny but spend 30–39% of their hours on updates.

…and the same clients in hours per year (2024–2025 average)
0 h50 h100 h150 h200 h25501002505001,0002,000Avg billed hours / year, 2024–2025 (log scale) — "account size"Avg update hours / year (2024–2025)Snowcountry 24 h/yr — but 39%S. van Huissteden 191 h/yrivol 165 h/yrBunzl Retail & Industry (excl. PostNL) 187 h/yrShogun 71 h/yr / 1,743 h billed/yr
LightStandardCoreHeavyCustom · hourlybubble size = update % of billed

Flip the Y-axis to average update hours per year (using the two full years, 2024 & 2025) and the picture inverts: the biggest consumers are the large, integration-heavy accounts — S. van Huissteden 191 h/yr, Bunzl Retail & Industry (excl. PostNL) 187 h/yr, ivol 165 h/yr, Maxima 148 h/yr, Tropilex 105 h/yr. Snowcountry is a big bubble (39% of its spend) but sits low on hours; Shogun is a small bubble (3.7%) but still meaningful in hours thanks to its size. So the two views are complementary: small shops feel updates most as a share of spend, but the complex accounts are where the real hours — and the real fixed-fee revenue — sit. Either way the driver is integration / Hyvä depth, not revenue.

Tier on integration / Hyvä depth — not on revenue or shop size. Share shows who feels the pain; hours/year show where the money is.

Segmentation

Fixed-fee the predictable, bill the volatile by the hour

Banded by average update hours per year (2024–2025): 3 Light (5–25) · 3 Standard (25–45) · 10 Core (45–60) · 5 Heavy (60–100) · 5 Custom · hourly (100+). The 5 custom accounts alone are ~796 h/yr — 42% of all update hours: too lumpy to fixed-fee, so they go on time-and-materials. The four fixed tiers cover the predictable rest.

Light
5–25 h/yr update — minimal, very predictable. Small fixed retainer + per-event.
3 clients5–25 h/yr
~17 h/yr avgfixed retainer + per-event
Snowcountry, ISS Integrated Facility Services, BV Eerste Barneveldse Houthandel
Standard
25–45 h/yr update — light integration. Fixed retainer + per-event.
3 clients25–45 h/yr
~30 h/yr avgfixed retainer + per-event
Miedema Bouwmaterialen, Maegis BV, Houthandel Goedkoop
Core
45–60 h/yr update — the bulk of the base; several integrations. Fixed retainer + per-event.
10 clients45–60 h/yr
~51 h/yr avgfixed retainer + per-event
Albeka, Aardbeiplantje.nl, Topa Verpakking, Luxn Beauty
Heavy
60–100 h/yr update — integration-heavy but still predictable. Larger retainer + per-event.
5 clients60–100 h/yr
~69 h/yr avgfixed retainer + per-event
Relatiegeschenken.nl, Shogun, Paco Verpakkingen, Vitalize Products
Custom · hourly
100+ h/yr update — deep integration, lumpy/high-variance. Billed hourly (T&M).
5 clients100+ h/yr
~159 h/yr avgbilled hourly (T&M)
S. van Huissteden, Bunzl Retail & Industry, ivol, Maxima
Four fixed-fee tiers for the predictable 56% of hours; the high-variance 100+ h/yr accounts (44% of hours) are billed hourly so a bad upgrade can't blow the fee.

Is it steady?

Events come in waves; maintenance is a constant floor
050010001500200025002023 events 148h2023 maintenance 110h2023*2582024 events 544h2024 maintenance 299h20248432025 events 1694h2025 maintenance 744h202524382026 events 248h2026 maintenance 184h2026*432* partial year

2025 was a supercycle — Magento 2.4.7 + 2.4.8 landed on top of the PHP 8.3 and 8.4 migrations, stacking ~60% of all three years' event work into one year.

But the key point for a recurring fee: maintenance is present every single year as a baseline, and a new event cycle is never more than ~12–18 months out. Over any rolling year there's always a fee's worth of work.

2023 (Jun–Dec) and 2026 (Jan–Jun) are partial windows; 2026 shows almost no major upgrades booked yet because upgrades are lumpy, not because the work stopped.

Events are lumpy and seasonal; maintenance is steady — together they're a continuous, pre-sellable pipeline.

Where the hours go

Magento leads, but 3rd-party maintenance is the silent #2
Magento 1825hPHP 956h3rd-party 893hHyvä 297h

Magento core upgrades + patches are 46% (1,825 h) and universal. PHP is 24% (956 h) — it went from a rounding error to a major cost in the 8.3/8.4 double-jump. 3rd-party / composer maintenance is 22% (893 h) — an always-on, invisible tail (Mollie, PostNL, Tweakwise, Amasty, Mirasvit, symfony/composer CVEs) that's exactly what a retainer should cover. Hyvä is 7% (297 h), concentrated in the few shops mid-cycle.

What it means for the offering

Four fixed-fee tiers + a custom (T&M) band — plus a pre-priced event.

Four fixed-fee tiers for the predictable accounts (<100 h/yr): a monthly maintenance retainer covering the patch/CVE/module tail (scaling from Light ~0.5 h/mo to Heavy ~3 h/mo) plus a pre-priced "update event" per planned Magento / PHP cycle (indicative anchors: Magento major ~18 h, PHP major ~16–20 h). The 100+ h/yr accounts are billed hourly (T&M) — their deep integrations produce lumpy, unpredictable work (e.g. a 90 h PostNL fallout, a 47 h Hyvä-checkout rebuild) that a fixed fee can't safely absorb. Hyvä cycles are scoped per project for everyone, not pre-priced.

Per-event fees isolate the lumpy risk; a thin tiered retainer captures the steady tail. Both are supported by the data.

Sizing the prize

~1,324 recurring hours per year — from this base alone

~1,324 h/yr

3,972 h over three years ≈ ~1,324 h/year of recurring update + maintenance work across these 29 clients — work we already do reactively and could pre-sell as a planned, fixed-fee pipeline. This is a floor: it's the highest-billing non-Elements clients, regression work logged under unrelated tickets is undercounted, and the full non-Elements portfolio (~76 clients) is larger.

Method & honest caveats

Read before quoting — every number here is conservative by construction.

The 9.8% is a floor, not a point estimate. Work logged in tickets without trigger words (e.g. "vulnerability in symfony/yaml" — ~60 h measured miss) is invisible to the search net, and regression done inside feature tickets isn't captured. The true share is ≥ 9.8%.

The event/maintenance split (66/34) is the least-robust headline. It's a rule-based rebucketing: all PHP is counted as "event" (some is arguably recurring), all 3rd-party as "maintenance", and the Magento upgrade-vs-patch line turns on ticket wording. Treat 66/34 as directional. A few very large single tickets are debugging/incident work rather than clean updates (e.g. a 90 h PostNL 500-error, a 47 h Hyvä-checkout CSP rebuild).

Per-client %s aren't strictly comparable. The denominator is all logged hours (incl. builds, PM, non-billable), so clients mid-rebuild read low (Shogun 3.7%) and lean mature shops read high (Snowcountry 39%). The 2–39% range conflates update intensity with denominator mix.

Sample & scope. 29 of ~76 clients (the highest-billing; dormant tail dropped), Elements clients excluded by judgment (not name-detectable), Bunzl storefronts merged with PostNL excluded, ~637 h of first-time installs excluded as one-time implementation. Classified semantically by Claude Fable 5 (3 pilot) / Opus 4.8 (26) on the same rules. Represents active non-Elements clients in this window — not the whole base.

Decision asks

  1. Approve the structure — retainer + pre-priced event, three complexity tiers — as the basis for the offering.
  2. Pick 2–3 pilot clients (one per tier) to test a fixed quote against actuals.
  3. Validate indicative pricing against the per-event and per-tier hours here before publishing a price sheet.
  4. Decide on scope — extend the analysis to the full non-Elements base (~47 remaining) and fold in the missed dependency-maintenance tail.