github.com/upstash/blob-go is the Go SDK. It has a Bucket client for server-side reads and writes, and an upload handler that serves the browser client, so a React app can upload straight to storage through a Go backend.
This section is the Go reference: names, types, and net/http wiring. What each call does, its defaults and its limits are on the concept pages it links to.
Install#
It needs Go 1.22 or later and uses only the standard library.
The package name is blob. The examples import it under that name explicitly, since the module path ends in blob-go.
| Exports | |
|---|---|
Bucket, NewBucket, NewBucketFromEnv, NewBucketWith, Options, RetryConfig | The bucket client. See Bucket API. |
UpdateJSON, UniquePath | Package functions that take or build a path. |
NewUploadHandler, UploadHandlerOptions, UploadRoute, JSONInput | The server half of a browser upload. See Upload handler. |
Error, ErrorCode, NewError, HasCode, ErrNotFound, … | See Errors. |
KB, MB, GB, MiB, …, ParseSize, FormatBytes | See Option types. |
CacheImmutable, CacheRevalidate, CacheNoStore | See Caching. |
MultipartAlways, MultipartNever, MultipartOver | See Large bodies. |
There is no Go browser client. The browser runs @upstash/blob/react or @upstash/blob/browser, which speak the same protocol to a Go handler as to a TypeScript one; see With a server in another language.
The Bucket client#
NewBucketFromEnv() returns an error when UPSTASH_BLOB_TOKEN is unset or empty. NewBucket(token) takes the token directly. NewBucketWith takes every option:
| Field | Type | Description |
|---|---|---|
Token | string | Required. Surrounding whitespace, such as the newline of a token read from a file, is trimmed. See Connecting. |
Cache | string | The default Cache-Control for every object this client stores. A per-call Cache overrides it. See Caching. |
DisableTelemetry | bool | Turns telemetry off for this client. See Telemetry. |
Retry | RetryConfig | See Retries. The zero value keeps the defaults. |
HTTPClient | *http.Client | Sends every request, for a proxy or a custom transport. Nil is http.DefaultClient. A Timeout on it also bounds reading a Get body and sending a large Put; bound a call with its context instead. |
A missing or malformed token, an unparseable Cache and a negative retry count are returned as an error from the constructor, not on the first request.
There is no visibility option. Whether the bucket is public or private is a console setting; see Connecting.
A *Bucket is safe for concurrent use. Build one at startup and share it, or build one per request: buckets on the same token share one credential cache.
Contexts#
Every method that makes a request takes a context.Context first. Canceling it, or a deadline passing, stops the request and any retry wait, and the method returns the context’s error. In a handler, pass r.Context().
A multipart upload that fails or is canceled aborts itself on its way out, on a context of its own, so the parts already sent are not left behind.
Retries#
| Field | Type | Description |
|---|---|---|
Disabled | bool | Sends every request once. |
Retries | int | Retries after the first attempt, for every request this client makes. Zero keeps the defaults. |
Backoff | func(retryCount int) time.Duration | The wait before retry n, counted from 0. A Retry-After from the service wins over it. Nil keeps the default. |
Which requests are retried, and the default budget and backoff, are on Retries. In Go, a body Put can read again is retried; see Bodies.
Using an S3 client#
bucket.S3(ctx) returns an *S3Credentials with Endpoint, Region, Bucket, a short-lived credential and its Expires. The SDK does not depend on the AWS SDK; bring your own. The credential stops working at Expires, so hand the AWS SDK a provider that calls bucket.S3 again, as above, rather than a static one.
What an S3 client is for, and why it must not presign, is on Using an S3 client.
Option types#
| Type | Go | Grammar |
|---|---|---|
| Size | int64 bytes | Size. Write 20 * blob.MB or 32 * blob.MiB. |
| Duration | time.Duration | Duration. Signed URL lifetimes count whole seconds. |
| CacheOption | string | CacheOption: a Cache* constant, a duration such as "15m", "3600" or "1h30m", or a raw header. |
| MultipartOption | blob.Multipart | Changing the threshold |
KB, MB, GB and TB are powers of 1,000, and KiB, MiB, GiB and TiB powers of 1,024. 32 * blob.MB refuses a 32 MiB file.
A size read from configuration goes through blob.ParseSize("32MiB"), which takes the same strings as the other SDKs and returns invalid_input for one that does not parse. blob.FormatBytes(2_400_000) is "2.4 MB", the same text the browser client shows.
The zero value of every option means unset: no limit, the default lifetime, the bucket’s cache. A negative size or lifetime on a Bucket call is refused with invalid_input, and a negative MaxSize on an upload handler or route is an error from NewUploadHandler. Two negatives have a meaning: a route’s MaxSize: blob.NoLimit clears the handler’s limit, and MultipartOver treats a negative threshold as 0.