EspoCRM high availability

A self-hosted EspoCRM instance that sales and service teams depend on needs a plan for database, file storage, background jobs and restores. This guide covers the decisions, build sequence, effort and verification.

On this page

Why EspoCRM high availability is more than adding a second server

High availability for EspoCRM means separating state from compute, making cron and the WebSocket daemon run reliably on every node that needs them, and proving that restores work. A self-hosted CRM that sales and service teams open all day stops being useful the moment one server fails, and a second server alone does not fix that. The second server only helps if the application can run on either node against the same data, the same files and the same scheduled work, and if someone has tested that recovery actually completes.

Start with the supported stack, because it sets the boundaries for any multi-node design. EspoCRM's server configuration documentation lists PHP 8.3 to 8.5, MySQL 8.0 or newer, MariaDB 10.6 or newer or PostgreSQL 15, and Apache, Nginx or IIS as the web server. Cron or a Windows scheduled task is required for background jobs. Before designing anything, check the vendor documentation for the version you run to see what a layout with several application nodes supports. Do not assume that a single-server guide covers a split database, shared storage or a load balancer.

Background jobs are the first place a second node causes trouble. Workflows, scheduled actions, email processing and large idle imports all depend on cron, and if every node runs the same cron entries, the same job can execute twice. Decide in advance which node owns scheduled work, or confirm with the vendor how the version in use prevents duplicate execution. Also confirm where the WebSocket daemon must run and whether clients can reconnect cleanly after a failover. Test these with a real workflow that sends an email, so duplicate or missing sends show up before users see them.

Uploaded attachments are the second trap. In a single-server install they sit on local disk under the EspoCRM directory, so a standby node has no copy unless you put the file store on shared or replicated storage. Sessions and cache have the same issue: if a user logs in on one node and the next request lands on another, the session must be readable there. Decide where sessions and cache live, whether that is shared storage, the database or an external cache, and confirm that choice against the documentation for your version before you commit to a load balancer design.

The backup that was never restored is the most common failure in this kind of setup. Backups should cover the database, the file store, configuration and any custom code, and they should be restored into a separate environment on a schedule. Ask your implementation partner or internal team to document each restore step, the order of components and who can perform it at 2 a.m. If the installer's command.sh utility is part of your plan, confirm which backup and restore operations it supports for your layout, because a multi-node design may need steps the utility does not cover.

Components that must survive a node failure

A multi-server EspoCRM setup is only as available as its weakest component. Each card names one part of the stack, the state it holds, what users experience when it fails, and what to confirm in the official docs for your version. Use this list as the starting point for a failure review before you size any node.

Database server

The database holds the records, users, teams and configuration that EspoCRM reads on every request, so it is the first component to design for redundancy. EspoCRM supports MySQL 8.0 or newer, MariaDB 10.6 or newer, or PostgreSQL 15. Confirm in the server configuration docs which replication or failover setups your engine and version support, whether failover is automatic, and whether the application reconnects cleanly after a switch. Also confirm how backups are taken from the replica or primary you choose.

Application servers

Each application node runs PHP 8.3 to 8.5 under Apache, Nginx or IIS. If one node fails, requests in flight on it return errors, and users must retry or reload. Confirm that every node needs the same PHP version, extensions, web server configuration and EspoCRM release, and that a node can be added or removed without a manual reconfiguration of the others. Ask how session state is handled when a user is moved to another node.

Shared file storage

Attachments and custom files live on disk, and a file uploaded through one node must be readable from every other node. If each node keeps its own copy, users will see missing attachments after a load balancer moves them. Confirm the exact directories EspoCRM writes to, whether the version you run supports external or object storage, and how the shared mount is permissioned and backed up. Test an upload on one node and a download on another before go-live.

Cron scheduled task

Background jobs such as scheduled actions, email processing and idle execution of large imports depend on the cron entry that EspoCRM requires. Running cron on every node can duplicate jobs, while running it on one node means background work stops if that node fails. Confirm in the docs for your version how cron should be scheduled in a multi-node setup, whether jobs are locked to prevent duplicate runs, and how you will detect that the scheduler has stopped.

WebSocket daemon

The WebSocket daemon pushes live updates to open browser sessions. If it stops or is unreachable, records still save, but users looking at stale screens will not see changes until they refresh. Confirm whether the daemon runs on one node or on each, which port it uses, what proxy configuration the front end needs to upgrade connections, and how browsers reconnect after a failover. Check this behavior in the docs for your exact version before you choose a topology.

Load balancer or reverse proxy

The load balancer or reverse proxy is the entry point for every user, so a single instance here becomes a single point of failure. The bundled installation script deploys one Docker-based stack with Nginx and MariaDB, which is a useful starting point but not a multi-node design. Confirm the health-check endpoint to use, whether session affinity is needed, how WebSocket upgrades pass through, and the timeouts required for long-running requests and imports.

Which HA pattern fits your EspoCRM team

This table compares three ways to build EspoCRM availability, from one application server with a resilient database to a warm standby node. Read each row against your own recovery targets, which you must define yourself, and against who on your team patches, monitors and tests failover. The main takeaway is that each added application server adds moving parts to operate, so choose the simplest pattern that meets your targets.

PatternWhen it fitsWhat it costs you operationally
Single application server with managed or replicated database and off-host backupsTeams that can rebuild the application server from scripted steps and want the fewest moving partsRebuild steps must be documented and tested. Restore needs both database and file storage to come back in step.
Two or more application servers behind a load balancer with shared storageTeams that need the application tier to keep serving when one server fails, without manual switchingEach node is patched and restarted in turn. Shared file storage, session handling and load balancer health checks need an owner.
Standby node kept warm for manual failoverTeams that want a second server ready but accept that a person decides when to switchThe standby must be patched in step with the primary. Failover runbooks and periodic test switches need a named owner.
Cron and WebSocket daemon placementAny pattern with more than one application serverConfirm which node runs scheduled jobs and the WebSocket daemon so background work is neither duplicated nor missed.
Restore testingEvery pattern, because backups only count once a restore has been provenSomeone must schedule restore tests, record results and repeat them after each EspoCRM upgrade.
On-call coverageDecide before choosing a pattern, since it sets who is woken and for whatSingle node: one rota covers application and database. Multi-node: also load balancer, shared storage and node health.

How to build a multi-server EspoCRM setup step by step

This sequence separates a single EspoCRM instance into a database tier, shared file storage, several application nodes, one designated scheduler, a WebSocket daemon and a load balancer. The result is a setup where any node can serve a request, background jobs run once, and backups cover both data and files. Confirm each release-specific detail against the current EspoCRM documentation before you start.

  1. Inventory the existing instance

    Record everything the current instance depends on before changing its layout. Capture the EspoCRM and PHP versions, every installed extension, the contents of the custom directory, each cron entry on the host, and the size and growth rate of the attachment volume. The team or partner collects this in one pass, and the list drives every later step. This step is done when the inventory is stored with the change records and each custom file has an owner who confirms it is still needed. Extensions and custom code cause most surprises when a second node is added, so review them against the upgrade notes for the target release.

  2. Move the database to its own host

    Run the database on a separate host, either self-managed with replication or as a managed service. Before choosing the engine, confirm the supported options in the EspoCRM server configuration docs, which list MySQL 8.0 or newer, MariaDB 10.6 or newer, or PostgreSQL 15, alongside PHP 8.3 to 8.5. Import a copy of the production database into the new host, point a test application node at it, then log in and save a record. This step is done when the test node reads and writes data it did not create locally, and the people who will operate the database have confirmed the replication or failover settings in writing.

  3. Move attachments and custom files to shared storage

    Attachments and custom files written by one application node must be readable by all of them. Create a shared file system that every node mounts at the same path, copy the existing attachment volume into it, and size it from the inventory. Confirm that file ownership and permissions allow the web server user on each node to read and write. Test by uploading an attachment through one node and opening it through another. This step is done when the file written on one node is visible on the other with identical content, and the mount is restored automatically after a node reboot.

  4. Configure identical application nodes

    Build each application node with the same PHP and EspoCRM versions, the same extensions and the same custom directory, all taken from the inventory. Point config.php on every node at the shared database and shared storage paths. Compare the files with a diff so that only host-specific values differ, and confirm that no node keeps local state the others need. Check that the version shown in the administration interface matches on every node, then log in through each node and open the same record. This step is done when every node serves identical data and the diff output has been reviewed and signed off.

  5. Designate one node for cron

    Background jobs such as scheduled actions, email processing and large imports depend on cron or a scheduled task. If every node runs cron, each job can run more than once. Choose one designated node for the scheduler, or follow the scheduling approach the documentation describes for multi-node setups, and remove the cron entry from every other node. Then create a test scheduled job that writes a log line or a record, trigger it, and count the executions across a full cron cycle. This step is done when the job runs exactly once and the designated node is recorded in the runbook.

  6. Set up the WebSocket daemon

    Start the WebSocket daemon only on the node or nodes that the EspoCRM documentation for your release specifies. Confirm its port and how it is kept running under a process supervisor, because clients rely on it for real-time updates. Open a logged-in browser session, then restart the daemon. Check that the client reconnects without a manual page reload and that a test notification still arrives. This step is done when the reconnection behavior has been observed after at least one restart and the supervisor settings are stored with the configuration.

  7. Place the load balancer and test sessions

    Put a load balancer in front of the application nodes with health checks against an endpoint your release provides, and terminate TLS at the balancer. Decide how sessions persist, then test whether a signed-in user stays signed in when requests move between nodes. Confirm that WebSocket upgrade requests pass through the balancer correctly. Take one application node out of rotation during an active session and observe the result. This step is done when the user experience during failover is documented, including whether sticky sessions are required or a re-login is expected.

  8. Configure and test backups and restores

    Back up the database and the shared file storage on schedules that give a consistent recovery point for both. The EspoCRM installation docs describe a command.sh utility for backups and restores on the script-based stack, so confirm with the release documentation what it covers in a multi-server layout. Store copies outside the cluster. Restore the database and file copy into a test environment, sign in, and open a record with an attachment. This step is done when a complete restore has succeeded and the operations team has recorded the procedure in the runbook.

How to test that EspoCRM fails over and comes back safely

Test each failure mode in a staging copy that matches production topology: the same number of application nodes, the same database arrangement, the same location for cron and the same shared file storage. Record the EspoCRM version, PHP version, database engine and configuration files before every run so the result can be repeated later. Each test should prove three things: the user keeps the work they were doing, the database accepts and keeps writes, and background processing resumes without running the same job twice. A single-node copy can show that the application starts, but it cannot show what a user sees when a node disappears mid-session. Agree on pass criteria with the people who own the data before you start, so nobody decides afterwards that a partial result was acceptable.

Start with the application node. Log in through the load balancer, open a record with several unsaved field edits, then stop the node serving that session. Save the record and confirm the user is not silently logged out and that the edit lands on the surviving node. A session that disappears can leave the user believing a save succeeded when it was rejected, which is one of the worst outcomes in a CRM. Next, stop the active database node and confirm the failover target accepts writes after promotion. Create a lead, edit an account and attach a file. Check that the application reconnects to the configured database host, and that no write shows a success message without reaching the database. Confirm these results with your database platform's own failover behavior, since the exact steps depend on how you built the cluster.

Background work needs its own test. EspoCRM requires cron or a scheduled task for background jobs, so identify which node runs it and stop that node. Before the test, queue a workflow, a scheduled email and a small CSV import. When the surviving node takes over scheduling, confirm each job runs once: count the emails sent, compare the imported record count with the source file, and look for duplicate workflow actions. Then restart the WebSocket daemon and confirm an open browser tab receives a live update from a second user's change without a manual page reload. Finally, restore the latest backup to a clean host and open sample records, attachments and a report. A restore that completes without errors proves little until someone reads the data and confirms it matches the backup time.

A passing result means the user keeps their session and unsaved work, writes survive the database switch, each background job runs once, live updates resume, and the restored copy shows the same records and files as the source at backup time. Failure is acceptable only when the data stays consistent. An import interrupted by a node loss should leave either the rows it completed or a state you can revert, with no half-imported records and missing related entries. Check that the import revert function and your backup both work before you rely on them. Write each scenario down with its start and end time, the observed result, any log entries and the person who verified it. Those notes are the evidence your change management process will ask for at the next upgrade or review.

What drives effort and cost in an EspoCRM HA project

This table lists the factors that change the scope and cost of an EspoCRM high availability project, why each one matters and how to keep it manageable. Read it before requesting a quote so the written scope covers the users, data, integrations and environments the design must carry. The main takeaway is that a self-hosted HA design carries infrastructure and labor costs that you must estimate from your own environment and vendor quotes.

DriverWhy it changes the workHow to keep it down
User count and concurrencyConcurrent sessions set web server and PHP capacity, and peak sales hours drive session and database load.Size from peak concurrent users and load test before go-live.
Data and attachment volumeAttachments on shared storage decide the storage design and how long a full restore takes.Set attachment retention rules early and measure restore time in a test restore.
Integrations and API schedulingEach integration adds API traffic, and batch syncs that overlap with cron jobs compete for the same database.Stagger batch windows, use dedicated API users and map which systems write to which entities.
Custom PHP and front-end codeCode in the custom directory must be retested after every EspoCRM upgrade or failover change.Keep changes in the Entity Manager and formula scripts where possible, and document each custom file.
Number of environmentsStaging, production and DR each need the same stack, data refresh process and configuration checks.Script configuration, limit staging data refreshes and test the DR site on a fixed schedule.
Database engine choiceMySQL 8.0 or newer, MariaDB 10.6 or newer, or PostgreSQL 15 each change replication, backup and tuning steps.Choose the engine your team already operates and confirm the replication method the design needs.
Compliance evidence requirementsAssessors may ask for failover test records, backup logs and access reviews, which add recurring work.Agree evidence needs with your assessor before design and schedule their collection.
Hosting modelEspoCRM Cloud is priced per user per month on the EspoCRM pricing page, while self-hosted HA adds infrastructure and labor costs.Estimate infrastructure and labor from your environment and vendor quotes, then compare them with per-user pricing.

How the HA layout changes by hosting environment

This is the layout the EspoCRM installation script targets. The script deploys a Docker-based stack with Nginx and MariaDB on Ubuntu, Debian or Linux Mint, with optional Let's Encrypt certificates and the command.sh utility for backups, restores and upgrades. Availability in this layout depends on protecting data outside the host and proving you can restore it, because there is no second application server to take over.

  • Cron: EspoCRM needs cron or a scheduled task for background jobs. Confirm that the schedule the installer configures runs inside the stack and resumes after a host reboot.
  • WebSocket daemon: Confirm in the server configuration docs how the daemon starts and is monitored in the Docker stack before you depend on real-time updates.
  • File storage: Attachments sit on the host volume. Make sure your command.sh backup set captures both the database and the file storage, and that both are copied off the host.
  • Restore: Restore to a second host with command.sh, then test sign-in, attachment access and one background job. Time the procedure in your own environment and keep the result with the runbook.

Before you treat this layout as recoverable, check the backup destination, retention period and restore test against the installation docs and your own recovery targets.

Securing the database, file storage and cluster access

A highly available EspoCRM setup multiplies the places where credentials, files and administrative sessions can be exposed. The controls below cover the database, the shared storage, the configuration secrets and the people who reach the nodes and load balancer, so that adding servers does not add unmanaged access paths.

Least-privilege database accounts

Give each application node its own database account with only the privileges EspoCRM needs on its schema, and keep backup credentials separate from the application login. Confirm the account grants with the database administrator for your chosen engine (MySQL 8.0 or newer, MariaDB 10.6 or newer, or PostgreSQL 15), and check that no node connects as a root or owner account.

Encryption in transit and at rest

Encrypt connections between application nodes, the database and the file store where your platform supports it, and encrypt backup copies at rest with keys held outside the backup itself. Ask your database and storage vendors to confirm which TLS versions and key management options apply to your versions, and test that a node refuses a connection with a missing or invalid certificate.

Write access to shared storage

Files uploaded to EspoCRM, such as attachments and exports, live on storage that every node reads. Set ownership so that only the EspoCRM service user can write to the data and cache directories, and make other users read-only or deny them entirely. Review the permissions after each upgrade, because a changed deployment user can silently reopen write access.

Config and secrets outside images

The configuration file config.php holds database details and other settings that should not be baked into container images or copied into shared repositories. Inject values at runtime from a secrets store, restrict who can read the mounted file, and audit any tickets, chat threads or support bundles for pasted copies. Rotate credentials after any suspected exposure.

Admin access to nodes and load balancer

Restrict shell and management access to the application nodes and the load balancer to named administrators, and use IP restrictions on the admin area as the EspoCRM security documentation recommends. Confirm that the allowed networks match your VPN or bastion ranges, and that a change to the list is logged and reviewed.

Separate admin and failover operator accounts

Keep a dedicated administrator account that is never used for daily CRM work, and plan which named people can act as the failover operator during an incident. Decide in advance how that access is granted, time-limited and revoked, and make sure the break-glass path does not depend on a single identity provider login. Two-factor authentication and password policy are covered in the EspoCRM security documentation.

What to monitor, back up and document after go-live

Go-live is where high availability either holds up or quietly degrades, so the first list to agree is what you monitor and who responds to each alert. Start with node health on every application server, including the ones that receive little traffic, and watch CPU, memory, disk and web server or PHP error rates per node. On the database, track replication lag and failover state, and treat any unplanned failover as a signal to investigate, because it usually points to a network or resource problem that will return. Watch free space on the shared storage that holds attachments, since file growth tends to be slow and then sudden. Confirm thresholds and alert routes with your own operations team, because the right values depend on your traffic and data volume.

Background work needs its own checks because EspoCRM depends on cron or a scheduled task for jobs such as email sending, workflow actions and large imports. Confirm that exactly one designated node runs cron and that the schedule is defined once, since duplicate runs across several nodes can send duplicate emails or repeat actions. Track the count of failed jobs that EspoCRM records and alert when it rises above the level your team has agreed is normal. Check the WebSocket daemon's status on the node that hosts it, and confirm in a reboot test that it restarts without manual action. Finally, track certificate expiry on the load balancer or proxy, including any Let's Encrypt renewal if you use the optional certificate setup, and alert well before the expiry date.

Back up the database and the attachment storage on a schedule, and keep at least one copy off the primary site so that a site-level failure does not remove both the data and the means to recover it. Decide retention periods, encryption and who holds the keys during the design phase, before the first incident forces the question. The installation script's command.sh utility covers backups, restores and upgrades for the Docker-based stack it deploys, so confirm whether it fits your layout or whether your own database and storage tooling should take over. Back up the configuration files as well, because a restored database paired with mismatched configuration can behave differently from the production system.

Schedule a restore test at a cadence you choose, based on how much data loss and downtime your business can accept, and run it in a separate environment that mirrors production. Record the time taken from the start of the restore to a working login, every manual step, and any step that depended on one person's knowledge. Those records show whether the recovery plan works and where it needs to be simpler. Upgrades follow the same discipline. Since UI upgrades are disabled by default as of EspoCRM 10.0, run them from the command line, and test each release on a staging copy built with the same high availability layout, including the cron and WebSocket arrangement, before touching production. Check the current 10.0.x releases on the official GitHub releases page before planning each upgrade window.

Keep a living runbook that a second engineer could follow during an out-of-hours incident. It should include a node inventory with each server's role, location and owner, the named person responsible for cron and the WebSocket daemon, the failover steps for the database and the load balancer, the monitoring alert routes, and the date and result of the last successful restore test. Review the runbook after every upgrade and every restore test, and assign one person to confirm the restore test date at each review. A runbook that falls out of date is a common reason recovery takes longer than the design intended, so treat it as part of the system rather than as paperwork.

Questions buyers ask about EspoCRM high availability

Can EspoCRM run on several application servers at once?

Yes in principle, but confirm it for the exact version you run before you design around it. All application servers must share one database, and the EspoCRM server configuration docs list the supported combinations of PHP (8.3 to 8.5), database (MySQL 8.0 or newer, MariaDB 10.6 or newer, or PostgreSQL 15) and web server (Apache, Nginx or IIS). Background jobs depend on cron or a scheduled task, so you must decide which node runs them and make sure they are neither duplicated nor left without an owner. The WebSocket daemon for live updates also needs a planned placement and supervised restarts. Test sessions, file uploads and scheduled jobs across nodes in staging before go-live.

How much does an EspoCRM high availability setup cost?

The total is the sum of infrastructure and labor, and the EspoCRM software itself is free under AGPL-3.0 for the self-hosted edition. Recurring costs include application servers, a database service or clustered database, load balancing, shared file storage for attachments, and backup storage, including any off-site copy. One-time costs cover design, build, failover testing, restore testing and written runbooks. Ongoing labor covers monitoring, patching, on-call coverage and repeating failover tests after upgrades. DeployOpen does not publish a price list. A quote follows from written scope, so ask for line items per component, the environments included, whether restore testing and runbooks are covered, and who operates the system afterward.

How long does an EspoCRM high availability project take?

The duration depends on the scope you agree in writing, so ask for a scoped plan with phases and dependencies before you compare timelines. The main drivers are the number of environments (for example production, staging and a recovery site), the data volume to replicate and verify, the number of integrations that must be re-tested, such as single sign-on, email and API consumers, and whether a restore test is included. Client-side steps also set the pace: access approvals, change windows for cutover and failover tests, and decisions from named owners. As an illustrative example, a single production instance with staging and no integrations is a much smaller scope than a multi-site design with directory and API integrations.

What does EspoCRM high availability need from our team?

Plan on providing access, time and people before the work starts. You will need access to the current infrastructure, including hosts or cloud accounts, DNS, certificates and the existing backup system. You will need change windows for cutover and for failover and restore tests, and named owners for the database, the network and identity, who can approve decisions quickly. A staging environment that resembles production is essential for testing. Also gather the current EspoCRM version, a list of customizations and extensions, the integrations that connect to it, and the recovery time and data loss limits the business has set, since those targets shape the design.

Can our own team set up EspoCRM high availability alone?

Yes, if your team has database and Linux operations skills and time to test failover properly. Check the skills first: can someone operate the database replication or clustering you choose, configure a load balancer for multiple application servers, manage shared storage for uploads, and supervise cron and the WebSocket service so they restart after a failure? Then check time and coverage. Failover and restore testing takes sustained effort, must be repeated after upgrades, and needs someone available when it fails. The vendor's installation script deploys a single-node Docker stack with Nginx and MariaDB, with backup, restore and upgrade commands, which is a useful starting point but not a high availability design on its own.

Is one EspoCRM server with good backups enough?

It depends on the recovery needs the business sets, so define two numbers first: how much recent data the business can lose and how long the CRM can be unavailable. A single server with tested backups may meet a relaxed target, but recovery means rebuilding a server and restoring data by hand, which takes time and depends on the people available that day. Backups alone do not provide failover. Cover the database, attachments, configuration, custom code and scheduled jobs in your backup scope. A backup that has never been restored into a clean environment is unproven, so schedule restore tests and record how long they take.

Which EspoCRM components must be shared between servers?

The database is the core shared component, because every application server must read and write the same CRM records. Uploaded files and attachments must also be available to every node, usually on shared or replicated file storage, so a user on any server can open them. The configuration files must be identical across nodes or managed from one source, and custom code in the custom directory must match on each node after every change. Scheduled jobs and the WebSocket service need one clear owner per job, so nothing runs twice or stops silently. Confirm these requirements against the vendor docs for your version before you finalize the design.

How DeployOpen scopes, builds and hands over EspoCRM HA

DeployOpen plans, implements, hardens, backs up, documents and supports self-hosted open-source platforms inside the client's own infrastructure. For EspoCRM high availability, that means agreeing a written scope first, building the separated tiers in your environment, and handing over runbooks, restore evidence and a support path your team can operate.

How we scope

  • Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts.
  • We inventory your current EspoCRM hosts, PHP and database versions, file storage and cron setup against the server requirements.
  • The written scope names the target topology, failover expectations, backup retention and the restore tests to be performed.

How we build

  • We separate the database, application servers and shared file storage, then configure cron and the WebSocket daemon to run on a single, controlled node.
  • We validate session handling, uploads and background jobs across the servers before any cutover, and document each configuration choice.
  • We run security testing on the deployed instance, covering access controls and exposed services, before handover.

How we hand over

  • You receive architecture documentation, configuration records and runbooks for failover, backup, restore and scheduled jobs.
  • We perform a restore test on a separate environment and provide the results as evidence your team and auditors can review.
  • Hand over includes a walkthrough with your operators so your team can run routine checks without relying on us.

How we support

  • Ongoing support, upgrades and continuous testing are available as retainers, scoped separately from the build.
  • Upgrades are planned against your customizations and extensions, using the command line process for EspoCRM 10 and later.
  • Confirm with us during scoping which support levels, response channels and recovery expectations your retainer will include.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.