Execution cost#
CEL runtimes can estimate the computational cost of expressions. Cost analysis helps prevent denial-of-service through expensive expressions.
Why cost matters#
Some CEL applications allow users to submit expressions. Without limits, a poorly-written or even malicious expression could:
- Consume excessive CPU time
- Allocate large amounts of memory
- Cause timeouts or service degradation
Static vs dynamic cost#
CEL provides utilities for estimating and tracking the cost of the expressions it evaluates. Cost is divided into two categories:
- Static cost is estimated at compile time based on the expression structure. It provides an upper bound but overestimates for macros and conditional branches without size estimates for input variables.
- Dynamic cost is tracked during evaluation. It reflects the actual operations performed. Dynamic cost is useful for runtime limits because it measures real work done.
Static cost model#
CEL assigns costs to operations for static analysis. The following values are from cel-go; other runtimes may differ.
| Operation | Cost |
|---|---|
| Scalar literals | 0 |
| List literals | 10 + cost of each element |
| Map literals | 30 + cost of each key and value |
| Message literals | 40 + cost of each field value |
| Variable access | 1 |
| Operators | 1 |
| Function calls | 1 + cost of each argument (default) |
| String functions | string length x 0.1 |
| Regex functions | string length x pattern length x 0.25 |
| Macros | collection size x predicate cost(s) |
| Conditional | condition + max(true branch, false branch) |
The total cost is estimated by summing operation costs.
Setting limits#
Set dynamic cost limits to terminate expensive expressions:
Exceeding the limit short-circuits execution and produces a runtime error.
Custom function costs#
When defining custom functions and macros, assign appropriate costs. Expensive operations (network calls, cryptography) should have high costs.
Runtime specifics#
Cost analysis implementation varies by runtime:
- cel-go: Use
cel.CostTracking()andcel.CostLimit() - cel-java: Use
CelRuntime.CostTracker - cel-cpp: Use
CostTracker
See also#
- Custom functions - Assigning costs to functions
- Common errors - Common errors and how to avoid them