Daytona enforces API rate limits to ensure fair usage, platform stability, and optimal performance for all users. Rate limits are applied based on your authentication status and the type of operation you’re performing.
Overview
Rate limits control how many API requests you can make within a specific time window. Understanding these limits helps you build robust applications that handle rate limiting gracefully and avoid service interruptions.
Rate Limit Types
Daytona has four distinct rate limit categories, each with independent counters:
| Type | Limit | Time Window | Applies To |
|---|---|---|---|
| Anonymous Requests | 600 requests | 60 seconds | Unauthenticated API calls |
| Authenticated Requests | 50,000 requests | 60 seconds | General authenticated API calls |
| Sandbox Creation | 600 requests | 60 seconds | Creating new sandboxes |
| Sandbox Lifecycle | 50,000 requests | 60 seconds | Start, stop, delete, archive operations |
Anonymous Requests
600 requests per 60 seconds
This rate limit applies to all unauthenticated API requests. Anonymous requests are tracked by IP address and include:
- Public endpoints without API keys or authentication tokens
- Unauthenticated requests to the Daytona API
Authenticated Requests
50,000 requests per 60 seconds
This is the general rate limit for authenticated API requests that don’t fall under sandbox creation or lifecycle operations. This includes:
- Listing sandboxes
- Getting sandbox details
- Retrieving sandbox regions
- Listing snapshots
- Managing volumes
- Viewing audit logs
- And other read/management operations
Rate limits for authenticated requests are tracked per organization.
Sandbox Creation
600 requests per 60 seconds (10 per second)
This rate limit applies to all sandbox creation methods, including creation from snapshots, declarative builds and any other parameters passed to daytona.create() (SDK) or POST requests to /api/sandbox (API).
This independent limit prevents resource exhaustion while allowing you to perform lifecycle operations on existing sandboxes without restriction.
Sandbox Lifecycle Operations
50,000 requests per 60 seconds
This rate limit applies to lifecycle and state management operations on existing sandboxes:
- Starting sandboxes (
POST /api/sandbox/:id/start) - Stopping sandboxes (
POST /api/sandbox/:id/stop) - Deleting sandboxes (
DELETE /api/sandbox/:id) - Archiving sandboxes (
POST /api/sandbox/:id/archive)
And all corresponding SDK methods.
These operations have a higher limit since they’re often performed more frequently during development workflows.
What Happens When You Hit the Limit
When you exceed a rate limit, subsequent requests will fail with:
- HTTP Status:
429 Too Many Requests - Error Response: JSON body with rate limit details
- Retry-After Header: Time to wait before retrying (in seconds)
SDK Behavior
If you’re using the official Daytona SDKs:
- TypeScript SDK: Throws
RateLimitError - Python SDK: Raises
RateLimitException
Example Error Response
{ "statusCode": 429, "message": "Rate limit exceeded", "error": "Too Many Requests"}Rate Limit Headers
Daytona includes rate limit information in API response headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum number of requests allowed in the time window |
X-RateLimit-Remaining | Number of requests remaining in the current window |
X-RateLimit-Reset | Time in seconds until the rate limit window resets |
Retry-After | Time in seconds to wait before retrying (included when limit is exceeded) |
Best Practices
To work effectively within rate limits, always handle 429 errors gracefully with proper retry logic. When you receive a rate limit error, implement exponential backoff—wait progressively longer between retries (1s, 2s, 4s, 8s, etc.) to avoid overwhelming the API. Here’s an example:
async function createSandboxWithRetry() { let retries = 0 const maxRetries = 5
while (retries < maxRetries) { try { return await daytona.create({ snapshot: 'my-snapshot' }) } catch (error) { if (error.statusCode === 429 && retries < maxRetries - 1) { const delay = Math.pow(2, retries) * 1000 // 1s, 2s, 4s, 8s, 16s await new Promise(resolve => setTimeout(resolve, delay)) retries++ } else { throw error } } }}Monitor rate limit headers (X-RateLimit-Remaining, X-RateLimit-Reset) to track your consumption and implement proactive throttling before hitting limits.
Cache API responses that don’t change frequently, such as sandbox lists (when relatively static), available regions, and snapshot information. This reduces unnecessary API calls and helps you stay well within your limits.
Batch and optimize operations by creating multiple sandboxes in parallel (within rate limits) rather than sequentially. Consider reusing existing sandboxes when possible instead of creating new ones for every task.
Efficiently manage sandbox lifecycle to reduce API calls. Archive sandboxes instead of deleting and recreating them, stop sandboxes when not in use rather than deleting them, and leverage auto-stop intervals to automatically manage running sandboxes without manual intervention.
Implement request queuing to prevent bursts that exceed limits, and use webhooks instead of polling for state changes to avoid unnecessary API calls. Set up monitoring and alerts for 429 errors in your application logs so you can proactively address rate limiting issues before they impact your users.
Custom Rate Limits
Rate limits are currently the same across all organization tiers. However, if your use case requires higher rate limits, we offer custom rate limiting for:
- High-volume applications requiring more than 300 sandbox creations per minute
- Enterprise deployments with specific throughput requirements
- Custom integrations with unique rate limit needs
Contact support@daytona.io to discuss custom rate limits tailored to your requirements.
Need Help?
If you’re experiencing rate limiting issues or need assistance:
- Check your current API usage
- Review this documentation for optimization strategies
- Contact support at support@daytona.io for assistance or to discuss custom rate limits