| name | canva-load-scale |
| description | Implement Canva Connect API load testing, auto-scaling, and capacity planning.
Use when running performance tests, planning capacity around Canva rate limits,
or scaling Canva integrations for production workloads.
Trigger with phrases like "canva load test", "canva scale",
"canva performance test", "canva capacity", "canva k6", "canva benchmark".
|
| allowed-tools | Read, Write, Edit, Bash(k6:*), Bash(kubectl:*) |
| version | 1.5.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
| tags | ["saas","design","canva"] |
| compatibility | Designed for Claude Code |
Canva Load & Scale
Overview
Load test and scale Canva Connect API integrations. Since Canva enforces per-user rate limits, scaling means distributing load across users, not increasing per-user throughput.
Canva Rate Limit Constraints
| Operation | Per-User Limit | Implication |
|---|
| Create design | 20/min | Max 1,200 designs/hr per user |
| List designs | 100/min | Generous for reads |
| Create export | 75/5min (500/24hr) | Max 500 exports/day per user |
| Integration export | 750/5min (5,000/24hr) | Shared across all users |
| Upload asset | 30/min | Max 1,800/hr per user |
| Autofill | 60/min | Max 3,600/hr per user |
Key insight: The integration-wide export limit of 5,000/day across ALL users is the most constraining for high-volume scenarios.
k6 Load Test
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend } from 'k6/metrics';
const errorRate = new Rate('canva_error_rate');
const exportDuration = new Trend('canva_export_duration');
export const options = {
scenarios: {
design_operations: {
executor: 'ramping-vus',
startVUs: 1,
: [
{ : , : },
{ : , : },
{ : , : },
{ : , : },
{ : , : },
],
},
},
: {
: [],
: [],
: [],
},
};
= ;
= __ENV.;
headers = {
: ,
: ,
};
() {
listRes = http.(, { headers });
(listRes, { : r. === });
errorRate.(listRes. !== );
(listRes. === ) {
retryAfter = (listRes.[] || );
(retryAfter);
;
}
createRes = http.(, .({
: { : , : , : },
: ,
}), { headers });
(createRes, { : r. === });
errorRate.(createRes. !== );
(createRes. === ) {
designId = createRes.();
exportStart = .();
exportRes = http.(, .({
: designId,
: { : },
}), { headers });
(exportRes. === ) {
jobId = exportRes.();
status = ;
(status === ) {
();
pollRes = http.(, { headers });
status = pollRes.();
}
exportDuration.(.() - exportStart);
}
}
();
}