Set cloud sandbox resource quotas for a specific Team, limiting the total amount of CPU and memory the Team can use. When cloud sandboxes are shared across multiple Teams, business lines, or environments, Team quotas let you enforce resource isolation, cost control, and capacity governance.
Team quota management extends beyond the E2B SDK, and Team quotas are managed through the Alibaba Cloud POP SDK. Creating and accessing sandboxes still requires a cloud sandbox API key from the Function Compute console. The quota APIs themselves use an Alibaba Cloud AccessKey and do not depend on an API key. For console operations to create a Team and choose a resource group and subscription plan, see Create a Team.
Prerequisites
Before using Team quota management, prepare the following:
-
Function Compute and cloud sandbox have been activated.
-
You have contacted customer support in the Alibaba Cloud console to complete allowlisting.
-
A Team has been created in the Function Compute console by following Create a Team, and you have obtained the Team ID for which quotas need to be configured.
-
An Alibaba Cloud AccessKey for calling the POP SDK is ready.
-
The Resource Access Management (RAM) user or role that owns the AccessKey has the
fcsandboxquota management permissions. -
The service endpoint has been confirmed, for example
fcsandbox.cn-beijing.aliyuncs.com.
Quota model
Team quotas are identified by Team ID, passed in through TagValue. The quota items are CPU core count and memory in GB.
| Parameter | Type | Required | Constraints | Description |
TagValue |
*string |
Yes | Matches [A-Za-z0-9_-]{1,64} |
Quota identifier; set to the Team ID. |
CpuCores |
*int32 |
Yes | Greater than or equal to 0 | CPU core quota. |
MemoryGB |
*int32 |
Yes | Greater than or equal to 0 | Memory quota in GB. |
Setting CpuCores or MemoryGB to 0 means the corresponding resource quota is 0, which effectively prohibits the Team from using that resource. When you call the update API multiple times, the new value overwrites the old one.
API overview
| Operation | Go Method | Description |
| Create or update quota | UpdateQuota |
Set the CPU and memory quotas for a Team. |
| Query quota | DescribeQuota |
Query the quota for a specified Team. |
| List quotas | ListQuota |
List the quotas under the current account. |
| Delete quota | DeleteQuota |
Delete the quota for a specified Team. |
Using the Go SDK
Use the Alibaba Cloud POP Go SDK to manage Team quotas. The Go method names are in PascalCase, such as UpdateQuota, DescribeQuota, ListQuota, and DeleteQuota. Request and response fields are pointer types. Use the helper functions from the tea package, such as tea.String and tea.Int32, for boxing and unboxing.
Install dependencies
go get github.com/alibabacloud-go/fcsandbox-20260509/client
go get github.com/alibabacloud-go/darabonba-openapi/v2/utils
go get github.com/alibabacloud-go/tea/tea
The packages involved are as follows:
| Package | Import Path | Purpose |
| SDK client | github.com/alibabacloud-go/fcsandbox-20260509/client |
Quota management APIs. |
| OpenAPI configuration | github.com/alibabacloud-go/darabonba-openapi/v2/utils |
Client configuration, including the AccessKey ID and AccessKey Secret (AK/SK) and the endpoint. |
| tea utilities | github.com/alibabacloud-go/tea/tea |
Pointer boxing and unboxing helper functions. |
Step 1: Initialize the SDK client
Pass the AccessKey through environment variables. Do not write the AK/SK into code, images, templates, or logs.
The following example shows the core code for initializing the client:
import (
"log"
"os"
fcsandbox "github.com/alibabacloud-go/fcsandbox-20260509/client"
openapiutil "github.com/alibabacloud-go/darabonba-openapi/v2/utils"
"github.com/alibabacloud-go/tea/tea"
)
config := &openapiutil.Config{
AccessKeyId: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")),
AccessKeySecret: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")),
SecurityToken: tea.String(os.Getenv("ALIBABA_CLOUD_SECURITY_TOKEN")),
Endpoint: tea.String("fcsandbox.cn-beijing.aliyuncs.com"),
}
client, err := fcsandbox.NewClient(config)
if err != nil {
log.Fatalf("init client failed: %v", err)
}
Set the environment variables before running:
export ALIBABA_CLOUD_ACCESS_KEY_ID="<your-access-key-id>"
export ALIBABA_CLOUD_ACCESS_KEY_SECRET="<your-access-key-secret>"
# Required only when using STS temporary credentials.
# export ALIBABA_CLOUD_SECURITY_TOKEN="<your-security-token>"
Step 2: Create a resource quota
Use UpdateQuota to set the CPU and memory quotas for a Team. Set TagValue to the Team ID.
resp, err := client.UpdateQuota(&fcsandbox.UpdateQuotaRequest{
Body: &fcsandbox.Quota{
TagValue: tea.String("{team-id}"),
CpuCores: tea.Int32(32),
MemoryGB: tea.Int32(32),
},
})
if err != nil {
log.Fatalf("update quota failed: %v", err)
}
quota := resp.Body.Quota
log.Printf("quota created: cpu=%d, memory=%d",
tea.Int32Value(quota.CpuCores),
tea.Int32Value(quota.MemoryGB),
)
Parameters:
| Parameter | Type | Required | Constraints | Description |
TagValue |
*string |
Yes | Matches [A-Za-z0-9_-]{1,64} |
Quota identifier; set to the Team ID. |
CpuCores |
*int32 |
Yes | Greater than or equal to 0 | CPU core quota. |
MemoryGB |
*int32 |
Yes | Greater than or equal to 0 | Memory quota in GB. |
UpdateQuota is an overwrite update. When you call it multiple times for the same TagValue, the later configuration replaces the earlier one.
Step 3: Query a quota
resp, err := client.DescribeQuota(&fcsandbox.DescribeQuotaRequest{
TagValue: tea.String("{team-id}"),
})
if err != nil {
log.Fatalf("describe quota failed: %v", err)
}
quota := resp.Body.Quota
log.Printf("quota: cpu=%d, memory=%d",
tea.Int32Value(quota.CpuCores),
tea.Int32Value(quota.MemoryGB),
)
Step 4: List all quotas
var nextToken *string
for {
resp, err := client.ListQuota(&fcsandbox.ListQuotaRequest{
MaxResults: tea.Int32(100),
NextToken: nextToken,
})
if err != nil {
log.Fatalf("list quota failed: %v", err)
}
for _, quota := range resp.Body.Quotas {
log.Printf("quota: tagValue=%s, cpu=%d, memory=%d",
tea.StringValue(quota.TagValue),
tea.Int32Value(quota.CpuCores),
tea.Int32Value(quota.MemoryGB),
)
}
nextToken = resp.Body.NextToken
if tea.StringValue(nextToken) == "" {
break
}
}
Pagination parameters:
-
MaxResults: The number of entries per page. -
NextToken: The pagination token, obtained from the previous response'sresp.Body.NextToken.
Step 5: Update a quota
Use the same UpdateQuota API to overwrite the quota:
resp, err := client.UpdateQuota(&fcsandbox.UpdateQuotaRequest{
Body: &fcsandbox.Quota{
TagValue: tea.String("{team-id}"),
CpuCores: tea.Int32(64),
MemoryGB: tea.Int32(64),
},
})
if err != nil {
log.Fatalf("update quota failed: %v", err)
}
quota := resp.Body.Quota
log.Printf("quota updated: cpu=%d, memory=%d",
tea.Int32Value(quota.CpuCores),
tea.Int32Value(quota.MemoryGB),
)
Step 6: Delete a quota
resp, err := client.DeleteQuota(&fcsandbox.DeleteQuotaRequest{
TagValue: tea.String("{team-id}"),
})
if err != nil {
log.Fatalf("delete quota failed: %v", err)
}
log.Printf("quota deleted: requestId=%s", tea.StringValue(resp.Body.RequestId))
After deletion, calling DescribeQuota again for the same TagValue will eventually return HTTP status code 404 and the error code ResourceQuotaNotFound. If deletion has a brief eventual-consistency delay, your business code should confirm the result with bounded polling.
Error handling
Errors from the Go SDK APIs are usually *tea.SDKError. Read Code, StatusCode, and Message through errors.As. If the error is not of this type, continue to log or return the original error. To use the following code, import the errors package.
var sdkErr *tea.SDKError
_, err := client.DescribeQuota(&fcsandbox.DescribeQuotaRequest{
TagValue: tea.String("{team-id}"),
})
if err != nil {
if errors.As(err, &sdkErr) {
log.Printf("code=%s, statusCode=%d, message=%s",
tea.StringValue(sdkErr.Code),
tea.IntValue(sdkErr.StatusCode),
tea.StringValue(sdkErr.Message),
)
} else {
log.Printf("request failed: %v", err)
}
}
For the meaning of the error codes, see the Error code reference section below.
Complete example
Below is a complete, runnable example main.go that performs the create, query, list, update, delete, and delete-confirmation steps in order.
Warning: This example overwrites the specified Team's quota twice and deletes the quota at the end. Run it only against a test Team that has no workloads and no existing quota configured. Do not run this complete example directly against a production Team; instead, run the individual operation examples according to your actual resource requirements.
package main
import (
"errors"
"fmt"
"log"
"os"
"time"
fcsandbox "github.com/alibabacloud-go/fcsandbox-20260509/client"
openapiutil "github.com/alibabacloud-go/darabonba-openapi/v2/utils"
"github.com/alibabacloud-go/tea/tea"
)
const (
endpoint = "fcsandbox.cn-beijing.aliyuncs.com"
)
func main() {
ak := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
sk := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
if ak == "" || sk == "" {
log.Fatal("Set ALIBABA_CLOUD_ACCESS_KEY_ID / ALIBABA_CLOUD_ACCESS_KEY_SECRET")
}
teamID := os.Getenv("FCSANDBOX_TEAM_ID")
if teamID == "" {
log.Fatal("Set FCSANDBOX_TEAM_ID")
}
client, err := fcsandbox.NewClient(&openapiutil.Config{
AccessKeyId: tea.String(ak),
AccessKeySecret: tea.String(sk),
SecurityToken: tea.String(os.Getenv("ALIBABA_CLOUD_SECURITY_TOKEN")),
Endpoint: tea.String(endpoint),
})
if err != nil {
log.Fatalf("init client failed: %v", err)
}
// 1. Create the quota
createResp, err := client.UpdateQuota(&fcsandbox.UpdateQuotaRequest{
Body: &fcsandbox.Quota{
TagValue: tea.String(teamID),
CpuCores: tea.Int32(32),
MemoryGB: tea.Int32(32),
},
})
if err != nil {
log.Fatalf("create quota failed: %v", err)
}
fmt.Printf("[1] created: cpu=%d, mem=%d\n",
tea.Int32Value(createResp.Body.Quota.CpuCores),
tea.Int32Value(createResp.Body.Quota.MemoryGB))
// 2. Query the quota
getResp, err := client.DescribeQuota(&fcsandbox.DescribeQuotaRequest{
TagValue: tea.String(teamID),
})
if err != nil {
log.Fatalf("describe quota failed: %v", err)
}
fmt.Printf("[2] describe: cpu=%d, mem=%d\n",
tea.Int32Value(getResp.Body.Quota.CpuCores),
tea.Int32Value(getResp.Body.Quota.MemoryGB))
// 3. List all quotas
total := 0
var nextToken *string
for {
listResp, err := client.ListQuota(&fcsandbox.ListQuotaRequest{
MaxResults: tea.Int32(100),
NextToken: nextToken,
})
if err != nil {
log.Fatalf("list quota failed: %v", err)
}
for _, q := range listResp.Body.Quotas {
total++
fmt.Printf(" tagValue=%s, cpu=%d, mem=%d\n",
tea.StringValue(q.TagValue),
tea.Int32Value(q.CpuCores),
tea.Int32Value(q.MemoryGB),
)
}
nextToken = listResp.Body.NextToken
if tea.StringValue(nextToken) == "" {
break
}
}
fmt.Printf("[3] list: %d quotas\n", total)
// 4. Update the quota
updResp, err := client.UpdateQuota(&fcsandbox.UpdateQuotaRequest{
Body: &fcsandbox.Quota{
TagValue: tea.String(teamID),
CpuCores: tea.Int32(64),
MemoryGB: tea.Int32(64),
},
})
if err != nil {
log.Fatalf("update quota failed: %v", err)
}
fmt.Printf("[4] updated: cpu=%d, mem=%d\n",
tea.Int32Value(updResp.Body.Quota.CpuCores),
tea.Int32Value(updResp.Body.Quota.MemoryGB))
// 5. Delete the quota
delResp, err := client.DeleteQuota(&fcsandbox.DeleteQuotaRequest{
TagValue: tea.String(teamID),
})
if err != nil {
log.Fatalf("delete quota failed: %v", err)
}
fmt.Printf("[5] deleted (requestId=%s)\n", tea.StringValue(delResp.Body.RequestId))
// 6. Confirm deletion; a 404 is expected eventually.
for attempt := 1; attempt <= 5; attempt++ {
_, err = client.DescribeQuota(&fcsandbox.DescribeQuotaRequest{
TagValue: tea.String(teamID),
})
if err == nil {
if attempt == 5 {
log.Fatal("[6] expected 404 but describe still succeeded")
}
time.Sleep(time.Duration(attempt) * time.Second)
continue
}
var sdkErr *tea.SDKError
if !errors.As(err, &sdkErr) {
log.Fatalf("confirm deletion failed: %v", err)
}
if tea.IntValue(sdkErr.StatusCode) != 404 ||
tea.StringValue(sdkErr.Code) != "ResourceQuotaNotFound" {
log.Fatalf("confirm deletion failed: statusCode=%d, code=%s",
tea.IntValue(sdkErr.StatusCode),
tea.StringValue(sdkErr.Code),
)
}
fmt.Printf("[6] confirmed deletion: statusCode=%d, code=%s\n",
tea.IntValue(sdkErr.StatusCode),
tea.StringValue(sdkErr.Code),
)
break
}
fmt.Println("ALL STEPS PASSED")
}
Set the environment variables before running:
export ALIBABA_CLOUD_ACCESS_KEY_ID="<your-access-key-id>"
export ALIBABA_CLOUD_ACCESS_KEY_SECRET="<your-access-key-secret>"
# Required only when using STS temporary credentials.
# export ALIBABA_CLOUD_SECURITY_TOKEN="<your-security-token>"
export FCSANDBOX_TEAM_ID="<team-id>"
go run main.go
Error code reference
Common errors are as follows:
| HTTP Status Code | Code | Description |
| 400 | InvalidParameter |
Request parameter validation failed, for example a missing required field or an invalid format. |
| 401 | Unauthorized |
Credentials are invalid or not provided. |
| 403 | Forbidden |
No permission to perform the operation. |
| 404 | ResourceQuotaNotFound |
The queried quota does not exist. |
| 429 | LimitExceeded |
The quota limit has been exceeded. |
| 500 | InternalError |
Internal service error; retry. |
FAQ
What should TagValue be set to?
Set it to the Team ID.
How do I obtain the Team ID?
After creating a Team (Create a Team) in the Function Compute cloud sandbox console, open Manage Team in the Team selector on the left and copy the Team ID from the list.
Can CpuCores and MemoryGB be set to 0?
Yes. A value of 0 means the quota is 0, which effectively prohibits the Team from using that resource. Negative values are not allowed.
What happens when I call UpdateQuota multiple times for the same TagValue?
UpdateQuota is an idempotent overwrite operation. Each call replaces the old value with the new one.
What happens when I query a quota after deleting it?
Querying the same TagValue after deletion will eventually return HTTP status code 404 and the error code ResourceQuotaNotFound. If deletion has a brief eventual-consistency delay, confirm the result with bounded polling.
Recommendations
-
Set separate quotas for production Teams, test Teams, and batch-processing Teams.
-
Do not let test workloads and production workloads share the same high-quota Team.
-
Before lowering a quota, confirm the running sandboxes and your peak business load.
-
Before deleting a quota, confirm that the Team no longer needs a dedicated quota.
-
When a quota is exhausted, your application should use queues, concurrency limits, timeouts, and backoff retries to avoid amplifying failures.
-
After a sandbox task completes, explicitly call
sandbox.kill()to release resources.
Notes
-
Team quota management uses the POP SDK and Alibaba Cloud AK/SK, not the cloud sandbox API key for authentication.
-
Cloud sandbox API keys are still created and managed through the Function Compute console.
-
Do not write the AK/SK or API key into code repositories, images, templates, logs, screenshots, tickets, or frontend pages.
-
Team quota management is a cloud sandbox control-plane management capability, not an E2B SDK-compatible API.
-
Quotas address only resource upper limits; they cannot replace rate limiting, task queues, timeout control, and resource release in your application.