oraclecloud-rate-limits

Handle OCI API rate limits with defensive retry patterns and known limits by service. Use when automating bulk OCI operations, hitting 429 TooManyRequests errors, or building resilient API clients. Trigger with "oraclecloud rate limits", "oci 429 error", "oci throttling", "oci backoff".

1,868 stars

Best use case

oraclecloud-rate-limits is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Handle OCI API rate limits with defensive retry patterns and known limits by service. Use when automating bulk OCI operations, hitting 429 TooManyRequests errors, or building resilient API clients. Trigger with "oraclecloud rate limits", "oci 429 error", "oci throttling", "oci backoff".

Teams using oraclecloud-rate-limits should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/oraclecloud-rate-limits/SKILL.md --create-dirs "https://raw.githubusercontent.com/jeremylongshore/claude-code-plugins-plus-skills/main/plugins/saas-packs/oraclecloud-pack/skills/oraclecloud-rate-limits/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/oraclecloud-rate-limits/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How oraclecloud-rate-limits Compares

Feature / Agentoraclecloud-rate-limitsStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Handle OCI API rate limits with defensive retry patterns and known limits by service. Use when automating bulk OCI operations, hitting 429 TooManyRequests errors, or building resilient API clients. Trigger with "oraclecloud rate limits", "oci 429 error", "oci throttling", "oci backoff".

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

Related Guides

SKILL.md Source

# Oracle Cloud Rate Limits

## Overview

OCI API rate limits vary by service and are not well documented. A `429 TooManyRequests` response kills your automation, and unlike AWS or Azure, OCI does not return a `Retry-After` header. This skill maps known limits by service, implements exponential backoff with jitter, and provides circuit breaker patterns for bulk operations.

**Purpose:** Build resilient OCI API clients that handle throttling gracefully without data loss.

## Prerequisites

- **OCI Python SDK** — `pip install oci`
- **OCI config file** at `~/.oci/config` with valid credentials (user, fingerprint, tenancy, region, key_file)
- Python 3.8+
- Understanding of which OCI service you are calling (limits vary per service)

## Instructions

### Step 1: Know the Limits

OCI publishes some rate limits, but many are undocumented. Here are the known limits observed in production:

| Service | Endpoint Type | Observed Limit | Notes |
|---------|--------------|----------------|-------|
| Compute | List/Get | ~20 req/sec | Per-tenancy, not per-user |
| Compute | Create/Update/Delete | ~10 req/sec | Stricter for mutating operations |
| Object Storage | List/Get | ~100 req/sec | Per-bucket namespace |
| Object Storage | Put/Delete | ~50 req/sec | Varies by region load |
| Identity | List/Get | ~10 req/sec | Tenancy-wide shared limit |
| Identity | Create/Update | ~5 req/sec | Very conservative |
| Database | All operations | ~10 req/sec | Shared across DB family |
| Networking (VCN) | All operations | ~20 req/sec | Per-compartment |
| Monitoring | Post metrics | ~50 req/sec | Per-metric namespace |
| Events | Rule CRUD | ~10 req/sec | Per-compartment |

**Critical:** These are observed limits, not guaranteed SLAs. OCI may throttle lower under load.

### Step 2: Implement Exponential Backoff with Jitter

OCI returns no `Retry-After` header on 429 responses, so you must implement your own backoff. The SDK's built-in retry handles some cases, but for bulk operations you need explicit control:

```python
import oci
import time
import random

config = oci.config.from_file("~/.oci/config")

def call_with_retry(fn, max_retries=5, base_delay=1.0):
    """Call an OCI SDK function with exponential backoff and jitter.

    OCI returns 429 TooManyRequests with NO Retry-After header,
    so we implement our own backoff strategy.
    """
    for attempt in range(max_retries):
        try:
            return fn()
        except oci.exceptions.ServiceError as e:
            if e.status == 429:
                # Exponential backoff with full jitter
                delay = base_delay * (2 ** attempt)
                jitter = random.uniform(0, delay)
                wait_time = delay + jitter
                print(f"Rate limited (429). Attempt {attempt + 1}/{max_retries}. "
                      f"Waiting {wait_time:.1f}s")
                time.sleep(wait_time)
            elif e.status >= 500:
                # Server errors — retry with backoff
                delay = base_delay * (2 ** attempt)
                print(f"Server error ({e.status}). Retrying in {delay}s")
                time.sleep(delay)
            else:
                raise  # 4xx errors (except 429) are not retryable
    raise Exception(f"Max retries ({max_retries}) exceeded")
```

### Step 3: Use the SDK's Built-in Retry Configuration

The OCI Python SDK supports retry configuration natively. Use this for simple cases:

```python
import oci
from oci.retry import RetryStrategyBuilder

config = oci.config.from_file("~/.oci/config")

# Build a custom retry strategy
retry_strategy = RetryStrategyBuilder(
    max_attempts_check=True,
    max_attempts=5,
    total_elapsed_time_check=True,
    total_elapsed_time_seconds=300,
    retry_max_wait_between_calls_seconds=30,
    retry_base_sleep_time_seconds=1,
    service_error_check=True,
    service_error_retry_on_any_5xx=True,
    service_error_retry_config={429: []},  # Retry on 429 with any message
    backoff_type=oci.retry.BACKOFF_DECORRELATED_JITTER
).get_retry_strategy()

compute = oci.core.ComputeClient(config, retry_strategy=retry_strategy)

# All calls through this client will automatically retry on 429 and 5xx
instances = compute.list_instances(
    compartment_id="ocid1.compartment.oc1..example"
)
```

### Step 4: Implement a Circuit Breaker for Bulk Operations

For operations that process hundreds of resources, a circuit breaker prevents cascading failures:

```python
import oci
import time
import random

class OCICircuitBreaker:
    """Circuit breaker for bulk OCI API operations."""

    def __init__(self, failure_threshold=5, reset_timeout=60):
        self.failure_count = 0
        self.failure_threshold = failure_threshold
        self.reset_timeout = reset_timeout
        self.last_failure_time = 0
        self.state = "closed"  # closed = normal, open = blocking

    def call(self, fn, max_retries=3, base_delay=1.0):
        if self.state == "open":
            if time.time() - self.last_failure_time > self.reset_timeout:
                self.state = "half-open"
                print("Circuit half-open — testing one request")
            else:
                remaining = self.reset_timeout - (time.time() - self.last_failure_time)
                raise Exception(f"Circuit open. Retry in {remaining:.0f}s")

        try:
            result = call_with_retry(fn, max_retries=max_retries, base_delay=base_delay)
            if self.state == "half-open":
                self.state = "closed"
                self.failure_count = 0
                print("Circuit closed — resuming normal operation")
            return result
        except Exception:
            self.failure_count += 1
            self.last_failure_time = time.time()
            if self.failure_count >= self.failure_threshold:
                self.state = "open"
                print(f"Circuit OPEN after {self.failure_count} failures. "
                      f"Pausing for {self.reset_timeout}s")
            raise

# Usage for bulk listing
breaker = OCICircuitBreaker(failure_threshold=3, reset_timeout=30)
config = oci.config.from_file("~/.oci/config")
compute = oci.core.ComputeClient(config)

compartment_ids = ["ocid1.compartment.oc1..aaa", "ocid1.compartment.oc1..bbb"]
all_instances = []

for cid in compartment_ids:
    result = breaker.call(
        lambda c=cid: compute.list_instances(compartment_id=c)
    )
    all_instances.extend(result.data)
    time.sleep(0.1)  # Courtesy delay between bulk calls
```

### Step 5: Batch Operations with Rate Limiting

For operations that must process many items (e.g., tagging all instances), throttle proactively:

```python
import oci
import time

config = oci.config.from_file("~/.oci/config")
compute = oci.core.ComputeClient(config)

def batch_with_throttle(items, operation, requests_per_second=5):
    """Process items with proactive rate limiting."""
    delay = 1.0 / requests_per_second
    results = []

    for i, item in enumerate(items):
        result = call_with_retry(lambda it=item: operation(it))
        results.append(result)

        if (i + 1) % 50 == 0:
            print(f"Processed {i + 1}/{len(items)}")

        time.sleep(delay)

    return results
```

## Output

Successful implementation produces:
- A retry wrapper function that handles 429 responses with exponential backoff and jitter
- SDK-level retry configuration applied to all OCI client calls
- A circuit breaker that prevents cascading failures during bulk operations
- Proactive rate limiting for batch processing scripts

## Error Handling

| Error | Code | Cause | Solution |
|-------|------|-------|----------|
| TooManyRequests | 429 | API rate limit exceeded (no Retry-After header) | Use exponential backoff with jitter — start at 1s, max 30s |
| NotAuthenticated | 401 | Bad config or expired key | Verify `~/.oci/config` credentials |
| NotAuthorizedOrNotFound | 404 | Missing IAM policy or wrong OCID | Check compartment OCID and IAM policies |
| InternalError | 500 | OCI service error | Retry with backoff; check https://ocistatus.oraclecloud.com |
| ServiceError (status -1) | -1 | Request timeout | Increase SDK timeout or reduce request payload |
| CERTIFICATE_VERIFY_FAILED | — | SSL certificate issue | Update CA certificates: `pip install certifi` |

## Examples

**Quick 429 test — intentionally trigger rate limiting:**

```python
import oci

config = oci.config.from_file("~/.oci/config")
compute = oci.core.ComputeClient(config)

# Rapid-fire requests to observe throttling behavior
for i in range(100):
    try:
        compute.list_instances(compartment_id="ocid1.compartment.oc1..example")
    except oci.exceptions.ServiceError as e:
        if e.status == 429:
            print(f"Throttled at request {i + 1}")
            break
```

**Check current OCI SDK retry defaults:**

```python
import oci
print(f"SDK version: {oci.__version__}")
# Default retry: NoneRetryStrategy (no retries unless configured)
# Always set explicit retry strategies for production code
```

## Resources

- [OCI API Request Limits](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apiconcepts.htm) — official rate limit documentation
- [Python SDK Retry Configuration](https://docs.oracle.com/en-us/iaas/tools/python/latest/) — RetryStrategyBuilder reference
- [SDK Troubleshooting](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdk_troubleshooting.htm) — common SDK errors
- [OCI Known Issues](https://docs.oracle.com/en-us/iaas/Content/knownissues.htm) — known service issues
- [OCI Status](https://ocistatus.oraclecloud.com) — service health dashboard

## Next Steps

After implementing rate limit handling, see `oraclecloud-security-basics` for IAM policy patterns, or `oraclecloud-observability` for monitoring your API call patterns and error rates.

Related Skills

workhuman-rate-limits

1868
from jeremylongshore/claude-code-plugins-plus-skills

Workhuman rate limits for employee recognition and rewards API. Use when integrating Workhuman Social Recognition, or building recognition workflows with HRIS systems. Trigger: "workhuman rate limits".

wispr-rate-limits

1868
from jeremylongshore/claude-code-plugins-plus-skills

Wispr Flow rate limits for voice-to-text API integration. Use when integrating Wispr Flow dictation, WebSocket streaming, or building voice-powered applications. Trigger: "wispr rate limits".

windsurf-rate-limits

1868
from jeremylongshore/claude-code-plugins-plus-skills

Understand and manage Windsurf credit system, usage limits, and model selection. Use when running out of credits, optimizing AI usage costs, or understanding the credit-per-model pricing structure. Trigger with phrases like "windsurf credits", "windsurf rate limit", "windsurf usage", "windsurf out of credits", "windsurf model costs".

webflow-rate-limits

1868
from jeremylongshore/claude-code-plugins-plus-skills

Handle Webflow Data API v2 rate limits — per-key limits, Retry-After headers, exponential backoff, request queuing, and bulk endpoint optimization. Use when hitting 429 errors, implementing retry logic, or optimizing API request throughput. Trigger with phrases like "webflow rate limit", "webflow throttling", "webflow 429", "webflow retry", "webflow backoff", "webflow too many requests".

vercel-rate-limits

1868
from jeremylongshore/claude-code-plugins-plus-skills

Handle Vercel API rate limits, implement retry logic, and configure WAF rate limiting. Use when hitting 429 errors, implementing retry logic, or setting up rate limiting for your Vercel-deployed API endpoints. Trigger with phrases like "vercel rate limit", "vercel throttling", "vercel 429", "vercel retry", "vercel backoff", "vercel WAF rate limit".

veeva-rate-limits

1868
from jeremylongshore/claude-code-plugins-plus-skills

Veeva Vault rate limits for REST API and clinical operations. Use when working with Veeva Vault document management and CRM. Trigger: "veeva rate limits".

vastai-rate-limits

1868
from jeremylongshore/claude-code-plugins-plus-skills

Handle Vast.ai API rate limits with backoff and request optimization. Use when encountering 429 errors, implementing retry logic, or optimizing API request throughput. Trigger with phrases like "vastai rate limit", "vastai throttling", "vastai 429", "vastai retry", "vastai backoff".

twinmind-rate-limits

1868
from jeremylongshore/claude-code-plugins-plus-skills

Implement TwinMind rate limiting, backoff, and optimization patterns. Use when handling rate limit errors, implementing retry logic, or optimizing API request throughput for TwinMind. Trigger with phrases like "twinmind rate limit", "twinmind throttling", "twinmind 429", "twinmind retry", "twinmind backoff".

together-rate-limits

1868
from jeremylongshore/claude-code-plugins-plus-skills

Together AI rate limits for inference, fine-tuning, and model deployment. Use when working with Together AI's OpenAI-compatible API. Trigger: "together rate limits".

techsmith-rate-limits

1868
from jeremylongshore/claude-code-plugins-plus-skills

TechSmith rate limits for Snagit COM API and Camtasia automation. Use when working with TechSmith screen capture and video editing automation. Trigger: "techsmith rate limits".

supabase-rate-limits

1868
from jeremylongshore/claude-code-plugins-plus-skills

Manage Supabase rate limits and quotas across all plan tiers. Use when hitting 429 errors, configuring connection pooling, optimizing API throughput, or understanding tier-specific quotas for Auth, Storage, Realtime, and Edge Functions. Trigger: "supabase rate limit", "supabase 429", "supabase throttle", "supabase quota", "supabase connection pool", "supabase too many requests".

stackblitz-rate-limits

1868
from jeremylongshore/claude-code-plugins-plus-skills

WebContainer resource limits: memory, CPU, file system size, process count. Use when working with WebContainers or StackBlitz SDK. Trigger: "webcontainer limits".