How to size OpenCTI and Elasticsearch before the data arrives
The documented minimums for OpenCTI are a floor, not a sizing result. The actual sizing depends on data volume, connector count and worker load, and the minimums do not account for any of those inputs. The deployment overview lists 2 cores and at least 8 GB of RAM for the platform, 2 cores, 8 GB of RAM and 16 GB of SSD for Elasticsearch or OpenSearch, and at least one platform node for every 3 workers. A team that has chosen OpenCTI still has to decide how large the platform, the search engine, Redis, RabbitMQ and object storage need to be for the data it expects to hold, so treat these figures as the starting line for a capacity model.
Sizing is harder than the minimums suggest because each component scales on a different input. The platform serves the web application and GraphQL API, so its load follows analyst activity and queries. Workers consume RabbitMQ messages for asynchronous writes, so their load follows the volume of incoming changes. Elasticsearch or OpenSearch indexes what has been written, so its memory and disk needs grow with stored entities and relationships. Connectors sit upstream of all of this. Switching on a new feed or enrichment connector can multiply write load through the queues and workers while the platform configuration stays unchanged, so a deployment that handled light testing can lag once a connector runs at full volume.
Confirm the dependency versions before you size anything, because the capacity model depends on the engine and versions you deploy. The documented minimums are Elasticsearch 8.0 or OpenSearch 2.9 or later, Redis 7.1 or later, RabbitMQ 3.11 or later, and S3-compatible storage such as MinIO. Check these against the OpenCTI release line you plan to run, and confirm with Filigran whether the minimums differ between continuous and LTS releases. Make the search engine decision early, since a managed service, a self-hosted cluster or a vendor-supported distribution each changes who sizes, patches and backs up the index. Object storage needs its own estimate of file volume and retention, which the search index does not capture.
Plan this work at three moments: when a pilot is promoted to production, before a large feed or connector is switched on, and when indexing lags behind ingestion. At each point, capture the measurements the minimums cannot give you, including RabbitMQ queue depth, worker throughput, indexing lag, search heap and disk use, and object storage growth. Use them to build a capacity model and a load test that replays a representative mix of connectors. When you request a quote for this work, ask which environments are in scope, how many connectors the load test covers, what the deliverable is (a sizing model, a test report or a tuned configuration), and whether re-sizing after each new connector is included or priced separately.
Which components carry the load in an OpenCTI deployment
Each component in an OpenCTI deployment takes load from a different direction, and the platform node and worker counts link them together. The documented minimums below are starting points for planning, not production targets. Use them to decide what to measure first as data volume and connector count grow.
Platform node (UI and GraphQL API)
The platform serves the web application and the GraphQL API that analysts, connectors and integrations call. The documented minimum is 2 cores and at least 8 GB RAM per node, which is a starting minimum that does not account for concurrent use. Check how many analysts and API clients you expect, because dashboards and bulk API reads load this tier directly.
Python workers and the platform ratio
Workers consume RabbitMQ messages and perform the asynchronous writes the platform queues, so ingestion speed depends on them as much as on the UI tier. The documented guidance recommends at least one platform node for every 3 workers. When you add workers to clear a backlog, confirm that the platform tier still meets that ratio, and watch queue depth and search write latency together.
Connectors for import, enrichment and export
Connectors run import, enrichment, file extraction, export and stream consumption jobs, and each one adds writes, reads and queue messages. Their load depends on feed size, polling frequency and how many enrichment lookups each imported object triggers. Inventory the connectors you plan to run, with their schedules and expected object volumes, before sizing workers.
Elasticsearch or OpenSearch index
The search index stores and serves the knowledge graph for queries, filters and dashboards. The documented minimum is 2 cores, 8 GB RAM and 16 GB SSD, and supported versions start at Elasticsearch 8.0 or OpenSearch 2.9. Index size grows with every ingested object and relationship, so track disk growth and heap pressure from the start, and confirm current shard and replica guidance in the official deployment documentation.
Redis and RabbitMQ coordination layer
RabbitMQ queues the messages that workers consume, and Redis backs the platform's cache and coordination. The supported minimums are Redis 7.1 and RabbitMQ 3.11. No sizing figures for either were supplied for this page, so confirm current memory, connection and queue guidance in the official deployment documentation before choosing instance sizes. Monitor queue depth and Redis memory during large imports.
S3-compatible object storage
S3-compatible storage, such as MinIO, holds files that the platform and connectors handle, including uploads and file extraction inputs. Its load follows file volume and upload frequency, and it sees little query traffic. Agree retention and backup expectations with your team early, because stored files accumulate over time and affect both capacity and recovery planning.
Which sizing decisions shape cost and operations
This table compares the main sizing decisions for an OpenCTI deployment and the operational cost each one carries. Read each row by checking when the option fits your environment, then the patching, upgrade, monitoring and failure-domain effects it brings. The main takeaway is that platform, search and storage choices usually cost more to run over time than they cost to set up.
| Decision | When the option fits | Operational cost |
|---|---|---|
| Elasticsearch or OpenSearch | Fits when your team already operates one engine at or above the documented floor and can confirm the release pairing. | Each engine brings its own patch cadence, licensing terms and upgrade path. Confirm the pairing with your OpenCTI release first. |
| Single host or separated components | A single host fits a pilot or lab with no uptime target. Separation fits production where search and queues need independent recovery. | Separation adds hosts to patch, monitor and back up, but a failure in one tier stops only that tier. |
| Number of workers and platform nodes | Fits when connector volume is known. The documented guidance is at least one platform node for every 3 workers. | Each added worker and node raises queue traffic, search writes and monitoring scope. Re-check the ratio as connectors are added. |
| Search index sized for growth or scaled in steps | Growth sizing fits large expected connector intake. Stepwise scaling fits teams that can add capacity based on their own monitoring. | Oversizing ties up storage and memory from day one. Stepwise scaling needs planned change windows to add nodes and rebalance data. |
| Self-managed MinIO or existing S3-compatible service | Self-managed MinIO fits isolated networks with no shared storage. An existing service fits teams with storage operations already in place. | MinIO adds a stateful service to patch and back up. A shared service adds bucket policy dependencies to confirm with its owner. |
| Redis and RabbitMQ placement | Co-locating fits when one platform team owns queues and cache. Dedicated instances fit when each has a separate owner or access rule. | Each service has its own version floor (Redis 7.1, RabbitMQ 3.11) and needs monitoring for queue backlog and memory use. |
How to size and stand up the stack in sequence
Each step builds on the one before it, so the data plan sets the search and queue sizing, and the platform is provisioned only after those choices are fixed. Every step closes with a check the team can record, and the sequence ends with a baseline of resource use that later growth can be measured against.
Inventory data sources and planned connectors
Your team lists every feed and connector planned for the first 90 days, including whether each is an import, enrichment, file extraction, export or stream connector, and the worker capacity each one will consume. For each entry, record the expected object volume, the owner who approves its data and whether it runs on a schedule or continuously. This list drives every sizing decision that follows, so it should be signed off before any hardware or cloud resources are requested. Closing check: a written inventory in which every connector has a named owner, a volume estimate and a stated run pattern.
Choose the OpenCTI release line
Decide between the regular releases, which use the x.YYMMDD.z numbering, and the LTS line, which uses x.YYMMDD.z-lts.n and requires a specific LTS license key. Read the release notes and deployment documentation for the chosen version, then record the Elasticsearch or OpenSearch, Redis, RabbitMQ and S3-compatible storage versions it documents. The deployment overview lists Elasticsearch 8.0 or OpenSearch 2.9 or later, Redis 7.1 or later, and RabbitMQ 3.11 or later as minimums. Ask the vendor or DeployOpen to confirm any connector version your inventory depends on. Closing check: a dependency matrix, signed by the platform owner, that lists the exact versions to deploy.
Size the search and queue layers first
Search and queue hold the data, so size them before the platform and workers. Start from the documented minimum for Elasticsearch or OpenSearch, which is 2 cores, 8 GB RAM and 16 GB SSD, then project index growth from the inventory volumes and the retention period your team plans to keep. Ask the vendor to confirm how index size scales with entity volume before relying on any estimate you build. Closing check: a capacity model with projected search disk use at several points in time and a written disk threshold, agreed by the platform owner, that triggers expansion.
Provision the platform node and workers
Deploy the platform with at least 2 cores and 8 GB RAM, the documented minimum, and add workers in line with the documented ratio of at least one platform node for every 3 workers. Workers consume RabbitMQ messages for asynchronous writes, so place them where they can reach the queue reliably and with predictable latency. Your infrastructure team or DeployOpen sets the final node sizes and orchestration pattern for your environment. Closing check: all services report healthy, the UI and GraphQL API respond, and a test login succeeds through the chosen authentication method.
Configure Redis and RabbitMQ at minimum versions
Deploy Redis at version 7.1 or later and RabbitMQ at 3.11 or later, matching the versions recorded in the dependency matrix. Confirm the platform connects to both services and that the queues it creates are visible, then set memory and retention alarms according to the vendor documentation for those versions. Run a small test import and watch queue depth return to zero before the import is marked complete. Closing check: the message queue drains between imports, and both services report the versions in the matrix.
Set up S3-compatible object storage
Provision an S3-compatible store, such as MinIO, that OpenCTI can reach with dedicated credentials, and create the buckets the platform expects. Scope the access key to those buckets only, and place the store on storage that matches the retention and backup needs recorded in the first step. Confirm with the vendor which encryption, versioning and lifecycle settings your chosen product supports for OpenCTI. Closing check: the platform writes and reads a test file through the storage API, and the access key cannot reach buckets outside the OpenCTI scope.
Enable connectors in stages with checks
Turn on connectors one group at a time, in the order set by the inventory, starting with the lowest-volume feeds. After each group, watch queue depth, indexing lag and worker load, and wait for the queue to drain and lag to return to its earlier level before enabling the next group. Record any connector that causes repeated backlog so it can be tuned, rescheduled or deduplicated before it runs again. Closing check: a log entry for each stage showing queue depth and indexing lag before and after the change, with every stage closed by a drained queue.
Record the baseline resource use
Once all planned connectors run, capture CPU, memory, disk and queue figures for the platform, workers, search, Redis, RabbitMQ and object storage under normal load. Store the baseline with its date, connector set and component versions so later changes can be compared against it. Compare the search disk trend with the projection from the sizing step and note any gap for the capacity review. Closing check: a baseline document for each component, signed off by the platform owner, with search disk use tracking the projection or a documented reason for the difference.
What drives sizing effort and how to keep each part down
This table lists the main drivers of OpenCTI and Elasticsearch sizing work, how each one changes load on the platform, workers, search and queues, and what the team can do to keep it contained. Read it as a checklist for scoping, since the largest effort usually comes from measuring and tuning after go-live rather than from the initial install.
| Driver | How it changes load | How to keep it down |
|---|---|---|
| Analysts and concurrent users | More concurrent sessions increase GraphQL API requests and platform node CPU and memory, and heavier graph queries add pressure on Elasticsearch or OpenSearch reads. | Confirm the peak concurrent user count early, scale platform nodes horizontally, and keep dashboards and saved searches lean so each view queries only the data it needs. |
| Volume of imported STIX2 objects | Every imported object becomes indexed data and a queued write, so ingestion volume drives Elasticsearch or OpenSearch disk, indexing rate and RabbitMQ message throughput. | Filter feeds to the object types and confidence levels analysts use, and measure object counts per week so growth is visible before it reaches storage limits. |
| Number and schedule of connectors | Each connector runs its own import or enrichment loop, so more connectors and shorter schedules raise queue depth, Python worker demand and Redis activity. | Stagger connector schedules so large imports do not start together, and add connectors one at a time while watching queue depth between additions. |
| Enrichment fan-out | One observable can trigger several enrichment connectors, and each result creates more objects and relationships, which multiplies writes in the queue and the index. | Enable only the enrichment services analysts use, set scope rules for what gets enriched, and review the connector list each quarter for unused services. |
| Duplicate and overlapping feeds | Feeds that repeat the same indicators inflate object counts without adding analytical value, raising index size and worker time for each duplicate. | Deduplicate feeds at the source where possible, compare overlapping connectors on a sample, and retire feeds that analysts no longer query. |
| File extraction workload | Extracting content from uploaded or imported files uses CPU on workers, adds temporary storage and creates additional indexed text for full-text search. | Limit file extraction to file types and sizes analysts need, and confirm with Filigran's documentation whether full-text document indexing is included in your edition before enabling it. |
| Environments (test, staging, production) | Each environment needs its own platform, workers, search, queues and object storage, so non-production copies add infrastructure and maintenance effort even when they run at low load. | Keep a separate test environment for upgrades and connector changes, use reduced data volumes outside production, and ask the partner to price non-production environments as their own line item. |
| Retention and object storage growth | Longer retention keeps more indexed objects and uploaded files in Elasticsearch or OpenSearch and S3-compatible storage, so disk growth is steady and cumulative. | Define retention rules per data source before go-live, archive or expire low-value data on a schedule, and track storage growth monthly against the sizing baseline. |
| Measuring and tuning after go-live | Real load differs from the documented minimums once connectors and users are live, so most sizing effort falls on monitoring queue depth, index health, memory pressure and response times, then adjusting. | Agree on the metrics to monitor and the thresholds that trigger action at scoping, budget time for tuning cycles after go-live, and ask for a written tuning report in the quote. |
How sizing changes for a lab, a single production node and a split deployment
A single-host lab runs the platform, workers, Elasticsearch or OpenSearch, Redis, RabbitMQ and S3-compatible storage on one machine. The documented minimums give the platform 2 cores and at least 8 GB RAM, and the search engine 2 cores, 8 GB RAM and 16 GB SSD. The host must cover those figures plus every other component, so a lab is best used to test functionality, not load.
- Resource pressure: The search engine and the platform compete for memory on one host. Confirm the host exceeds the documented minimums before adding connectors.
- Measure: Startup time, container memory use, and how long a connector import takes on sample data.
- Patching: Restarting the host restarts every component. This is acceptable for a lab but not for a shared analyst team.
- Backup: A host-level snapshot is usually enough, and sample data can be reloaded from exports.
- Failure isolation: None. A disk or memory fault stops every component at once.
Before reusing lab figures in production, confirm with Filigran's current deployment guidance which dependency versions the release expects.
A single production node means one platform node with separate dependency hosts. Sizing starts from the platform minimum of 2 cores and 8 GB RAM and the search minimum, but production needs headroom for indexing peaks and analyst queries. Workers consume RabbitMQ messages, and the documented ratio is at least one platform node for every 3 workers, so the planned worker count determines whether a second platform node is needed.
- Dependency hosts: Search, Redis, RabbitMQ and object storage are sized separately, and the search host usually carries the largest share of memory and disk.
- Measure: RabbitMQ queue depth, search heap use, weekly disk growth, and platform response time under typical analyst load.
- Patching: Platform restarts interrupt analysts, so schedule maintenance windows. Dependency patches can be staged on one host at a time.
- Backup: Back up search indices and object storage together, and test restores on a separate host.
- Failure isolation: A dependency failure halts ingestion, and a single platform node means no UI or API access during restarts.
Compare queue depth and disk growth against the worker count you plan to run, and set a date for the next capacity review.
In a split deployment, the platform, workers and dependencies run on separate hosts or in separate cloud accounts. The sizing unit moves from one machine to each role. The ratio of at least one platform node for every 3 workers sets the minimum platform count as workers grow, and network latency and cross-account access become sizing inputs in their own right.
- Per-role sizing: Size each platform node, worker host and dependency host from its documented minimum, then add headroom based on load tests.
- Measure: Cross-host latency, throughput per worker host, RabbitMQ connection counts, and search indexing rate.
- Patching: Roll platform nodes one at a time to keep the service available. Coordinate dependency upgrades because version compatibility spans hosts.
- Backup: Each host or account has its own snapshot and access path, which adds recovery steps that must be tested.
- Failure isolation: A worker host failure affects only the queues it consumes, while a shared search cluster failure still affects every role.
- Air-gapped sites: Every host role needs offline container images and offline dependency packages, so build a complete inventory before installation.
Ask the vendor to confirm the supported topologies for your version, and confirm the full offline package list before splitting components across accounts or networks.
How to test that the sized stack holds under load and fails safely
Test the sizing before analysts depend on it. A sizing plan is a set of estimates until a load test shows how the platform, workers, Elasticsearch or OpenSearch, Redis, RabbitMQ and object storage behave under the work you actually plan to run. Agree the pass criteria in writing before the first run, using the thresholds in your sizing plan, and confirm each one with the team that owns that component. The test should answer three questions: does the stack keep up with planned input, does it recover when something breaks, and is the data correct afterward.
Build the load test from the planned connector schedule and import sizes, not from a generic volume. Replay the schedule, including any bursts that occur when several connectors import at the same time, and run long enough for the largest scheduled import to finish and for the queue to return to its normal level. Watch RabbitMQ queue depth, worker throughput in messages processed per minute, search indexing lag between a write and its appearance in search, Redis memory use and object storage growth compared with the files you expect each import to produce. Check the worker count against the documented guidance of at least one platform node for every 3 workers, and confirm with your vendor or the deployment overview how Redis memory grows under your workload.
Then run the failure tests during a load run, because that is when they matter most. Stop one worker and confirm that its unprocessed messages stay in RabbitMQ and are processed after restart without loss. Restart Elasticsearch or OpenSearch and confirm that the platform reports the outage or degraded search instead of accepting writes it cannot index silently. Fill the queue to the point where RabbitMQ applies memory or disk limits, then confirm how producers slow down and whether the platform recovers once the queue drains. Record what each component does in your version, since behavior during outages differs between releases, and confirm details with the documentation for your deployed version.
Recovery is only complete when the data is correct. After each failure test, compare entity and relationship counts for each connector with the counts in the source feed, check for duplicate objects, spot-check a sample of records against the source, and confirm that recently imported objects appear in search. Check that connector outputs match the source feed for identifiers, dates and markings, not only for totals. A platform that comes back up with missing or duplicated intelligence has failed the test, even if every service shows as healthy.
Record the results as the baseline for later upgrades. Store the component versions, the configuration, the test inputs, the queue and lag graphs, the pass and fail results and any changes you made during testing alongside the sizing decision. OpenCTI publishes regular releases and LTS lines, with each LTS line supported for one year, so the same scenarios should be re-run before you move to a new release or change a dependency. A stored baseline lets you show whether an upgrade changed throughput, recovery or data accuracy, rather than relying on memory of how the stack behaved last time.
What to monitor, keep and document once the stack is sized
A sizing decision is only as good as the measurements that justify it and the records that keep it current. The cards below cover what to watch on each dependency, what to back up as data grows, and what to write down so the next release change can be checked against a known baseline.
Queue depth and worker health
OpenCTI workers consume RabbitMQ messages for asynchronous writes, so a growing queue is the first sign that workers cannot keep pace with imports and connectors. Track queue depth over time, not just at a moment, and compare it against the worker count you sized for. Check that each worker stays connected and restarts rarely, since a silently stalled worker can look like a healthy queue with delayed data.
Elasticsearch or OpenSearch disk and heap
The search index is the component most likely to outgrow its disk and heap as indicators and relationships accumulate. Watch heap pressure, garbage collection behavior, free disk space and shard sizes on the index nodes, and set alerts well before the disk fills. Record the growth rate in the baseline so you can estimate when the next disk expansion is needed.
Redis memory use
Redis holds cache and transient state for the platform, and its memory use can rise with concurrent users and queued work. Track used memory against the instance limit and watch for evictions or out-of-memory errors, which signal that the instance was sized too small. Confirm the Redis version you run meets the documented minimum of 7.1 before you rely on these metrics.
RabbitMQ message backlog
RabbitMQ carries the messages between the platform and workers, so its backlog and unacknowledged message counts show how far the pipeline lags behind incoming work. Watch queue length, message rates and memory or disk alarms on the broker, and confirm the broker runs at or above the documented minimum of 3.11. A backlog that never drains usually points to too few workers or a connector sending more data than planned.
Object storage growth
Files and exports held in S3-compatible storage grow with every file import and enrichment, and this growth is separate from the index. Track bucket size and object counts over time and compare them against the storage you sized. Confirm how your chosen storage handles deletion and retention, since data removed in OpenCTI may not free space in the bucket automatically.
Backups of the index and object storage
Treat backup size as a sizing input, because the search index and object storage both grow with the data you keep. Schedule backups of the index and the bucket, record how long a restore takes in a test environment, and confirm the backup storage has room for several retention periods. Backup scope and restore procedures should be agreed with your recovery requirements, which this page does not design.
The sizing record and re-measurement
Document the sizing decision with the baseline measurements taken at go-live, the connector schedule that produced the load, and the exact dependency versions in use. Before each platform or dependency change, re-measure the same indicators and compare them with the record, then update the record with the result. This keeps the next upgrade decision grounded in observed data rather than memory.
What buyers and engineers ask before sizing OpenCTI
How much infrastructure does OpenCTI need to start?
The documented minimums are 2 cores and at least 8 GB RAM for the platform, and 2 cores, 8 GB RAM and 16 GB SSD for Elasticsearch or OpenSearch. These are starting points for a small test environment, not production sizing. Production need depends on the number of objects you will store, how many connectors import and enrich data, how long you keep data in the search index, how many analysts query the platform at once, and how many workers process messages. Plan for the dependencies as well: Redis 7.1 or later, RabbitMQ 3.11 or later, and S3-compatible object storage. Confirm current guidance for your release in the OpenCTI deployment documentation before you buy hardware.
Should we run Elasticsearch or OpenSearch for OpenCTI?
Both are supported search backends. The documentation lists Elasticsearch 8.0 or OpenSearch 2.9 or later, so the choice comes down to your organization's existing standards, licensing terms, support contracts, managed service options and the skills your operations team already has. Nothing in the sizing minimums makes one option cheaper or faster by default. Before you commit, check the version compatibility for the OpenCTI release you plan to run, and confirm that your search cluster meets the same memory, disk and snapshot requirements under your own data volumes. Ask your vendor or partner to document the choice in the design record.
How many workers should an OpenCTI deployment run?
The documented guidance is at least one platform node for every 3 workers. Worker count is driven by message volume rather than by the platform alone. Workers consume RabbitMQ messages for asynchronous writes, so the number you need depends on how quickly connectors produce work and how quickly workers drain the queues. Start with the documented ratio, run a representative import, and watch queue depth and time to drain the backlog. Add workers when the backlog grows during normal operation, and record each change so you can explain the sizing later.
What happens to OpenCTI performance when new connectors add load?
Each connector sends import, enrichment or export work through RabbitMQ to the workers, which then write into the platform and the search index. A new connector adds messages to the queues, more indexing work for Elasticsearch or OpenSearch, and more write activity against Redis. The early symptoms are growing queue depth, slower interface responses, and enrichment that arrives hours late. Measure before and after each connector goes live: queue length, worker throughput, search indexing rate, heap and disk use on the search nodes, and Redis memory. Onboard connectors in stages so you can attribute each change to one source.
How long does OpenCTI sizing take, and what does it need from our team?
The duration depends on the scope: how many connectors you plan to run, how much historical data you need to load, whether you can use a representative environment, and how many environments you must cover, such as test, staging and production. No fixed duration applies across these cases, so ask for a written estimate that lists the phases and their exit criteria. Your team should provide access to a test environment, the connector list with expected data volumes, the retention rules, a named owner for cloud or data center accounts, and monitoring for the platform, search cluster, Redis and RabbitMQ. Decision-makers should confirm the retention and access requirements early, because they change the results.
Can our internal team size OpenCTI without an outside partner?
Yes, if your team has working experience with Linux, containers, the chosen search engine, RabbitMQ and Redis, and time to run a load test with data that resembles your production feeds. The main risks are sizing on synthetic data, missing growth in connector volume, and treating the documented minimums as the target. A fixed-scope engagement can cover the same work with a written scope, deliverables and timeline agreed before work starts. DeployOpen plans and implements self-hosted open-source platforms inside the client's own cloud accounts, data centers or air-gapped networks, so the sizing results stay in your environment.
What drives the ongoing infrastructure cost of an OpenCTI deployment?
Most of the recurring cost is compute and storage: platform nodes, workers, the search cluster with its SSD-backed disks, Redis, RabbitMQ and object storage for files. The largest driver is usually how much data you keep in the search index and how long you retain it, followed by the number of workers needed to keep queues short. One-time costs include design, load testing and initial migration of data. If you plan to run an LTS release, check the license terms separately, because LTS releases require a specific license key. Ask any quote to separate hardware or cloud spend, licensing, implementation effort and ongoing support, so you can compare options on the same basis.
How DeployOpen scopes, sizes and hands over an OpenCTI stack
DeployOpen scopes OpenCTI platform and Elasticsearch sizing from the documented minimums, then adjusts them to your data volume, connector count and infrastructure. Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts. The work runs inside your own cloud accounts, data centers or air-gapped networks.
How we scope
- Written scope lists the platform, worker, Elasticsearch or OpenSearch, Redis, RabbitMQ and object storage components in each environment.
- Sizing inputs include expected threat intelligence volume, connector count, retention needs and growth expectations agreed with your team.
- Fixed-scope engagements set deliverables and timelines in writing before work starts, and a quote follows from that scope.
How we build
- Deploy at the documented minimums, then size each tier to the agreed data and connector load.
- Apply the documented ratio of at least one platform node for every three workers.
- Test indexing and search against representative data volumes, then record measured headroom for each component.
How we hand over
- Sizing document covers component versions, resource requests, scaling triggers and the assumptions behind each number.
- Runbooks describe monitoring of queue depth, search heap and disk use, plus steps for adding workers or nodes.
- Knowledge transfer sessions walk your operators through the build, tests and upgrade path before sign-off.
How we support
- Ongoing support, upgrades and testing are available as retainers, scoped separately from the initial build.
- Resize triggers are reviewed as connector counts and feed volumes change, and the sizing document is updated.
- Confirm the dependency versions required by your chosen OpenCTI release line before the sizing is signed off.

