> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/grafana/k6/llms.txt
> Use this file to discover all available pages before exploring further.

# Constant Arrival Rate Executor

> Start iterations at a constant rate regardless of iteration duration

The `constant-arrival-rate` executor starts iterations at a fixed rate (iterations per second), independent of how long each iteration takes. This executor is ideal when you need to maintain a specific throughput or requests-per-second rate.

## How It Works

With constant arrival rate:

1. Iterations start at a fixed rate (e.g., 10 iterations/second)
2. k6 automatically allocates VUs as needed to maintain the rate
3. If iterations are fast, fewer VUs are needed
4. If iterations are slow, more VUs are allocated (up to `maxVUs`)
5. If `maxVUs` is reached and rate can't be maintained, iterations are dropped

```
Iteration Rate: 10 iters/sec

Fast iterations (100ms):
  VU 1: [i][i][i][i][i][i][i][i][i][i]  (handles all 10/sec)
  
Slow iterations (500ms):
  VU 1: [----i----][----i----]           (2/sec)
  VU 2: [----i----][----i----]           (2/sec)
  VU 3: [----i----][----i----]           (2/sec)
  VU 4: [----i----][----i----]           (2/sec)
  VU 5: [----i----][----i----]           (2/sec)
  Total: 10 iters/sec with 5 VUs
```

## Configuration

<ParamField path="executor" type="string" required>
  Must be `constant-arrival-rate`
</ParamField>

<ParamField path="rate" type="integer" required>
  Number of iterations to start per `timeUnit` period. Must be greater than 0.
</ParamField>

<ParamField path="timeUnit" type="duration" default="1s">
  Period over which the `rate` is calculated. Must be greater than 0.
</ParamField>

<ParamField path="duration" type="duration" required>
  Total duration of the executor. Must be at least 1 second.
</ParamField>

<ParamField path="preAllocatedVUs" type="integer" required>
  Number of VUs to pre-allocate before test start. These VUs are immediately available.
</ParamField>

<ParamField path="maxVUs" type="integer" default="preAllocatedVUs">
  Maximum number of VUs allowed. If iterations require more VUs, they will be dropped. Cannot be less than `preAllocatedVUs`.
</ParamField>

## Example

### Basic Throughput Test

```javascript theme={null}
import http from 'k6/http';

export const options = {
  scenarios: {
    constant_rps: {
      executor: 'constant-arrival-rate',
      rate: 30,              // 30 iterations per second
      timeUnit: '1s',
      duration: '5m',
      preAllocatedVUs: 50,   // Start with 50 VUs
      maxVUs: 100,           // Allow up to 100 VUs
    },
  },
};

export default function () {
  http.get('https://test.k6.io');
}
```

### API Rate Limit Testing

```javascript theme={null}
import http from 'k6/http';
import { check } from 'k6';

export const options = {
  scenarios: {
    api_rate_limit: {
      executor: 'constant-arrival-rate',
      rate: 100,             // 100 requests per second
      timeUnit: '1s',
      duration: '10m',
      preAllocatedVUs: 10,
      maxVUs: 200,
    },
  },
  thresholds: {
    http_req_failed: ['rate<0.05'],        // Less than 5% errors
    dropped_iterations: ['rate<0.01'],     // Less than 1% dropped
  },
};

export default function () {
  const res = http.get('https://test.k6.io/api');
  check(res, {
    'status is 200': (r) => r.status === 200,
    'not rate limited': (r) => r.status !== 429,
  });
}
```

### Different Time Units

```javascript theme={null}
export const options = {
  scenarios: {
    // 100 iterations per minute (1.67/sec)
    per_minute: {
      executor: 'constant-arrival-rate',
      rate: 100,
      timeUnit: '1m',
      duration: '10m',
      preAllocatedVUs: 5,
      maxVUs: 10,
    },
  },
};
```

## When to Use

Use the constant arrival rate executor when:

* You need to maintain a specific requests-per-second (RPS) rate
* Iteration duration varies significantly or is unpredictable
* You want to test system throughput capacity
* You're testing against rate limits
* You need consistent load regardless of response times
* You want to model realistic arrival patterns (Poisson distribution)
* Response time degradation shouldn't reduce load

## Behavior Details

### Dynamic VU Allocation

k6 automatically adjusts the number of active VUs to maintain the iteration rate:

```javascript theme={null}
// If response time increases from 100ms to 500ms:
// VUs automatically increase from ~2 to ~10 to maintain rate
```

### Pre-allocated vs Max VUs

* **preAllocatedVUs**: VUs initialized at test start (instant availability)
* **maxVUs**: Maximum VUs that can be used (allocated on-demand)

```javascript theme={null}
{
  preAllocatedVUs: 20,  // 20 VUs ready immediately
  maxVUs: 100,          // Can grow to 100 if needed
}
// If rate needs 30 VUs, 10 more are allocated dynamically
// If rate needs 150 VUs, only 100 are used, rest is dropped
```

### Dropped Iterations

When `maxVUs` is reached and can't maintain the rate, iterations are dropped:

```javascript theme={null}
export const options = {
  scenarios: {
    insufficient_vus: {
      executor: 'constant-arrival-rate',
      rate: 100,
      duration: '5m',
      preAllocatedVUs: 10,
      maxVUs: 10,  // Too few VUs!
    },
  },
  thresholds: {
    dropped_iterations: ['count<100'],  // Alert if too many dropped
  },
};
```

Monitor the `dropped_iterations` metric to detect insufficient VU allocation.

### Calculation: Rate to Iterations/Second

```javascript theme={null}
// rate: 30, timeUnit: '1s' = 30 iters/sec
// rate: 60, timeUnit: '1m' = 1 iter/sec
// rate: 100, timeUnit: '10s' = 10 iters/sec

itersPerSecond = rate / timeUnit_in_seconds
```

## Common Patterns

### Capacity Testing

Find maximum sustainable throughput:

```javascript theme={null}
export const options = {
  scenarios: {
    capacity_test: {
      executor: 'constant-arrival-rate',
      rate: 500,              // Target: 500 RPS
      duration: '10m',
      preAllocatedVUs: 100,
      maxVUs: 500,            // Allow plenty of headroom
    },
  },
  thresholds: {
    http_req_duration: ['p(95)<1000'],   // 95th percentile under 1s
    http_req_failed: ['rate<0.01'],      // Less than 1% errors
    dropped_iterations: ['rate==0'],     // No dropped iterations
  },
};
```

### Realistic Traffic Simulation

```javascript theme={null}
import http from 'k6/http';
import { randomItem } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js';

const endpoints = [
  '/api/users',
  '/api/products', 
  '/api/orders',
];

export const options = {
  scenarios: {
    api_traffic: {
      executor: 'constant-arrival-rate',
      rate: 50,               // 50 RPS average production rate
      duration: '30m',
      preAllocatedVUs: 20,
      maxVUs: 100,
    },
  },
};

export default function () {
  http.get(`https://test.k6.io${randomItem(endpoints)}`);
}
```

### Combined with Ramping

Use multiple scenarios to ramp arrival rate:

```javascript theme={null}
export const options = {
  scenarios: {
    warmup: {
      executor: 'constant-arrival-rate',
      rate: 10,
      duration: '2m',
      preAllocatedVUs: 5,
      maxVUs: 20,
    },
    normal: {
      executor: 'constant-arrival-rate',
      rate: 50,
      duration: '10m',
      startTime: '2m',
      preAllocatedVUs: 20,
      maxVUs: 100,
    },
    peak: {
      executor: 'constant-arrival-rate',
      rate: 200,
      duration: '5m',
      startTime: '12m',
      preAllocatedVUs: 50,
      maxVUs: 300,
    },
  },
};
```

## Sizing VUs

Calculate required VUs:

```
Required VUs ≈ (rate × avg_iteration_duration) / timeUnit

Example:
- Rate: 100 iterations/second
- Average iteration: 500ms
- Required VUs ≈ 100 × 0.5 = 50 VUs

Recommended:
- preAllocatedVUs: 50 (expected)
- maxVUs: 100 (2x safety margin)
```

## Metrics

Key metrics for arrival rate testing:

* `iterations` - Total completed iterations
* `iteration_duration` - How long each iteration takes
* `dropped_iterations` - Iterations dropped due to insufficient VUs
* `vus` - Current number of active VUs
* `vus_max` - Current number of allocated VUs (up to maxVUs)

## Best Practices

1. **Set maxVUs generously**: Allow 2-3x the expected VUs to handle variability
2. **Monitor dropped\_iterations**: Set thresholds to alert on dropped iterations
3. **Right-size preAllocatedVUs**: Match expected steady-state requirements
4. **Consider iteration duration**: Longer iterations need more VUs for same rate
5. **Test VU allocation**: Run short tests to verify VU requirements
6. **Use for throughput testing**: Better than constant-vus for testing capacity
7. **Watch for rate limiting**: Monitor for 429 responses when testing limits

## Comparison with Constant VUs

| Feature             | Constant Arrival Rate     | Constant VUs         |
| ------------------- | ------------------------- | -------------------- |
| Load model          | Fixed iterations/sec      | Fixed VUs            |
| VU count            | Dynamic (auto-scaled)     | Static               |
| Throughput          | Constant (if possible)    | Variable             |
| When response slows | More VUs allocated        | Throughput decreases |
| Complexity          | Higher                    | Lower                |
| Best for            | Throughput/capacity tests | User simulation      |

## Troubleshooting

### Too Many Dropped Iterations

```javascript theme={null}
// Problem: dropped_iterations is high
// Solution: Increase maxVUs
{
  maxVUs: 200,  // Increase from 100
}
```

### VUs Not Fully Utilized

```javascript theme={null}
// Problem: vus much less than preAllocatedVUs
// Solution: Reduce preAllocatedVUs to save resources
{
  preAllocatedVUs: 10,  // Reduce from 50
}
```

## See Also

* [Ramping Arrival Rate](/executors/ramping-arrival-rate) - Variable arrival rate over stages
* [Constant VUs](/executors/constant-vus) - Fixed VU count instead of fixed rate
