Skip to content

fix(wfctl): fix Spaces bucket bootstrap to use correct DO API endpoint#424

Merged
intel352 merged 1 commit into
mainfrom
fix/spaces-bootstrap-s3-api
Apr 20, 2026
Merged

fix(wfctl): fix Spaces bucket bootstrap to use correct DO API endpoint#424
intel352 merged 1 commit into
mainfrom
fix/spaces-bootstrap-s3-api

Conversation

@intel352

Copy link
Copy Markdown
Contributor

Summary

  • Fixes bootstrapDOSpacesBucket to use the correct DO Spaces Buckets REST API
  • Check: GET /v2/spaces/buckets/{bucket} (was /v2/spaces/{bucket} — doesn't exist → 404)
  • Create: POST /v2/spaces/buckets (was /v2/spaces — doesn't exist → 404)
  • Response body is now included in error messages for 4xx/5xx create failures

Root Cause

The previous endpoints /v2/spaces and /v2/spaces/{bucket} don't exist in the DO REST API. The check always returned 404 (interpreted as "bucket doesn't exist"), and the create always returned 404 (reported as an error). The correct path is /v2/spaces/buckets (plural).

Design Notes

  • Auth remains Authorization: Bearer {DIGITALOCEAN_TOKEN} — no Spaces keys required for bucket management via the REST API
  • Extracted bootstrapDOSpacesBucketAt(ctx, bucket, region, apiBase) for test injection; bootstrapDOSpacesBucket delegates to it with the production API base URL

Tests

Four httptest.NewServer-based tests in infra_bootstrap_bucket_test.go:

  • TestBootstrapDOSpacesBucket_AlreadyExists — GET 200 → skip
  • TestBootstrapDOSpacesBucket_CreatesNew — GET 404 + POST 201 → create
  • TestBootstrapDOSpacesBucket_CreateErrorIncludesBody — POST 422 → error with response body
  • TestBootstrapDOSpacesBucket_MissingToken — clear error when token unset

All pass: GOWORK=off go test ./cmd/wfctl/... -run Bootstrap

🤖 Generated with Claude Code

The previous code hit /v2/spaces/{bucket} (check) and /v2/spaces (create),
which don't exist — causing HTTP 404 on every fresh-environment bootstrap.

Changes:
- Check:  GET /v2/spaces/buckets/{bucket}  (200 → exists, 404 → missing)
- Create: POST /v2/spaces/buckets  (201 → created)
- Include server response body in error messages for 4xx/5xx create failures
- Extract bootstrapDOSpacesBucketAt(ctx, bucket, region, apiBase) for testing

Tests: 4 httptest-based cases cover exist-skip, create-new, 4xx-with-body,
and missing-token. GOWORK=off go test ./cmd/wfctl/... -run Bootstrap passes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 20, 2026 19:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes wfctl infra bootstrap’s DigitalOcean Spaces bucket bootstrap logic to use the correct REST API endpoints, and adds tests to validate the expected “exists vs create” behavior and error reporting.

Changes:

  • Update DO Spaces bucket check/create URLs to /v2/spaces/buckets/{bucket} and /v2/spaces/buckets.
  • Extract bootstrapDOSpacesBucketAt(..., apiBase) to enable endpoint injection for tests.
  • Add httptest-based unit tests and include response body in create error messages.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
cmd/wfctl/infra_bootstrap.go Switches to correct DO Spaces bucket endpoints; factors testable helper; includes response body on create failure.
cmd/wfctl/infra_bootstrap_bucket_test.go Adds tests covering “already exists”, “create new”, “create error includes body”, and “missing token”.

Comment on lines 122 to +127
if resp.StatusCode == http.StatusOK {
fmt.Printf(" state backend: bucket %q already exists — skipped\n", bucket)
return nil
}

// Create bucket.
// Create bucket via POST /v2/spaces/buckets.

Copilot AI Apr 20, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existence check treats any non-200 response as “bucket missing” and proceeds to create. This will attempt creation even on auth failures (401/403), rate limits (429), or transient server errors (5xx), obscuring the real cause. Consider only creating on 404, and returning a clear error (optionally including response body) for other status codes from the GET check endpoint.

Copilot uses AI. Check for mistakes.
Comment on lines 141 to +143
if createResp.StatusCode != http.StatusCreated && createResp.StatusCode != http.StatusOK {
return fmt.Errorf("create bucket %q: HTTP %d", bucket, createResp.StatusCode)
respBody, _ := io.ReadAll(createResp.Body)
return fmt.Errorf("create bucket %q: HTTP %d: %s", bucket, createResp.StatusCode, respBody)

Copilot AI Apr 20, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On create failures, io.ReadAll(createResp.Body) reads the full response body without bounds and ignores the read error. A large/streaming error response could cause excessive memory usage or hang. Consider reading with a size limit (e.g., io.LimitReader) and handling the read error so the returned message is reliable.

Copilot uses AI. Check for mistakes.
Comment on lines +28 to +48
var postCalled bool
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
w.WriteHeader(http.StatusNotFound)
case http.MethodPost:
postCalled = true
w.WriteHeader(http.StatusCreated)
default:
http.Error(w, "unexpected: "+r.Method, http.StatusInternalServerError)
}
}))
defer srv.Close()

t.Setenv("DIGITALOCEAN_TOKEN", "test-token")
if err := bootstrapDOSpacesBucketAt(context.Background(), "my-bucket", "nyc3", srv.URL); err != nil {
t.Fatalf("expected no error creating new bucket, got: %v", err)
}
if !postCalled {
t.Error("expected POST to be called when bucket does not exist")
}

Copilot AI Apr 20, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test has a data race: postCalled is written by the httptest server handler goroutine and read by the test goroutine. Under go test -race this will fail. Use an atomic, a channel, or synchronize via a mutex/WaitGroup (or assert the POST was called by validating handler behavior and failing the test if it wasn’t).

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +18
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
w.WriteHeader(http.StatusOK)
return
}
http.Error(w, "unexpected method", http.StatusInternalServerError)
}))

Copilot AI Apr 20, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These httptest handlers only branch on HTTP method and don’t assert the request path (e.g., /v2/spaces/buckets/{bucket}) or POST body (name/region). As a result, the tests could pass even if the production code regresses to the wrong endpoint again. Consider validating r.URL.Path (and decoding the JSON body for POST) so the tests actually cover the intended API contract.

Copilot uses AI. Check for mistakes.
@github-actions

Copy link
Copy Markdown

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:245: parsing iteration count: invalid syntax
baseline-bench.txt:366690: parsing iteration count: invalid syntax
baseline-bench.txt:658720: parsing iteration count: invalid syntax
baseline-bench.txt:1011362: parsing iteration count: invalid syntax
baseline-bench.txt:1319808: parsing iteration count: invalid syntax
baseline-bench.txt:1666798: parsing iteration count: invalid syntax
benchmark-results.txt:245: parsing iteration count: invalid syntax
benchmark-results.txt:286851: parsing iteration count: invalid syntax
benchmark-results.txt:621601: parsing iteration count: invalid syntax
benchmark-results.txt:959246: parsing iteration count: invalid syntax
benchmark-results.txt:1290834: parsing iteration count: invalid syntax
benchmark-results.txt:1604320: parsing iteration count: invalid syntax
goos: linux
goarch: amd64
pkg: github.com/GoCodeAlone/workflow/dynamic
cpu: AMD EPYC 9V74 80-Core Processor                
                            │ benchmark-results.txt │
                            │        sec/op         │
InterpreterCreation-4                 3.288m ± 191%
ComponentLoad-4                       3.485m ±   0%
ComponentExecute-4                    1.811µ ±   2%
PoolContention/workers-1-4            1.020µ ±   2%
PoolContention/workers-2-4            1.015µ ±   1%
PoolContention/workers-4-4            1.027µ ±   8%
PoolContention/workers-8-4            1.017µ ±   1%
PoolContention/workers-16-4           1.022µ ±   1%
ComponentLifecycle-4                  3.518m ±   1%
SourceValidation-4                    2.085µ ±   3%
RegistryConcurrent-4                  740.6n ±   2%
LoaderLoadFromString-4                3.546m ±   1%
geomean                               16.61µ

                            │ benchmark-results.txt │
                            │         B/op          │
InterpreterCreation-4                  2.027Mi ± 0%
ComponentLoad-4                        2.180Mi ± 0%
ComponentExecute-4                     1.203Ki ± 0%
PoolContention/workers-1-4             1.203Ki ± 0%
PoolContention/workers-2-4             1.203Ki ± 0%
PoolContention/workers-4-4             1.203Ki ± 0%
PoolContention/workers-8-4             1.203Ki ± 0%
PoolContention/workers-16-4            1.203Ki ± 0%
ComponentLifecycle-4                   2.183Mi ± 0%
SourceValidation-4                     1.984Ki ± 0%
RegistryConcurrent-4                   1.133Ki ± 0%
LoaderLoadFromString-4                 2.182Mi ± 0%
geomean                                15.25Ki

                            │ benchmark-results.txt │
                            │       allocs/op       │
InterpreterCreation-4                   15.68k ± 0%
ComponentLoad-4                         18.02k ± 0%
ComponentExecute-4                       25.00 ± 0%
PoolContention/workers-1-4               25.00 ± 0%
PoolContention/workers-2-4               25.00 ± 0%
PoolContention/workers-4-4               25.00 ± 0%
PoolContention/workers-8-4               25.00 ± 0%
PoolContention/workers-16-4              25.00 ± 0%
ComponentLifecycle-4                    18.07k ± 0%
SourceValidation-4                       32.00 ± 0%
RegistryConcurrent-4                     2.000 ± 0%
LoaderLoadFromString-4                  18.06k ± 0%
geomean                                  183.3

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                            │ baseline-bench.txt │
                            │       sec/op       │
InterpreterCreation-4               5.399m ± 96%
ComponentLoad-4                     3.499m ±  1%
ComponentExecute-4                  1.909µ ±  1%
PoolContention/workers-1-4          1.192µ ±  1%
PoolContention/workers-2-4          1.202µ ±  1%
PoolContention/workers-4-4          1.196µ ±  1%
PoolContention/workers-8-4          1.199µ ±  1%
PoolContention/workers-16-4         1.206µ ±  2%
ComponentLifecycle-4                3.569m ±  1%
SourceValidation-4                  2.309µ ±  1%
RegistryConcurrent-4                934.4n ±  8%
LoaderLoadFromString-4              3.659m ±  2%
geomean                             19.20µ

                            │ baseline-bench.txt │
                            │        B/op        │
InterpreterCreation-4               2.027Mi ± 0%
ComponentLoad-4                     2.180Mi ± 0%
ComponentExecute-4                  1.203Ki ± 0%
PoolContention/workers-1-4          1.203Ki ± 0%
PoolContention/workers-2-4          1.203Ki ± 0%
PoolContention/workers-4-4          1.203Ki ± 0%
PoolContention/workers-8-4          1.203Ki ± 0%
PoolContention/workers-16-4         1.203Ki ± 0%
ComponentLifecycle-4                2.183Mi ± 0%
SourceValidation-4                  1.984Ki ± 0%
RegistryConcurrent-4                1.133Ki ± 0%
LoaderLoadFromString-4              2.182Mi ± 0%
geomean                             15.25Ki

                            │ baseline-bench.txt │
                            │     allocs/op      │
InterpreterCreation-4                15.68k ± 0%
ComponentLoad-4                      18.02k ± 0%
ComponentExecute-4                    25.00 ± 0%
PoolContention/workers-1-4            25.00 ± 0%
PoolContention/workers-2-4            25.00 ± 0%
PoolContention/workers-4-4            25.00 ± 0%
PoolContention/workers-8-4            25.00 ± 0%
PoolContention/workers-16-4           25.00 ± 0%
ComponentLifecycle-4                 18.07k ± 0%
SourceValidation-4                    32.00 ± 0%
RegistryConcurrent-4                  2.000 ± 0%
LoaderLoadFromString-4               18.06k ± 0%
geomean                               183.3

pkg: github.com/GoCodeAlone/workflow/middleware
cpu: AMD EPYC 9V74 80-Core Processor                
                                  │ benchmark-results.txt │
                                  │        sec/op         │
CircuitBreakerDetection-4                     297.2n ± 2%
CircuitBreakerExecution_Success-4             22.67n ± 0%
CircuitBreakerExecution_Failure-4             71.17n ± 0%
geomean                                       78.28n

                                  │ benchmark-results.txt │
                                  │         B/op          │
CircuitBreakerDetection-4                    144.0 ± 0%
CircuitBreakerExecution_Success-4            0.000 ± 0%
CircuitBreakerExecution_Failure-4            0.000 ± 0%
geomean                                                 ¹
¹ summaries must be >0 to compute geomean

                                  │ benchmark-results.txt │
                                  │       allocs/op       │
CircuitBreakerDetection-4                    1.000 ± 0%
CircuitBreakerExecution_Success-4            0.000 ± 0%
CircuitBreakerExecution_Failure-4            0.000 ± 0%
geomean                                                 ¹
¹ summaries must be >0 to compute geomean

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                  │ baseline-bench.txt │
                                  │       sec/op       │
CircuitBreakerDetection-4                  462.3n ± 0%
CircuitBreakerExecution_Success-4          59.71n ± 1%
CircuitBreakerExecution_Failure-4          65.42n ± 0%
geomean                                    121.8n

                                  │ baseline-bench.txt │
                                  │        B/op        │
CircuitBreakerDetection-4                 144.0 ± 0%
CircuitBreakerExecution_Success-4         0.000 ± 0%
CircuitBreakerExecution_Failure-4         0.000 ± 0%
geomean                                              ¹
¹ summaries must be >0 to compute geomean

                                  │ baseline-bench.txt │
                                  │     allocs/op      │
CircuitBreakerDetection-4                 1.000 ± 0%
CircuitBreakerExecution_Success-4         0.000 ± 0%
CircuitBreakerExecution_Failure-4         0.000 ± 0%
geomean                                              ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/module
cpu: AMD EPYC 9V74 80-Core Processor                
                                 │ benchmark-results.txt │
                                 │        sec/op         │
JQTransform_Simple-4                        824.3n ± 32%
JQTransform_ObjectConstruction-4            1.397µ ±  6%
JQTransform_ArraySelect-4                   3.388µ ±  4%
JQTransform_Complex-4                       41.61µ ±  1%
JQTransform_Throughput-4                    1.740µ ±  1%
SSEPublishDelivery-4                        64.64n ±  0%
geomean                                     1.623µ

                                 │ benchmark-results.txt │
                                 │         B/op          │
JQTransform_Simple-4                      1.273Ki ± 0%
JQTransform_ObjectConstruction-4          1.773Ki ± 0%
JQTransform_ArraySelect-4                 2.625Ki ± 0%
JQTransform_Complex-4                     16.22Ki ± 0%
JQTransform_Throughput-4                  1.984Ki ± 0%
SSEPublishDelivery-4                        0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

                                 │ benchmark-results.txt │
                                 │       allocs/op       │
JQTransform_Simple-4                        10.00 ± 0%
JQTransform_ObjectConstruction-4            15.00 ± 0%
JQTransform_ArraySelect-4                   30.00 ± 0%
JQTransform_Complex-4                       324.0 ± 0%
JQTransform_Throughput-4                    17.00 ± 0%
SSEPublishDelivery-4                        0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                 │ baseline-bench.txt │
                                 │       sec/op       │
JQTransform_Simple-4                     949.7n ± 23%
JQTransform_ObjectConstruction-4         1.514µ ±  3%
JQTransform_ArraySelect-4                3.285µ ±  2%
JQTransform_Complex-4                    36.65µ ±  1%
JQTransform_Throughput-4                 1.823µ ±  2%
SSEPublishDelivery-4                     76.64n ±  9%
geomean                                  1.700µ

                                 │ baseline-bench.txt │
                                 │        B/op        │
JQTransform_Simple-4                   1.273Ki ± 0%
JQTransform_ObjectConstruction-4       1.773Ki ± 0%
JQTransform_ArraySelect-4              2.625Ki ± 0%
JQTransform_Complex-4                  16.22Ki ± 0%
JQTransform_Throughput-4               1.984Ki ± 0%
SSEPublishDelivery-4                     0.000 ± 0%
geomean                                             ¹
¹ summaries must be >0 to compute geomean

                                 │ baseline-bench.txt │
                                 │     allocs/op      │
JQTransform_Simple-4                     10.00 ± 0%
JQTransform_ObjectConstruction-4         15.00 ± 0%
JQTransform_ArraySelect-4                30.00 ± 0%
JQTransform_Complex-4                    324.0 ± 0%
JQTransform_Throughput-4                 17.00 ± 0%
SSEPublishDelivery-4                     0.000 ± 0%
geomean                                             ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/schema
cpu: AMD EPYC 9V74 80-Core Processor                
                                    │ benchmark-results.txt │
                                    │        sec/op         │
SchemaValidation_Simple-4                       1.083µ ± 6%
SchemaValidation_AllFields-4                    1.647µ ± 6%
SchemaValidation_FormatValidation-4             1.563µ ± 3%
SchemaValidation_ManySchemas-4                  1.586µ ± 1%
geomean                                         1.450µ

                                    │ benchmark-results.txt │
                                    │         B/op          │
SchemaValidation_Simple-4                      0.000 ± 0%
SchemaValidation_AllFields-4                   0.000 ± 0%
SchemaValidation_FormatValidation-4            0.000 ± 0%
SchemaValidation_ManySchemas-4                 0.000 ± 0%
geomean                                                   ¹
¹ summaries must be >0 to compute geomean

                                    │ benchmark-results.txt │
                                    │       allocs/op       │
SchemaValidation_Simple-4                      0.000 ± 0%
SchemaValidation_AllFields-4                   0.000 ± 0%
SchemaValidation_FormatValidation-4            0.000 ± 0%
SchemaValidation_ManySchemas-4                 0.000 ± 0%
geomean                                                   ¹
¹ summaries must be >0 to compute geomean

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                    │ baseline-bench.txt │
                                    │       sec/op       │
SchemaValidation_Simple-4                   1.010µ ± 21%
SchemaValidation_AllFields-4                1.499µ ±  1%
SchemaValidation_FormatValidation-4         1.462µ ±  4%
SchemaValidation_ManySchemas-4              1.485µ ±  4%
geomean                                     1.346µ

                                    │ baseline-bench.txt │
                                    │        B/op        │
SchemaValidation_Simple-4                   0.000 ± 0%
SchemaValidation_AllFields-4                0.000 ± 0%
SchemaValidation_FormatValidation-4         0.000 ± 0%
SchemaValidation_ManySchemas-4              0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

                                    │ baseline-bench.txt │
                                    │     allocs/op      │
SchemaValidation_Simple-4                   0.000 ± 0%
SchemaValidation_AllFields-4                0.000 ± 0%
SchemaValidation_FormatValidation-4         0.000 ± 0%
SchemaValidation_ManySchemas-4              0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/store
cpu: AMD EPYC 9V74 80-Core Processor                
                                   │ benchmark-results.txt │
                                   │        sec/op         │
EventStoreAppend_InMemory-4                   1.117µ ± 10%
EventStoreAppend_SQLite-4                     1.081m ±  3%
GetTimeline_InMemory/events-10-4              12.47µ ±  2%
GetTimeline_InMemory/events-50-4              70.35µ ±  2%
GetTimeline_InMemory/events-100-4             125.3µ ± 15%
GetTimeline_InMemory/events-500-4             548.9µ ±  3%
GetTimeline_InMemory/events-1000-4            1.117m ±  3%
GetTimeline_SQLite/events-10-4                86.41µ ±  1%
GetTimeline_SQLite/events-50-4                222.7µ ±  1%
GetTimeline_SQLite/events-100-4               389.4µ ±  5%
GetTimeline_SQLite/events-500-4               1.683m ±  1%
GetTimeline_SQLite/events-1000-4              3.315m ±  4%
geomean                                       196.9µ

                                   │ benchmark-results.txt │
                                   │         B/op          │
EventStoreAppend_InMemory-4                     752.0 ± 8%
EventStoreAppend_SQLite-4                     1.987Ki ± 1%
GetTimeline_InMemory/events-10-4              7.953Ki ± 0%
GetTimeline_InMemory/events-50-4              46.62Ki ± 0%
GetTimeline_InMemory/events-100-4             94.48Ki ± 0%
GetTimeline_InMemory/events-500-4             472.8Ki ± 0%
GetTimeline_InMemory/events-1000-4            944.3Ki ± 0%
GetTimeline_SQLite/events-10-4                16.74Ki ± 0%
GetTimeline_SQLite/events-50-4                87.14Ki ± 0%
GetTimeline_SQLite/events-100-4               175.4Ki ± 0%
GetTimeline_SQLite/events-500-4               846.1Ki ± 0%
GetTimeline_SQLite/events-1000-4              1.639Mi ± 0%
geomean                                       67.08Ki

                                   │ benchmark-results.txt │
                                   │       allocs/op       │
EventStoreAppend_InMemory-4                     7.000 ± 0%
EventStoreAppend_SQLite-4                       53.00 ± 0%
GetTimeline_InMemory/events-10-4                125.0 ± 0%
GetTimeline_InMemory/events-50-4                653.0 ± 0%
GetTimeline_InMemory/events-100-4              1.306k ± 0%
GetTimeline_InMemory/events-500-4              6.514k ± 0%
GetTimeline_InMemory/events-1000-4             13.02k ± 0%
GetTimeline_SQLite/events-10-4                  382.0 ± 0%
GetTimeline_SQLite/events-50-4                 1.852k ± 0%
GetTimeline_SQLite/events-100-4                3.681k ± 0%
GetTimeline_SQLite/events-500-4                18.54k ± 0%
GetTimeline_SQLite/events-1000-4               37.29k ± 0%
geomean                                        1.162k

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                   │ baseline-bench.txt │
                                   │       sec/op       │
EventStoreAppend_InMemory-4                1.135µ ±  3%
EventStoreAppend_SQLite-4                  1.087m ±  3%
GetTimeline_InMemory/events-10-4           13.80µ ±  3%
GetTimeline_InMemory/events-50-4           75.61µ ±  2%
GetTimeline_InMemory/events-100-4          119.8µ ± 25%
GetTimeline_InMemory/events-500-4          611.4µ ±  1%
GetTimeline_InMemory/events-1000-4         1.238m ±  1%
GetTimeline_SQLite/events-10-4             84.03µ ±  1%
GetTimeline_SQLite/events-50-4             241.8µ ±  4%
GetTimeline_SQLite/events-100-4            438.4µ ±  2%
GetTimeline_SQLite/events-500-4            1.989m ±  2%
GetTimeline_SQLite/events-1000-4           3.862m ±  2%
geomean                                    211.4µ

                                   │ baseline-bench.txt │
                                   │        B/op        │
EventStoreAppend_InMemory-4                 780.0 ± 10%
EventStoreAppend_SQLite-4                 1.985Ki ±  2%
GetTimeline_InMemory/events-10-4          7.953Ki ±  0%
GetTimeline_InMemory/events-50-4          46.62Ki ±  0%
GetTimeline_InMemory/events-100-4         94.48Ki ±  0%
GetTimeline_InMemory/events-500-4         472.8Ki ±  0%
GetTimeline_InMemory/events-1000-4        944.3Ki ±  0%
GetTimeline_SQLite/events-10-4            16.74Ki ±  0%
GetTimeline_SQLite/events-50-4            87.14Ki ±  0%
GetTimeline_SQLite/events-100-4           175.4Ki ±  0%
GetTimeline_SQLite/events-500-4           846.1Ki ±  0%
GetTimeline_SQLite/events-1000-4          1.639Mi ±  0%
geomean                                   67.27Ki

                                   │ baseline-bench.txt │
                                   │     allocs/op      │
EventStoreAppend_InMemory-4                  7.000 ± 0%
EventStoreAppend_SQLite-4                    53.00 ± 0%
GetTimeline_InMemory/events-10-4             125.0 ± 0%
GetTimeline_InMemory/events-50-4             653.0 ± 0%
GetTimeline_InMemory/events-100-4           1.306k ± 0%
GetTimeline_InMemory/events-500-4           6.514k ± 0%
GetTimeline_InMemory/events-1000-4          13.02k ± 0%
GetTimeline_SQLite/events-10-4               382.0 ± 0%
GetTimeline_SQLite/events-50-4              1.852k ± 0%
GetTimeline_SQLite/events-100-4             3.681k ± 0%
GetTimeline_SQLite/events-500-4             18.54k ± 0%
GetTimeline_SQLite/events-1000-4            37.29k ± 0%
geomean                                     1.162k

Benchmarks run with go test -bench=. -benchmem -count=6.
Regressions ≥ 20% are flagged. Results compared via benchstat.

@intel352 intel352 merged commit 0f6d1c8 into main Apr 20, 2026
22 checks passed
@intel352 intel352 deleted the fix/spaces-bootstrap-s3-api branch April 20, 2026 19:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants