Scheduled, Backup-Protected 3CX Updates for MSPs at Fleet Scale

Out-of-date 3CX servers are a liability. Updating them blind, during business hours, with no restore point is a different liability. Here's how to patch a whole fleet on a maintenance window — with a fresh backup taken first — without logging into a single console.

The two-sided risk of 3CX patching

Patch management on 3CX has a reputation for being either neglected or done dangerously, and both ends of that spectrum hurt MSPs.

Patch too late and you're carrying a known liability. 3CX is internet-facing by design — a public FQDN, a web client, SIP on the edge — which makes an out-of-date build an attractive target. The 2023 supply-chain incident put 3CX security squarely on every partner's radar, and the practical lesson stuck: a PBX that's months behind on releases is the one that ends up in an incident report. Late patching also generates quiet support drag — bugs that were fixed upstream keep generating tickets because the fix never landed on the customer's box.

Patch carelesslyand you trade a slow risk for a fast one. 3CX applies updates asynchronously and can restart services while it does — run that at 2 p.m. and you've dropped live calls for a customer who never agreed to a maintenance window. Worse, if a release interacts badly with that instance's config and you have no recent backup, your rollback plan is "rebuild and hope." Doing it by hand also means logging into every customer's console one at a time, which is exactly the work that doesn't get done consistently across a fleet of twenty or fifty PBXs.

The answer to both is the same shape: decide when each instance patches, make sure there's a restore point before it does, and run the whole thing from one place instead of N consoles. That's what scheduled, backup-protected updates give you.

The fleet view: know what's running before you touch anything

The starting point in Sikurd's Update Manager is a single screen that lists every connected 3CX instance with:

  • Current 3CX version — what's actually running on each box right now.
  • Pending updates — what 3CX reports as available from the last scan, with the individual update names so you can see exactly what would install.
  • Channel — whether that instance is on the Stable or Beta update channel (more on this below).
  • Maintenance status — 3CX blocks updates once maintenance/support lapses, so an expired instance is flagged and held out of the push, not silently skipped.
  • Last checked — when the instance was last scanned, so you're never acting on stale data.

Summary tiles at the top roll the fleet up at a glance: how many instances have updates available, how many are up to date, how many have maintenance expired, and how many are on Beta. A "Check all for updates" action re-scans every instance so the view reflects reality before you commit to anything. This is the part that replaces the spreadsheet — instead of remembering which customer is on which build, you open one page and the whole estate is in front of you, with the instances that need attention sorted to the top.

How a scheduled, backup-protected update works

Once you can see the fleet, the workflow is: scan, select, choose timing, and let the worker do the rest safely. Here's each step and what's actually happening underneath.

1. Scan and select

You scan (or re-scan) the instances you care about, then open the push dialog. You pick which instances to include and — per instance — which of the pending updates to install. You're choosing against a live read of what 3CX currently reports as out of date, not a guess.

2. Choose: update now, or schedule

Two timing options: update immediately, or schedule for a specific date and time. Scheduling is the headline for production fleets — you queue the work for tonight's maintenance window and walk away. Because each selected instance becomes its own job with its own scheduled time, you can stagger a rollout: lab and low-risk customers first, the rest on their individual windows. A scheduled job can be cancelled any time before it starts.

3. Backup-first (on by default)

The "take a fresh managed backup before each update" option is checked by default, and it's the single most important safety control here. When the job runs, the worker:

  • Looks for a managed backup of that instance taken in the last hour. A recent backup is already a valid restore point, so it's reused — no redundant capture.
  • If there isn't a recent one, it triggers a fresh capture and waits for that backup to land in immutable storage before it touches the update.
  • Only then does it move on to installing.

So by the time a single byte of the update is applied, you have a same-day restore point sitting in off-site storage. If the release misbehaves on that box, you're restoring — not rebuilding.

The one hard requirement: backup-first needs the instance enrolled in Sikurd's Verified / Managed Backups. If an instance isn't enrolled, Sikurd flags it right in the push dialog ("not enrolled — backup-first will fail"), and the job fails fast rather than installing unprotected. You can disable backup-first per push if you've created a restore point another way — but for production instances, leaving it on is the whole point. (For what "managed backup" really means and how Sikurd proves those backups actually restore, see Verified Backups.)

4. Re-validate, then install

Right before installing, the worker re-fetches the update list from 3CX and re-validates that your selected updates are still pending. This matters more than it sounds: time may have passed between scheduling and execution, and 3CX regenerates its install key on every fetch. Sikurd matches your selection against the fresh list and installs the current entries. If the updates turn out to be applied already — say 3CX picked them up on its own in the interim — the job is marked Completed with nothing to do, not failed. The goal was "that server is current," and it already is.

5. The status ladder

Every job moves through a status you can read at a glance on the fleet row:

  • Scheduled
    Queued for its time. Shows the scheduled moment in your timezone, with a cancel option.
  • Backing up
    The worker is capturing (or waiting on) the fresh pre-update backup.
  • Installing
    The backup is in place; the update has been handed to 3CX.
  • Completed
    3CX accepted the install. The new version appears on the next scan.
  • Failed
    Something stopped the job — with the reason attached, so you know whether to re-push or fix the underlying issue first.

One job per instance, one clear state per job. A fleet-wide rollout becomes legible instead of a pile of console tabs.

What "Completed" really means (and why that's honest)

It's worth being precise, because over-claiming here would be misleading. "Completed" means 3CX accepted the install request. 3CX applies updates asynchronously and may restart services as part of doing so — so the moment a job reads Completed is the moment the command was accepted, not a guarantee that every service is already back up on the new build. The authoritative confirmation is the version number on the next scan: once that instance reports the new release, you know it's running it. Sikurd surfaces the accepted state immediately and the new version on the following scan, so you get fast feedback without a false promise.

Stable vs. Beta: a channel control per instance

Not every box should see the same releases. Sikurd exposes a per-instance channel filter in the fleet view:

  • Stable — production 3CX releases. Where the overwhelming majority of customer instances belong.
  • Beta — pre-release builds, for the instances where you actually want them: a lab PBX, an internal box, or a customer who has explicitly opted into early builds.

The channel is set per instance, so a single beta-testing server doesn't drag pre-release builds in front of your whole fleet. It's a small control with an outsized payoff: you can run one or two canary instances on Beta to catch problems early, while every production customer stays on Stable until you're satisfied a release is safe.

Why this beats per-console patching

The build-it-yourself alternative is to remember each customer's version, log into each console on their schedule, take a backup by hand (if you remember), apply the update, and hope nothing restarts at a bad time. That works for one or two PBXs. Across a real fleet it produces the exact failure mode the industry keeps relearning: the instances that fall behind are the ones nobody got around to, and the update that breaks something is the one with no recent backup.

Scheduled, backup-protected updates close that gap by default. You see the whole fleet's version state in one place, you patch on the windows your customers agreed to, and a fresh restore point is taken before each install unless you opt out. The work that "didn't get done consistently" becomes a few minutes on one screen.

Adjacent reading

Frequently asked questions

Why not just let 3CX auto-update?
3CX can apply some updates on its own, but auto-update gives you no control over timing (an update can restart phone services mid-shift), no pre-update restore point, and no fleet-wide visibility into who's on what version. For a single home PBX that's fine. Across dozens of customer instances, you want to decide when each one patches, take a backup first, and see the whole fleet's version state in one place. Sikurd's Update Manager adds exactly those three controls on top of 3CX's native update mechanism.
Does the backup-first option work on any instance?
Backup-first requires the instance to be enrolled in Sikurd's Verified / Managed Backups. If it's enrolled, the worker checks for a managed backup taken in the last hour and uses it as the restore point; if there isn't a recent one, it triggers a fresh capture and waits for it to land in immutable storage before installing. If the instance isn't enrolled, backup-first can't run — Sikurd flags that in the push dialog and the job fails fast rather than installing unprotected. You can also turn backup-first off per push if you've taken a restore point another way.
What does a "Completed" update actually mean?
It means 3CX accepted the install request. 3CX applies updates asynchronously and may restart services as it does — so "Completed" is the point where the command was accepted, not necessarily the moment every service is back on the new build. The new version number shows up on the next update scan of that instance, which is the authoritative confirmation that the server is running the new release.
Can I schedule different instances for different times?
Yes. Each instance you select becomes its own job with its own scheduled time, so you can stagger a fleet — patch your lab and low-risk customers first, then roll the rest on their individual maintenance windows. Sikurd creates one job per instance; a worker picks up each job when its time arrives, runs the optional backup, re-validates, and installs. A scheduled job can be cancelled any time before it starts.
What's the difference between the Stable and Beta channels?
It's a per-instance channel filter for the Sikurd-managed update view: Stable surfaces the production 3CX releases; Beta surfaces pre-release builds for instances where you want them (a lab box, an internal PBX, a customer who's opted in). Most production instances stay on Stable. You set the channel per instance from the fleet view, so a single beta-testing server doesn't push pre-release builds at everyone else.
What happens if the update was already applied by the time the job runs?
The worker re-checks 3CX for pending updates right before installing — it doesn't blindly replay a selection captured at scan time. If the selected updates are already applied (for example, 3CX picked them up on its own in the meantime), the job is marked Completed with nothing to do, not failed. The desired state — that server being current — is what matters, and it's already met.
Do I have to update through a portal for each customer?
No — that's the point. The fleet view lists every connected instance's current 3CX version, pending updates, channel, and maintenance status on one screen. You select across customers, choose update-now or a scheduled time once, and Sikurd dispatches the jobs. No per-console logins, no spreadsheet of who's on what version.

Patch your whole 3CX fleet on a schedule, backup-first.

Scan every instance's version in one view, select across customers, and update now or on a maintenance window — with a fresh managed backup taken first by default. Your first three instances are free, forever.