AI Inference Tidal Algorithm
Feature Introduction
Tidal is a scheduled scaling algorithm designed for workloads with clear tidal characteristics. Users can configure Tidal CRD to scale target workloads (such as Deployment, StatefulSet, ResourceScalingGroup, etc.) to a specified number of replicas at designated times. The current version mainly considers the time dimension factor, suitable for scenarios where business load patterns are clear and capacity can be planned in advance through time-based configuration. Tidal Controller is only responsible for calculating the desired replicas and writing them to the status field—the actual scaling is executed by the general decision framework ElasticScaler. The Tidal resource is bound to an ElasticScaler resource through metadata.labels (elasticscaler.io/name, elasticscaler.io/namespace) in the CRD, and the scaling decisions are uniformly consumed by ElasticScaler.
NOTE:
openFuyao defines a custom resource named ResourceScalingGroup (abbreviated as RSG) in Kubernetes. For detailed introduction and usage of this resource, please refer to the documentation: ResourceScalingGroup-Resource Group Scaling. RSG or ResourceScalingGroup mentioned in this document refers to this custom resource object.
Application Scenarios
- Scenarios with clear business time patterns such as morning/evening peaks and event days, requiring proactive scaling before peaks and scaling down during low-traffic periods.
- Multi-stage resource strategies for workdays/weekends, holidays, warm-up/peak/wrap-up periods, requiring different replica counts at different time points.
- Clusters with existing ElasticScaler, seeking to add time-based scaling capabilities to coordinate with existing metric-based policies.
Capability Scope
- Provides time-driven scaling decisions based on standard CRD (Tidal), independent of historical metric predictions, suitable for scenarios with clear business time patterns (such as morning/evening peaks, event days, etc.).
- Supports scalable resources such as Deployment, StatefulSet, ResourceScalingGroup as targets, working with the ElasticScaler framework for unified elastic management.
- Supports combining multiple time rules to construct multi-stage resource strategies for workdays/weekends, holidays, warm-up/peak/wrap-up periods, etc.
- Supports 6-field CRON expressions with second-level precision and mandatory timezone configuration to ensure consistent behavior across environments.
- Supports conflict resolution strategies (taking the maximum replica count) when multiple rules trigger simultaneously at the same time point, ensuring business capacity safety even under complex rules.
- Provides observable scaling intentions through Status fields (such as
desiredReplicas,activeRule,lastTriggerTime,nextTriggerTime) for troubleshooting and auditing.
Highlight Features
- Focuses on "time dimension" tidal scheduling: Compared to traditional autoscaling based on real-time metrics, it is more suitable for scenarios with clear business calendars (workdays/weekends/event periods), enabling proactive scaling before peaks and timely scaling down during low-traffic periods.
- Deep integration with ElasticScaler: Through the two standard labels
elasticscaler.io/nameandelasticscaler.io/namespace, Tidal resources are decoupled from ElasticScaler resources for binding. ElasticScaler is responsible for orchestrating time-based policies with other metric-based policies. - Strongly constrained timezone + 6-field CRON syntax: Built-in validation rules to avoid time deviation issues caused by missing timezones or 5-field CRON expressions.
Implementation Principle
This section explains the implementation principle of the tidal algorithm from both logical and runtime perspectives.
Logical View
The logical view shows the core components and their interaction relationships of the time-based tidal business scenario scheduling decision algorithm. The system adopts a layered architecture design, including the user layer, Kubernetes API layer, tidal algorithm layer (Tidal Controller and Timer Scheduler), and decision framework integration layer. Each layer interacts through standard Kubernetes API mechanisms (Watch, Reconcile). The Controller is responsible for watching CR changes and coordinating timing rules, the Timer Scheduler is responsible for parsing CRON expressions and triggering timed events, and finally integrates with the decision framework through label mechanisms to achieve automatic scaling of target Deployments.
Figure 1 Tidal Algorithm Logical View
Runtime View
The runtime view shows the complete runtime flow from user configuration to final scaling execution through a sequence diagram, which can be divided into four stages.
- Users configure Tidal CR through YAML and submit it to APIServer.
- Controller perceives CR changes through the Watch mechanism, triggers Reconcile processing, and synchronizes time rules to the internal TimerScheduler.
- TimerScheduler sets timers based on CRON expressions and notifies the Controller when trigger time arrives.
- Controller updates Tidal's Status and desired replica count. Decision frameworks like ElasticScaler watch status changes and execute actual Pod scaling operations.
Figure 2 Tidal Algorithm Runtime Sequence Diagram
Relationship with Related Features
ElasticScaler: Tidal resources depend on ElasticScaler to complete actual scaling. Tidal resources are only responsible for calculating desired replicas based on time policies and writing them to status, without directly modifying target resources. After binding to a specified ElasticScaler resource through elasticscaler.io/name and elasticscaler.io/namespace in metadata.labels, ElasticScaler watches Tidal resource's status.desiredReplicas and other statuses through the Watch mechanism, and executes actual scaling on the target resource pointed to by spec.targetRef. ElasticScaler must be deployed and configured before using Tidal.
Installation
Prerequisites
- An available Kubernetes cluster with
kubectlandhelminstalled. - Network environment configured to access
cr.openfuyao.cn.
Installation
Create the namespace scaling-system (if it doesn't exist):
kubectl create namespace scaling-systemTwo deployment methods are supported: deploying through the pd-orchestrator unified chart (with optional sub-components), or deploying the Tidal component separately from the source code repository.
Method 1: Deploy via pd-orchestrator chart
Install the pd-orchestrator chart from the OCI repository, which by default installs three Controllers: elastic-scaler, resourcescalinggroup, and tidal. Since Tidal depends on ElasticScaler to complete actual scaling, it is recommended to deploy Tidal with ElasticScaler together; ResourceScalingGroup (RSG) can be deployed optionally as needed.
For full capabilities (Tidal+ElasticScaler), use the default installation.
helm install orchestrator oci://cr.openfuyao.cn/charts/pd-orchestrator --version 0.0.0-latestIf you only need to deploy Tidal Controller, you can enable sub-components on demand through --set switches, for example, to enable only Tidal Controller.
helm install orchestrator oci://cr.openfuyao.cn/charts/pd-orchestrator --version 0.0.0-latest \
--set elastic-scaler.enabled=true \
--set resourcescalinggroup.enabled=false \
--set tidal.enabled=trueNOTE:
ElasticScaler typically points to only one scaling target. When using tidal, the Tidal resource will be associated with a certain ElasticScaler through labels, and that ElasticScaler will scale the same target. If a default ElasticScaler example CR is also created during installation (for HPA to scale RSG groups), it will conflict or duplicate with the ElasticScaler used by tidal. It is recommended that one scaling target corresponds to only one ElasticScaler resource. Users should create the ElasticScaler CR themselves and bind it to the Tidal resource's labels, so the default ElasticScaler CR during installation should be disabled. Whenresourcescalinggroup.enabled=false, RSG is not deployed andresourcescalinggroup.instanceConfig.enablednaturally doesn't take effect. However, whenelastic-scaler.enabled=true, you still need to separately setelastic-scaler.elasticScaler.enabled=falseto avoid creating the default ElasticScaler example CR. Example:
helm install orchestrator oci://cr.openfuyao.cn/charts/pd-orchestrator --version 0.0.0-latest \
--set elastic-scaler.enabled=true \
--set resourcescalinggroup.enabled=false \
--set tidal.enabled=true \
--set elastic-scaler.elasticScaler.enabled=falseMethod 2: Deploy individual component (from source)
After cloning the code from the ElasticScaler repository, navigate to the charts/elastic-scaler/charts/tidal path and execute helm install in that directory to deploy only the Tidal Controller.
git clone https://gitcode.com/openFuyao/elastic-scaler.git
cd elastic-scaler/charts/elastic-scaler/charts/tidal
helm install tidal . -n <namespace>This method only installs the Tidal component. For actual scaling capabilities, ElasticScaler needs to be deployed separately and ensure that the Tidal CR's labels are correctly bound to the ElasticScaler resource.
Key Parameter Description
Table 1 Helm Key Parameters
| Parameter Key | Description |
|---|---|
orchestrator | Helm Release name, can be modified as needed. |
--version 0.0.0-latest | Install the latest version of orchestrator (which includes the three Controllers mentioned above). |
--set elastic-scaler.enabled / --set resourcescalinggroup.enabled / --set tidal.enabled | Set to true or false as needed to control whether to deploy the corresponding Controller; all are enabled by default if not specified. |
--set resourcescalinggroup.instanceConfig.enabled | Controls whether to install the ResourceScalingGroup default example CR. If mainly using Tidal/ElasticScaler for tidal scaling, it is recommended to keep the default value when --set resourcescalinggroup.enabled=false (at this time RSG is not deployed, instanceConfig no longer takes effect). |
--set elastic-scaler.elasticScaler.enabled | Controls whether to install the ElasticScaler default example CR. Since ElasticScaler typically points to only one scaling resource, if using Tidal to bind a custom ElasticScaler for tidal scaling, it is recommended to explicitly set this value to false to avoid conflicts between the default ElasticScaler example CR and the ElasticScaler in tidal scenarios. |
Verify Deployment
After completing the installation, you can verify whether the Tidal Controller is running normally through the following steps.
Check Pod status (using namespace
scaling-systemas an example).bashkubectl get pods -n scaling-system | grep tidalExpect to see Pods with
tidalin the name andSTATUSasRunning.Check Controller logs to confirm there are no persistent errors (replace
<pod-name>or<deployment-name>according to the actual deployment name).bash# View Pod logs kubectl logs -n scaling-system <pod-name> # Or view Pod list through Deployment and then view logs kubectl get deploy -n scaling-system kubectl logs -n scaling-system deploy/<deployment-name>
If the Pod is in a non-Running state or there are numerous errors in the logs, you can prioritize checking:
- Whether the namespace is correct during Helm installation.
- Whether cluster access to
cr.openfuyao.cnis normal (whether the image is pulled successfully). - Whether there are conflicts with existing ElasticScaler/ResourceScalingGroup deployments in the cluster.
Using AI Inference Tidal Algorithm
Prerequisites
- The installation steps described earlier in this guide have been completed, and Tidal Controller and ElasticScaler are running normally.
- During installation, the default ElasticScaler/ResourceScalingGroup example CRs that conflict with tidal scenarios have been disabled according to the recommendations in Key Parameter Description.
- At least one target workload (such as Deployment, StatefulSet, etc.) to be scaled exists in the cluster.
Background Information
Tidal describes time-based policy rules through CR. ElasticScaler watches fields such as
status.desiredReplicasof Tidal resources through the Watch mechanism and executes actual scaling on the target resource pointed to byspec.targetRef.This capability is suitable for scenarios where business loads have clear time patterns (such as morning/evening peaks, event days, etc.). The current version only considers the time dimension without comprehensive real-time metric decision-making.
Time rules are configured through "timezone prefix + 6-field CRON expression" in the format:
textCRON_TZ=<timezone> second minute hour day month weekdayExample (trigger at 8:00 on workdays):
textCRON_TZ=Asia/Shanghai 0 0 8 * * 1-5 └──────────timezone────┘ │ │ │ │ │ └─ weekday (1-5 represents Monday to Friday) │ │ │ │ └── month │ │ │ └──── day │ │ └────── hour │ └──────── minute └────────── second
Usage Restrictions
- Currently only supports fixed replica count setting based on time policies, does not support dynamic curve adjustments within time periods.
- A single ElasticScaler resource typically points to only one scaling target; the same target should not be controlled by multiple ElasticScaler/Tidal/HPA policies simultaneously to avoid policy conflicts.
- CRON expression must be in timezone prefix + 6-field format and must include the second field; incorrect expressions will cause time policies to not take effect.
- Tidal Controller is only responsible for calculating desired replicas and writing to Status, it does not directly modify target resources; if ElasticScaler is not correctly deployed or bound, time policies will not actually take effect.
Operation Steps
Write Tidal CR.
Below is a Tidal example more aligned with actual production scenarios, used to set different replica counts at different time periods.
- Scale to 10 replicas before morning peak on workdays (8:00).
- Scale to 20 replicas during evening peak on workdays (20:00).
- Scale down to 2 replicas at 1:00 AM daily to save resources.
yamlapiVersion: tidal.io/v1alpha1 kind: Tidal metadata: name: ecommerce-traffic-tidal namespace: scaling-system labels: elasticscaler.io/name: ecommerce-traffic-elasticscaler elasticscaler.io/namespace: scaling-system spec: targetRef: apiVersion: apps/v1 kind: Deployment name: ecommerce-frontend namespace: production triggers: times: rules: - name: workday-morning-base cron: "CRON_TZ=Asia/Shanghai 0 0 8 * * 1-5" replicas: 10 description: "Scale to 10 replicas before workday morning peak to ensure daytime traffic" - name: workday-evening-peak cron: "CRON_TZ=Asia/Shanghai 0 0 20 * * 1-5" replicas: 20 description: "Scale to 20 replicas during workday evening peak to handle evening traffic surge" - name: nightly-offpeak cron: "CRON_TZ=Asia/Shanghai 0 0 1 * * *" replicas: 2 description: "Scale down to 2 replicas at 1 AM daily to save resources"Table 2 Tidal CR Field Description
Field Path Required Description metadata.nameYes Tidal resource name, unique within the namespace. metadata.namespaceYes Tidal namespace. It is recommended to be consistent with the ElasticScaler namespace or planned according to operational specifications. metadata.labels.elasticscaler.io/nameYes Name of the bound ElasticScaler resource. ElasticScaler will watch the status of this Tidal resource. metadata.labels.elasticscaler.io/namespaceYes Namespace of the bound ElasticScaler resource. spec.targetRef.apiVersionYes APIVersion of the target workload. spec.targetRef.kindYes Type of target workload, such as Deployment, StatefulSet, ResourceScalingGroup, etc. spec.targetRef.nameYes Name of the target workload. spec.targetRef.namespaceYes Namespace of the target workload. spec.triggers.times.rules[].nameYes Time rule name, should be unique within the same Tidal resource, used for troubleshooting and identifying current rule in status. spec.triggers.times.rules[].cronYes 6-field CRON expression with timezone prefix, controlling when the rule triggers. spec.triggers.times.rules[].replicasYes Desired target replica count when the rule triggers. spec.triggers.times.rules[].descriptionNo Rule description to help the team understand the business meaning of the rule. Create resource.
bashkubectl apply -f ecommerce-traffic-tidal.yamlView and verify Tidal resource status.
bashkubectl get tidal ecommerce-traffic-tidal -n scaling-system -o yamlNOTE:
status.desiredReplicas: Current desired replica count calculated by the time policy.status.activeRule: Name of the currently active time rule.status.lastTriggerTime: Time point of the most recent time rule trigger.status.nextTriggerTime: Expected next trigger time point.
When a time rule trigger point is reached,desiredReplicasandactiveRulewill be updated. After ElasticScaler watches the status change, it will execute actual scaling on the Deployment/StatefulSet or other resources pointed to byspec.targetRef.Adjust rules according to business needs.
- You can update the CRON expressions and replica counts in
rulesby editing the CR (kubectl edit tidal ...) or re-apply. - It is recommended to conduct small-scale drills during low-risk periods first, and confirm that the scaling time points match expectations before applying to production traffic.
- You can update the CRON expressions and replica counts in
Follow-up Operations
Regularly review and adjust time rules in Tidal resources according to business changes to avoid long-term retention of historical event rules.
When a time policy is no longer needed, you can delete the corresponding Tidal CR:
bashkubectl delete tidal ecommerce-traffic-tidal -n scaling-system
Related Operations
Execute the following command to view all Tidal instances:
bashkubectl get tidal -AExecute the following command to view single instance details:
bashkubectl describe tidal ecommerce-traffic-tidal -n scaling-system

