Resource Usage

CPU

A single CCF node process runs a host event-loop thread, an enclave coordination thread, and worker threads, along with auxiliary threads. The host manages sockets and files. The enclave coordination thread handles lifecycle events, while worker threads execute tasks including TLS termination, cryptography, and application and key value code. The worker_threads configuration entry (see worker_threads) defaults to 1. CCF starts one more worker than configured, in addition to the coordination thread, to preserve task execution capacity. For example, 1 starts two workers and 2 starts three. A configured value of 0 starts one worker and logs a warning; positive values are incremented silently.

Consensus timers, idle node-channel cleanup and indexing updates run as independent owner-managed periodic tasks. These tasks may execute concurrently with each other and inbound node processing, using the relevant subsystem locks rather than an aggregate ordered lane. Each periodic task accounts for its own elapsed time, including scheduling delays, and prevents overlapping executions of itself. The tasks use the shared worker pool, so blocking all workers can delay consensus. Task lifetime is managed by weak ownership and job-board shutdown after workers have joined, without a separate per-component shutdown cascade. Consensus, channel-manager and indexer construction is followed by periodic-task registration once shared ownership is established. Recovery-service-opening retries use a local delayed task after private recovery completes, rescheduling only while opening remains uncommitted and recovery still applies. Indexing reads its committed transaction ID through a read-only commit-point subsystem, which exposes no usable commit point until the node is part of the network and private recovery is complete.

Memory

The memory available to a CCF node process is ultimately bounded by the environment it runs in, typically the size of the virtual machine (VM) or container, and any additional OS- or container-level limits applied to the process. On SEV-SNP, the node process runs inside a confidential VM; the VM size chosen at deployment time sets an upper bound on the memory that can be made available to the node, subject to any further limits imposed by the guest OS or container.

Note

If a JavaScript application is deployed, then by default the source code is pre-compiled into bytecode and stored in the Key Value store. While this reduces RPC latency it increases memory usage. The size of the bytecode cache can be queried via the /node/js_metrics RPC. See the JavaScript Deployment section for details on enabling or disabling the cache.

Backpressure

A node returns 503 TooManyPendingTransactions for application and governance requests when either its local uncommitted transaction count reaches consensus.max_uncommitted_tx_count, or its pending ledger append bytes reach ledger.max_pending_append_bytes (16MB by default). This applies to reads and writes on both primaries and backups. /node endpoints remain exempt so operators can diagnose a node that is not making progress. Setting consensus.max_uncommitted_tx_count to 0 disables only the transaction-count threshold; setting ledger.max_pending_append_bytes to 0 disables only ledger backlog backpressure.

While its ledger is backlogged, a node also drops incoming AppendEntries replication messages, including heartbeats, without applying them or replying. Normal periodic probes and retransmissions allow it to catch up once ledger IO clears the backlog, at the cost of resending discarded batches. Long IO stalls may cause elections or interrupt service if too few nodes can keep up. Ledger backlog threshold crossings are logged; persistent overload warrants investigating storage latency and node resource contention.

These are admission thresholds, not hard memory caps. The byte threshold covers pending appends, not all queued work or the duration of an IO stall. Already-admitted work and internal operations can continue, and /node-triggered writes are not capped by this gate. Requests are admitted again when both conditions clear; a backup’s uncommitted count also depends on receiving updated commit information from the primary. Completion of a ledger append is not a new per-transaction disk synchronisation guarantee; see Ledger and Snapshots for ledger file persistence and management.