Skip to content

Command–query separation

A design principle requiring each method either to change state as a command or return information as a side-effect-free query, but not both.

Version
v2 · 2026-09-06 · History
Domain-specific #
1507
Origin domain
computer science
Subdomain
imperative and object-oriented software design
Aliases
CQS, Command–query separation principle

Core Idea

Command–query separation is a design principle requiring each method either to change state as a command or return information as a side-effect-free query, but not both.

Command–query separation classifies operations by their contract: a command changes observable state and returns no informational result, while a query returns information and does not change observable state. Separating mutation from observation makes assertions, reasoning, testing, retries, and interface use more predictable, though controlled exceptions may be justified and documented.

Its operative boundary is not supplied by the name alone. Preserve this identity: A design principle requiring each method either to change state as a command or return information as a side-effect-free query, but not both.

Scope of Application

The abstraction recurs literally within imperative methods, object interfaces, APIs, design by contract, and systems where mutation effects must remain legible. The following habitats preserve the same recognition machinery; they are not invitations to extend the name metaphorically.

  • Class interfaces. mutators are separated from observational methods.
  • Design by contract. assertions can invoke queries without changing the state they inspect.
  • API design. clients know whether a call is safe to repeat or reorder.
  • Testing. queries observe postconditions without introducing new effects.
  • Concurrent design. exceptions are evaluated against atomicity and race requirements.

Clarity

The relevant property is observable effect, not return syntax alone. A query that advances a cursor, consumes a stream, changes global state, or performs visible I/O violates strict CQS even if it appears to 'read.' A command may return minimal completion status under a relaxed convention, but that deviation should be named.

Manages Complexity

CQS reduces hidden temporal coupling by making effectful calls visually and contractually distinct. It improves local reasoning at the price of more operations and occasional awkwardness when observation and mutation must be atomic.

The compression remains accountable because each simplification has a named failure condition. Disagreement can be localized to a missing role, an invalid assumption, an ambiguous measurement, or a neighboring abstraction instead of being hidden inside an unanalyzed label.

Abstract Reasoning

R1. Define the observable state from the caller's perspective. R2. Classify each operation by its contractual effect and result. R3. Move observation out of commands where atomicity does not require combination. R4. Test queries for hidden mutation, I/O, cursor movement, and shared-cache effects. R5. Document exceptions with the concurrency or performance reason that justifies them.

Knowledge Transfer

CQS transfers literally across programming languages and APIs that expose operations over state. State transition and separation of concerns are broader parents; a political distinction between asking and ordering is only metaphor.

The transfer boundary is explicit: DOMAIN-SPECIFIC PASS / PRIME FAIL: The principle recurs across methods, classes, APIs, design-by-contract systems, and imperative codebases. Literal recognition retains the specialist vocabulary and validity conditions of imperative software design; outside that setting only broader parent operations transfer.

Relationships to Other Abstractions

Local relationship map for Command–query separationParents appear above the current abstraction, mutual partners to the right, and children below. Node labels state whether each abstraction is prime or domain-specific; colors identify relation types.Command–queryseparationDOMAINPrime abstraction: State and State Transition — presupposesState and StateTransitionPRIMEPrime abstraction: Modularity — is a kind ofModularityPRIME

Current abstraction Command–query separation Domain-specific

Parents (2) — more general patterns this builds on

  • Command–query separation is a kind of Modularity Prime

    Modularity (prime:modularity).

  • Command–query separation presupposes State and State Transition Prime

    State and State Transition (prime:state_and_state_transition).

Hierarchy paths (2) — routes to 2 parentless roots

Neighborhood in Abstraction Space

Command–query separation sits in a sparse region of the domain-specific corpus (73rd percentile for distinctiveness): few abstractions share its structure, so a faithful description tends to retrieve it precisely.

Family — Unclustered & Miscellaneous (1565 abstractions)

Nearest neighbors

Computed from structural-signature embeddings · 2026-09-08