Collections API, configsets & replica placement

This section documents the current Solr line (10.0; 9.10.x the maintained 9.x branch), written and verified against the Apache Solr Reference Guide. No specific patch version is pinned. Some capabilities (the Solr Operator on Kubernetes, the package-manager ecosystem, Learning To Rank model training, and expert plugin development) are linked, not documented in depth.

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

This section’s bibliography lists the reference material consulted while preparing these pages.

A SolrCloud collection is created, reshaped and torn down through the Collections API — an HTTP control plane, not a schema or config change — while the config files it starts from (solrconfig.xml, the managed schema, stopwords, synonyms…​) live in ZooKeeper as a reusable configset, uploaded and managed through the separate Configset API. A collection can also be addressed indirectly through an alias, including aliases that automatically create a new backing collection per time window or per category value. Finally, deciding where a new replica actually lands is the job of a replica-placement plugin — the mechanism that replaced Solr’s now-removed autoscaling framework. This page assumes the shard/replica/leader vocabulary from SolrCloud architecture; it does not repeat it.

Configsets & the Configset API

A configset is a named directory tree — solrconfig.xml, managed-schema (or schema.xml), and any auxiliary files such as stopword or synonym lists — stored under /configs/<name> in ZooKeeper. Every collection references exactly one configset at creation time via collection.configName; multiple collections may share the same configset, and updating it (then `RELOAD`ing the collections) is how a config change reaches all of them at once.

bin/solr create bootstraps a configset from the _default template and uploads it in one step for quick starts. For anything beyond that — a hand-edited schema, a shared template used by many collections — upload and manage configsets explicitly through the Configset API:

# Upload a local configset directory (zipped) as "books-config"
curl -X POST --header "Content-Type:application/octet-stream" \
  --data-binary @books-config.zip \
  "http://localhost:8983/solr/admin/configs?action=UPLOAD&name=books-config"

# Create a new configset by copying an existing one ("base") and overlaying it
curl "http://localhost:8983/solr/admin/configs?action=CREATE&name=books-config-v2&baseConfigSet=books-config"

# List / delete configsets
curl "http://localhost:8983/solr/admin/configs?action=LIST"
curl "http://localhost:8983/solr/admin/configs?action=DELETE&name=books-config-v2"

By default an uploaded configset is trusted only when uploaded by an authenticated admin; an untrusted configset (uploaded without authentication where security is enabled) cannot use <lib> directives to load external jars, closing off a plugin-loading attack path. See Configsets API and Security for the trust model.

The Collections API

Every cluster-shape change — creating a collection, adding or removing a replica, splitting a shard — is one HTTP call against /solr/admin/collections, executed by the Overseer and applied across the cluster state in ZooKeeper. See Collection Management for the full action reference; the commands below cover the ones used day to day.

# CREATE -- 3 shards over the compositeId router, 2 replicas per shard, from an uploaded configset
curl "http://localhost:8983/solr/admin/collections?action=CREATE&name=books&numShards=3\
&replicationFactor=2&collection.configName=books-config&router.name=compositeId"

# RELOAD -- pick up a configset change (new solrconfig.xml / schema) without recreating the collection
curl "http://localhost:8983/solr/admin/collections?action=RELOAD&name=books"

# MODIFYCOLLECTION -- change a mutable collection-level attribute in place
curl "http://localhost:8983/solr/admin/collections?action=MODIFYCOLLECTION&collection=books\
&readOnly=true"

# DELETE -- removes the collection and its ZooKeeper state (data included; irreversible)
curl "http://localhost:8983/solr/admin/collections?action=DELETE&name=books"

Growing a collection past its original shard count, or moving replicas around, uses SPLITSHARD and ADDREPLICA:

# SPLITSHARD -- splits shard1 into two new sub-shards, each keeping the parent's replica count
curl "http://localhost:8983/solr/admin/collections?action=SPLITSHARD&collection=books&shard=shard1"

# ADDREPLICA -- add one more replica of shard1, letting placement (see below) pick the node
curl "http://localhost:8983/solr/admin/collections?action=ADDREPLICA&collection=books&shard=shard1&type=NRT"

SPLITSHARD is online but expensive (it re-indexes the parent shard’s documents into the two children) and, unlike an Elasticsearch _split, does not require the source to be read-only first; writes keep flowing to the parent during the split and are dual-routed to whichever sub-shard has already taken over that key range. MIGRATE moves documents matching a route key from one collection into another — a much narrower operation, used to rebalance across collections rather than within one:

# MIGRATE -- move every document whose route key is "tenant42!" from "books" into "books-archive"
curl "http://localhost:8983/solr/admin/collections?action=MIGRATE&collection=books\
&target.collection=books-archive&split.key=tenant42!"

BACKUP and RESTORE snapshot a collection (index files plus its configset) to a shared repository location and recreate it later, including onto a differently-shaped cluster:

curl "http://localhost:8983/solr/admin/collections?action=BACKUP&name=books-2025-09-08\
&collection=books&location=/mnt/solr-backups"

curl "http://localhost:8983/solr/admin/collections?action=RESTORE&name=books-2025-09-08\
&collection=books-restored&location=/mnt/solr-backups"

Indexing throughput and update semantics for a running collection are covered in Indexing & updates and Partial updates & concurrency; this page is only about the collection’s own shape.

Collection aliases

An alias is a name that resolves to one or more collections at query time, giving the same indirection Elasticsearch gets from an index alias: reindex into a new collection, then repoint the alias in one atomic call so clients never see a gap.

# CREATEALIAS -- a plain alias over one collection, queried and (by default) written as "books"
curl "http://localhost:8983/solr/admin/collections?action=CREATEALIAS&name=books&collections=books-v2"

# Re-point the same alias to a freshly rebuilt collection; "books" clients see the change immediately
curl "http://localhost:8983/solr/admin/collections?action=CREATEALIAS&name=books&collections=books-v3"

Time Routed Aliases (TRA)

A Time Routed Alias manages a time-sequential series of collections for you: writes carrying a timestamp field are routed to the collection covering that time window, and a new window’s collection is created automatically the moment a document needs one — there is no manual _rollover call to make, unlike the Elasticsearch pattern in Index lifecycle & scaling.

curl "http://localhost:8983/solr/admin/collections?action=CREATEALIAS&name=logs\
&router.name=time&router.field=evt_dt&router.start=NOW/DAY&router.interval=%2B1DAY\
&router.autoDeleteAge=%2FDAY-30DAYS&create-collection.collection.configName=logs-config\
&create-collection.numShards=1"

# Write straight to the alias; the RoutedAliasUpdateProcessor picks (or creates) the right collection
curl "http://localhost:8983/solr/logs/update?commit=true" -H "Content-Type: application/json" \
  -d '[{"id": "e-1", "evt_dt": "2025-09-08T10:00:00Z", "message": "server started"}]'

router.autoDeleteAge (a date-math expression) is what ages out old collections automatically, the TRA equivalent of an ILM delete phase. Most of these settings can be changed later with ALIASPROP instead of recreating the alias.

Category Routed Aliases (CRA) and Dimensional Routed Aliases (DRA)

A Category Routed Alias instead creates one backing collection per distinct value of a field — useful for per-tenant or per-region isolation without a separate CREATE call per tenant:

curl "http://localhost:8983/solr/admin/collections?action=CREATEALIAS&name=events\
&router.name=category&router.field=region\
&create-collection.collection.configName=events-config&create-collection.numShards=1"

A Dimensional Routed Alias combines two routing dimensions (currently time plus category) into one alias, producing collection names like eventsCRAeuTRA2025-09-08. See Aliases for the complete parameter reference, including the constraint that a TRA’s collections must stay a contiguous, gap-free sequence.

Replica-placement plugins

Solr’s autoscaling framework (cluster-wide policies and triggers that used to drive automatic replica placement and rebalancing) has been removed. Placement decisions — where CREATE, ADDREPLICA, SPLITSHARD and MOVEREPLICA put a new replica — are now made exclusively by a replica-placement plugin, a single cluster-wide plugin configured either in solr.xml or, more commonly, dynamically through the /api/cluster/plugin endpoint. Older per-collection placement rules are likewise superseded by this mechanism.

Only one placement plugin is active cluster-wide at a time, registered under the fixed name .placement-plugin. Solr ships several implementations, selectable by class:

  • SimplePlacementFactory (default) — round-robins new replicas toward nodes that currently hold fewer replicas; it does not prevent two replicas of the same shard from landing on one node.

  • RandomPlacementFactory — placement, but guarantees no two replicas of the same shard share a node; adequate only for small, simple deployments.

  • MinimizeCoresPlacementFactory — prefers the node with the fewest cores overall, still respecting the same-shard/same-node constraint.

  • AffinityPlacementFactory — the closest match to the old 8.x autoscaling behavior: spreads replicas across availability zones, can pin specific replica types to specific node classes, and honors withCollection/collectionNodeType co-location constraints plus free-disk-space thresholds (minimalFreeDiskGB, prioritizedFreeDiskGB).

# Install AffinityPlacementFactory as the cluster's one active placement plugin
curl -X POST -H 'Content-Type: application/json' "http://localhost:8983/api/cluster/plugin" -d '{
  "add": {
    "name": ".placement-plugin",
    "class": "org.apache.solr.cluster.placement.plugins.AffinityPlacementFactory",
    "config": {
      "minimalFreeDiskGB": 10,
      "prioritizedFreeDiskGB": 50
    }
  }
}'

# Inspect or remove the active plugin
curl "http://localhost:8983/api/cluster/plugin"
curl -X POST -H 'Content-Type: application/json' "http://localhost:8983/api/cluster/plugin" \
  -d '{"remove": ".placement-plugin"}'

See Replica Placement Plugins for the full configuration schema, including how to author a custom PlacementPluginFactory for placement logic none of the built-ins cover. Cluster-side node health and the node/replica topology these plugins place onto are covered in SolrCloud architecture; day-to-day operational concerns — upgrading nodes, rolling restarts — are in Deployment & upgrades.