feat: scale mode — throttle CPU/memory instead of stopping containers#908
Merged
Conversation
Instead of stopping a container when a session expires, scale mode throttles its CPU and memory to a configurable idle profile. When a new session is requested the resources are restored to the active profile immediately — no container restart, no cold-start latency. Four new instance labels control the behaviour: sablier.idle.cpu – CPU limit applied on session expiry sablier.idle.memory – memory limit applied on session expiry sablier.active.cpu – CPU limit restored on new session sablier.active.memory – memory limit restored on new session Provider support ---------------- * Docker / Podman – docker update (NanoCPUs + Memory/MemorySwap) * Docker Swarm – service update resource limits (NanoCPUs + MemoryBytes) * Kubernetes – strategic-merge-patch on Deployment / StatefulSet container resource limits (resource.Quantity) * Proxmox LXC – not supported (tag-based config, no key-value labels) Implementation notes -------------------- * ScaleConfig / ResourceProfile types added to pkg/sablier/instance.go; ScaleConfigFromLabels() reads labels in both InstanceStop and InstanceStart. * Docker: MemorySwap is always set equal to Memory in the same update call to satisfy Docker's memswap >= memory constraint. * No changes to Sablier core session/request logic; providers handle scale internally. Tests ----- * Unit tests for CPU/memory parsers (Docker, Swarm) * Unit tests for Kubernetes strategic-merge-patch builder * Unit tests for ScaleConfigFromLabels and PopulateEnabledAndGroup * Integration tests (dind) for Docker scale stop/start Docs & example -------------- * docs/configuration.md – new Scale Mode section with per-provider examples * examples/scale-mode/ – Docker Compose example with whoami + Sablier
|
Test Results✅ All tests passed! | 377 tests in 80.557s |
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


What is scale mode?
Scale mode is a new alternative to the default stop/start lifecycle. Instead of shutting down a container when a session expires, Sablier throttles its CPU and memory to a configurable idle profile. When a new session arrives the resources are restored immediately — no container restart, no cold-start latency.
It is related a bit related to #882 but it does not really implement the feature
How to enable it
Add the four new instance labels to your container/service/workload:
sablier.idle.cpusablier.idle.memorysablier.active.cpusablier.active.memoryYou can set any subset of the four labels. A missing label means "no limit".
Docker / Podman (Compose example)
CPU values are decimal fractions of one core (
0.5= half a core). Memory values use Docker-style suffixes (b,k,m,g).Docker Swarm
Kubernetes (Deployment)
Kubernetes uses standard quantity notation (
100m= 0.1 core,64Mi= 64 mebibytes). Resource limit changes trigger a rolling restart — the service stays available during the transition.Try the example
What changed
Core
pkg/sablier/instance.go— newScaleConfig/ResourceProfiletypes;ScaleConfigFromLabels()helper;PopulateEnabledAndGroupnow populatesScaleConfigProviders
container_scale.go(new);container_stop.go/container_start.gocheck for scale labels before stopping/startingservice_scale.go(new);service_stop.go/service_start.goupdatedresource_scale.go(new, strategic-merge-patch approach);instance_stop.go/instance_start.goupdatedTests
ScaleConfigFromLabelsandPopulateEnabledAndGroupDocs
docs/configuration.md— new Scale Mode section with per-provider examplesexamples/scale-mode/— runnable Docker Compose example