Skip to content

php.ini configuration

The driver reads its configuration from php.ini, or from a file in the conf.d directory. Every setting is PHP_INI_SYSTEM. ini_set() cannot change any of them at runtime.

Why PHP_INI_SYSTEM and not PHP_INI_ALL

The Cluster\Builder seeds below become part of the identity of a cached CassCluster. A request-scoped ini_set() would give each request a different identity, and the persistent cache would grow with no limit inside the worker. The read-only scope is what keeps the cache bounded.

Logging

SettingDefaultValues
cassandra.log_levelERRORCRITICAL, ERROR, WARN, INFO, DEBUG, TRACE
cassandra.logcassandra.logA file path, syslog, stderr, or an empty value for stderr

See Metrics and logging for the log format.

Credentials

SettingDefaultValues
cassandra.expose_credentials01 prints the password in Cluster\Builder debug output

Keep this off in production. See Authentication.

Persistent resources

The driver caches clusters, sessions and prepared statements per PHP-FPM worker. Nothing bounds those caches by default. An application that builds CQL with string concatenation gets one cache slot per distinct query text, so the cache grows until the worker restarts.

SettingDefaultMeaning
cassandra.allow_persistent1Master switch for all three caches
cassandra.max_persistent_clusters-1Cached clusters per worker
cassandra.max_persistent_sessions-1Cached sessions per worker
cassandra.max_persistent_prepared_statements-1Cached prepared statements per worker

-1 means unlimited. 0 disables the cache for that resource.

Past a cap the driver still creates the resource, but does not keep it. The application keeps working, at the cost of one rebuild per request. The driver writes one E_WARNING per request when this first happens, so a saturated cache is visible in the error log.

ini
[cassandra]
; Bound the prepared-statement cache to 512 entries per worker.
cassandra.max_persistent_prepared_statements = 512

cassandra.allow_persistent = 0 is a floor, not a default. With it off, withPersistentSessions(true) cannot turn caching back on. Use it to shut off persistence for a worker pool without a change to the application.

Cluster\Builder defaults

Each setting below is the value a new Cassandra\Cluster\Builder starts with. The matching with*() method still overrides it, so these are deployment defaults, not a lock.

Contact points

SettingDefaultUnit
cassandra.contact_points127.0.0.1Comma-separated hosts
cassandra.port90421 to 65535
cassandra.randomized_contact_points1Boolean
cassandra.hostname_resolution0Boolean

Timeouts

SettingDefaultUnit
cassandra.connect_timeout5000Milliseconds
cassandra.request_timeout12000Milliseconds
cassandra.reconnect_interval2000Milliseconds

Queries

SettingDefaultUnit
cassandra.default_consistencyLOCAL_QUORUMSee the list below
cassandra.default_page_size5000Rows
cassandra.protocol_version41 to 5

Consistency accepts ANY, ONE, TWO, THREE, QUORUM, ALL, LOCAL_QUORUM, EACH_QUORUM, SERIAL, LOCAL_SERIAL and LOCAL_ONE. The name is not case-sensitive.

Do not set this to QUORUM

QUORUM counts replicas in every datacenter. It adds cross-datacenter latency to every query and fails when a remote datacenter is unreachable. LOCAL_QUORUM, the default, gives the same strong read-your-writes guarantee at local latency.

Keep consistency in the application

cassandra.default_consistency is a correctness decision, not a deployment knob. Prefer withDefaultConsistency() in code, where a reader can see it next to the query.

Connection pool

SettingDefaultUnit
cassandra.io_threads1Threads
cassandra.core_connections_per_host1Connections
cassandra.max_connections_per_host2Connections
cassandra.connection_heartbeat_interval30Seconds, 0 disables
cassandra.tcp_keepalive_delay0Seconds, 0 disables
cassandra.tcp_nodelay1Boolean

See Connection pool and timeouts.

ScyllaDB rack-aware routing

SettingDefaultUnit
cassandra.local_dcemptyDatacenter name
cassandra.local_rackemptyRack name

A non-empty cassandra.local_rack turns on rack-aware load balancing. The driver tries live nodes in the local rack first, then the rest of the local datacenter, then remote datacenters. Use it to keep traffic inside one cloud availability zone and cut the cross-zone bill.

ini
cassandra.local_dc   = eu-west-1
cassandra.local_rack = eu-west-1a

Leave both empty to keep the current policy. If you set only cassandra.local_rack, the driver infers the datacenter from the first contact point it reaches, so list contact points from the local rack only.

This setting needs the ScyllaDB C/C++ driver. The upstream DataStax driver does not have it.

Application identity

SettingDefaultUnit
cassandra.application_nameemptyFree text
cassandra.application_versionemptyFree text

The server records both. Query them to see which application and which version opens the connections:

sql
SELECT address, client_options FROM system.clients;

client_options then contains APPLICATION_NAME and APPLICATION_VERSION.

Reconnection

SettingDefaultUnit
cassandra.reconnect_policyconstantconstant or exponential
cassandra.reconnect_max_interval60000Milliseconds

With constant, the driver waits cassandra.reconnect_interval between every attempt. With exponential, that value becomes the base delay and the wait grows to cassandra.reconnect_max_interval, plus or minus 15 percent of jitter.

Prefer exponential for a large worker pool. A constant delay makes every worker retry a recovering node at the same moment.

Speculative execution

SettingDefaultUnit
cassandra.speculative_execution_delay0Milliseconds, 0 disables
cassandra.speculative_execution_max2Extra attempts

The driver sends the same request to another replica when the first one does not answer within the delay. It cuts tail latency caused by one slow replica.

Only for idempotent statements

The driver only runs a statement speculatively when you mark it idempotent, so this setting does nothing until you call setIdempotent() on the statement or pass the idempotent execution option. See Idempotence.

Never mark a counter update, a lightweight transaction, or an append to a list as idempotent. Speculative execution also multiplies load, so keep it off while the cluster is already saturated.

Event loop tuning

SettingDefaultUnit
cassandra.coalesce_delay200Microseconds
cassandra.new_request_ratio501 to 100
cassandra.queue_size_io8192Queued requests per IO thread

coalesce_delay is how long the driver waits to batch writes into one system call. new_request_ratio splits IO thread time between accepting new requests and finishing outstanding ones.

Change these against a measurement

The defaults come from the C driver and suit most deployments. PHP-FPM handles one request per process, so there is little to batch. Do not change either without a benchmark of your own workload.

Nine directives do nothing on the scylla-rust backend

cpp-rs-driver does not declare the setter behind cassandra.new_request_ratio, cassandra.queue_size_io, cassandra.monitor_reporting_interval, cassandra.prepare_on_all_hosts, cassandra.prepare_on_up_or_add_host, cassandra.no_compact, cassandra.tracing_consistency, cassandra.tracing_max_wait_time or cassandra.tracing_retry_wait_time. Each keeps its driver default on that backend. Every other directive, including execution profiles and rack-aware routing, works on all three backends.

Connection lifetime

SettingDefaultUnit
cassandra.connection_idle_timeout60Seconds an unused connection stays open
cassandra.max_schema_wait_time10000Milliseconds to wait for schema agreement
cassandra.resolve_timeout2000Milliseconds for a hostname lookup
cassandra.monitor_reporting_interval300Seconds, 0 disables
cassandra.local_addressemptySource address for outgoing connections

Set cassandra.local_address on a host with several interfaces, to pick the one that reaches the cluster. An empty value lets the kernel choose.

Prepared statements

SettingDefaultUnit
cassandra.prepare_on_all_hosts1Boolean
cassandra.prepare_on_up_or_add_host1Boolean

The driver prepares a statement on every node, not only on the coordinator, and prepares again when a node comes up or joins. Leave both on. With them off, a query that lands on a node which never saw the prepare pays an extra round trip.

Protocol and routing

SettingDefaultUnit
cassandra.shuffle_replicas1Boolean
cassandra.no_compact0Boolean
cassandra.beta_protocol0Boolean

shuffle_replicas spreads reads of one partition over its replicas instead of always choosing the first. Turn it off only to make a benchmark repeatable.

no_compact asks the server to show COMPACT STORAGE tables in their non-compact form. It matters only for a cluster that still has such tables.

beta_protocol is for testing

A beta native protocol can change between server releases. Never set this in production.

Request tracing

SettingDefaultUnit
cassandra.tracing_consistencyONEConsistency name
cassandra.tracing_max_wait_time15Milliseconds
cassandra.tracing_retry_wait_time3Milliseconds

These apply only to statements that turn tracing on. The server writes the trace after it answers the query, so the driver polls for it. A wait that is too short returns an incomplete trace.

Routing and metadata

SettingDefaultUnit
cassandra.token_aware_routing1Boolean
cassandra.latency_aware_routing1Boolean
cassandra.schema_metadata1Boolean

See Load balancing and routing.

Bad values

The driver ignores a bad value and keeps the documented default. It does not clamp the value, and it does not refuse to start. Each rejected directive writes one E_WARNING at startup that names the value it ignored.

ini_get() and phpinfo() report the default in that case, so what they show is always what the driver uses.

ini
cassandra.port = 99999
Warning: cassandra | cassandra.port must be between 1 and 65535, ignoring '99999' and using the default

ini_get('cassandra.port') then returns 9042, and the driver connects on port 9042.

Example

ini
[cassandra]
extension=cassandra.so

cassandra.log = syslog
cassandra.log_level = WARN

cassandra.contact_points = db-1.internal,db-2.internal,db-3.internal
cassandra.connect_timeout = 3000
cassandra.request_timeout = 8000

cassandra.io_threads = 4
cassandra.core_connections_per_host = 2
cassandra.max_connections_per_host = 8

cassandra.max_persistent_prepared_statements = 512

Version 1.4. Released under the Apache License 2.0.