Decision Framework
Both CRDs and the Aggregation Layer extend the Kubernetes API, but they solve different problems. Choosing the wrong one creates architectural debt that is painful to undo.
| Dimension | CRD | Aggregation Layer |
|---|---|---|
| Storage | Etcd (always) | Anywhere (memory, external DB, S3, computed) |
| Implementation effort | Low — just YAML | High — must write and operate a server |
| Data volatility | Low-frequency config | High-frequency or real-time data |
| Custom request logic | None | Full control (streaming, custom verbs, etc.) |
| Validation | CEL expressions, webhooks | Custom code |
| Failure impact | CRD still exists if controller crashes | API group unavailable if server crashes |
| Best for | Desired-state configuration | Dynamic data, external data, custom semantics |
Use a CRD when:
- You are storing desired state (e.g., "I want a database with these settings").
- Data changes infrequently (seconds to minutes between updates).
- You want a controller to reconcile the world toward that state.
- You don't need custom request handling logic.
Use the Aggregation Layer when:
- Data is computed on the fly or changes faster than Etcd can handle.
- Data lives outside the cluster (external APIs, S3, time-series databases).
- You need custom subresources, streaming responses, or non-standard verbs.
- You are building platform infrastructure (metrics, logs, admission systems).
The hybrid pattern: Many production systems use both. A CRD stores the configuration ("scrape these endpoints at this interval"), and an Aggregated API serves the results ("here are the current metric values"). The CRD is the input; the Aggregated API is the output.