Modern applications often struggle with organizing complex database queries and business logic. Two patterns that attempt to solve this problem are Atomic Query Construction (AQC) and Command Query Responsibility Segregation (CQRS).
At first glance they may look similar because both introduce structured ways to separate logic. But they solve very different problems.
This article explains how they differ, when to use them, and why confusing them can lead to unnecessary complexity.
What is AQC (Atomic Query Construction)?
Atomic Query Construction (AQC) is a pattern focused on building database queries in a modular, reusable, and composable way.
Instead of placing query logic inside controllers, services, or repositories, AQC introduces small atomic query classes that each handle a specific filtering, joining, or transformation task.
These query units are then composed to construct complex queries.
The main goal of AQC is:
- Maintainability
- Query reuse
- Readable data access logic
- Separation of query responsibilities
Example
Instead of writing a large query like this inside a controller:
User::query()
->where('active', true)
->where('verified', true)
->where('country', $country)
->with('orders')
->orderBy('created_at', 'desc')
->get();
AQC conditionally composes it based on parameters provided:
class GetUsers
{
public function handle(array $params = [])
{
$query = User::query();
// apply filters conditionally
if (!empty($params['active'])) {
$query->where('active', $params['active']);
}
if (!empty($params['verified'])) {
$query->where('verified', $params['verified']);
}
if (!empty($params['country'])) {
$query->where('country', $params['country']);
}
// Apply sorting when requested otherwise do it on id by default
if(isset($params['sortBy']) && isset($params['type'])){
$sortBy = $params['sortBy'];
$type = $params['type'];
$query->orderBy($sortBy, $type);
}
return isset($params['paginate'])
? $query->paginate(User::PAGINATE)
: $query->get();
}
}
The idea is simple: each query class performs one atomic task. In the above case fetch users with any combination possible passed via parameters.
What is CQRS (Command Query Responsibility Segregation)?
CQRS is a much larger architectural pattern that separates read operations and write operations into different models.
It was popularized by Greg Young.
CQRS splits application behavior into two sides:
Command Side (Write)
Handles state changes.
Examples:
- Create order
- Register user
- Update product
- Cancel subscription
Commands usually represent business actions.
Example:
RegisterUserCommand
CreateOrderCommand
CancelSubscriptionCommand
Query Side (Read)
Handles data retrieval optimized for reading.
Examples:
GetUserProfileQuery
GetDashboardStatsQuery
GetOrdersByCustomerQuery
These queries often use read models that are optimized for fast data retrieval.
The Core Difference
The biggest misunderstanding is thinking AQC is a variant of CQRS but it is not.
| Aspect | AQC | CQRS |
|---|---|---|
| Scope | Query organization pattern | System architecture pattern |
| Main Purpose | Modular query construction | Separate read and write models |
| Focus | Database query structure | Application architecture |
| Complexity | Low to medium | Medium to very high |
| Used For | Cleaner data access layer | Large scalable systems |
When to Use AQC
AQC works well when:
- Queries are becoming large and hard to maintain
- Multiple endpoints reuse the same query filters
- You want cleaner query logic
- You are working with frameworks like Laravel or Django
Typical use cases:
- Admin dashboards
- Analytics queries
- Reporting systems
- API filtering systems
AQC is lightweight and easy to introduce.
When to Use CQRS
CQRS makes sense when:
- The system has very different read and write workloads
- Reads require highly optimized projections
- Writes involve complex domain logic
- The system needs high scalability
Common examples:
- Banking systems
- E-commerce platforms
- Event-driven systems
- Systems using Event Sourcing
CQRS can significantly increase complexity and should not be used for small projects.
Advantages of AQC
- Query logic becomes modular
- Reusable query components
- Easier testing
- Cleaner controllers and services
- Easier collaboration in large teams
Advantages of CQRS
- Highly scalable architecture
- Independent read and write models
- Better performance optimization
- Clear separation of responsibilities
- Works well with event-driven systems
Drawbacks of AQC
- May feel unnecessary in small applications
- Requires team discipline
Drawbacks of CQRS
- Much higher complexity
- Requires careful design
- Debugging becomes harder
- Infrastructure overhead increases
Final Thoughts
AQC and CQRS serve completely different purposes.
- AQC improves how queries are written
- CQRS changes how the entire application is structured
AQC is a practical pattern that can improve code organization with minimal overhead.
CQRS is a powerful architectural approach that should only be used when the system genuinely requires it.
Understanding the difference helps teams avoid unnecessary complexity while still benefiting from better code structure.