Skip to content

Commit 2843df1

Browse files
feat(orchestrator): add concurrent sandbox creation benchmark (#2280)
* feat(orchestrator): add concurrent sandbox creation benchmark The current maxStartingInstancesPerNode limit of 3 was established from non-rigorous historical measurements on n1 machines. To find the optimal limit for n2 machines we need proper data. This adds BenchmarkConcurrentResume which launches N sandboxes simultaneously via barrier-synchronized goroutines and measures per-sandbox creation latency (avg, P50, P95, P99, min, max), wall-clock time, and success/failure counts. Concurrency levels default to 1,2,3,4,5,6,7,8,9,10 and can be overridden via the CONCURRENCY_LEVELS env var. Network and NBD pool sizes are scaled to the max concurrency level to avoid measuring pool starvation instead of actual creation overhead. * feat(orchestrator): use real cgroup manager in concurrent benchmark Replace cgroup.NewNoopManager() with the real cgroup.NewManager() so sandboxes get proper CPU and memory isolation via cgroupv2, matching production behavior. * feat(orchestrator): aggregate latency stats across benchmark iterations Accumulate per-sandbox latencies and wall-clock times across all benchmark iterations instead of reporting only the last iteration. This makes percentiles (P50/P95/P99) statistically meaningful at high iteration counts (e.g. -benchtime=100x at concurrency-5 gives 500 latency samples instead of 5). * feat(orchestrator): add awk script to convert benchmark results to markdown table * fix(orchestrator): fix linter issues in concurrent benchmark - Use max/min builtins instead of if-chains in percentile() - Use WaitGroup.Go instead of manual Add/Done goroutine pattern - Replace sort.Slice/sort.Ints with slices.Sort - Add blank line before bare return (nlreturn) - Rename min/max variables to fastest/slowest to avoid shadowing builtins * chore(orchestrator): rename bench2md.awk to benchmark-to-markdown.awk Use a more descriptive filename for the awk script that converts Go benchmark output to markdown tables. * refactor(orchestrator): move benchmark tests to benchmarks/ folder Keep benchmark files in a dedicated subdirectory to separate them from the main orchestrator source. Update relative paths to account for the extra directory level. * chore: auto-commit generated changes --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 569e8ab commit 2843df1

3 files changed

Lines changed: 582 additions & 3 deletions

File tree

packages/orchestrator/benchmark_test.go renamed to packages/orchestrator/benchmarks/benchmark_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import (
4747
"github.com/e2b-dev/infra/packages/shared/pkg/utils"
4848
)
4949

50-
var tracer = otel.Tracer("github.com/e2b-dev/infra/packages/orchestrator")
50+
var tracer = otel.Tracer("github.com/e2b-dev/infra/packages/orchestrator/benchmarks")
5151

5252
func BenchmarkBaseImageLaunch(b *testing.B) {
5353
if os.Geteuid() != 0 {
@@ -106,8 +106,8 @@ func BenchmarkBaseImageLaunch(b *testing.B) {
106106

107107
// hacks, these should go away
108108
b.Setenv("ARTIFACTS_REGISTRY_PROVIDER", "Local")
109-
b.Setenv("FIRECRACKER_VERSIONS_DIR", abs(filepath.Join("..", "fc-versions", "builds")))
110-
b.Setenv("HOST_ENVD_PATH", abs(filepath.Join("..", "envd", "bin", "envd")))
109+
b.Setenv("FIRECRACKER_VERSIONS_DIR", abs(filepath.Join("..", "..", "fc-versions", "builds")))
110+
b.Setenv("HOST_ENVD_PATH", abs(filepath.Join("..", "..", "envd", "bin", "envd")))
111111
b.Setenv("HOST_KERNELS_DIR", abs(kernelsDir))
112112
b.Setenv("LOCAL_TEMPLATE_STORAGE_BASE_PATH", abs(filepath.Join(persistenceDir, "templates")))
113113
b.Setenv("ORCHESTRATOR_BASE_PATH", tempDir)

0 commit comments

Comments
 (0)