Imagine: your mobile app hits the top of the App Store, and 50,000 new users flood in overnight. In the morning, you find backend downtime—504 errors on every screen. Without load testing, the backend can't handle peak surges from push notifications or ad campaigns. We run full-cycle testing: write scripts in k6, JMeter, or Gatling; set up load profiles; analyze bottlenecks; and provide optimization recommendations. k6 starts scripts three times faster than JMeter at high volumes, and its scripts are compact and readable. Below, we walk through the process using a typical mobile API example.
Why API Load Testing Is Critical for Mobile Apps
Mobile traffic differs from web: devices send many concurrent requests, run in the background, and experience unpredictable network conditions. Without load profiling, the backend may not withstand peak loads. A common issue is that the backend is designed for average traffic, not spikes from push notifications or ad campaigns.
How We Choose the Tool
Three main tools, each for its own purpose:
| Tool | Script Language | Strength |
|---|---|---|
| k6 | JavaScript | Modern, CI-friendly, low entry barrier |
| JMeter | XML / GUI | Mature, rich plugins, visual test design |
| Gatling | Scala / DSL | Precise metrics, convenient HTML reports |
For most mobile APIs, we choose k6—compact scripts, native Grafana integration, runs in Docker without JVM. Our specialists (5+ years experience) configure the tool for your architecture.
Writing a k6 Script for a Mobile API
A typical mobile API has specifics: JWT authorization with short TTL, refresh tokens, gzip response compression, sometimes GraphQL instead of REST. The script must account for these.
import http from 'k6/http';
import { check, sleep } from 'k6';
import { SharedArray } from 'k6/data';
// Test accounts from CSV—not a single account for all VUs
const users = new SharedArray('users', () => open('./test_users.csv').split('\n').map(line => {
const [email, password] = line.split(',');
return { email, password };
}));
export const options = {
stages: [
{ duration: '2m', target: 100 }, // ramp-up
{ duration: '5m', target: 500 }, // plateau
{ duration: '2m', target: 1000 }, // peak
{ duration: '1m', target: 0 }, // ramp-down
],
thresholds: {
http_req_duration: ['p(95)<500'], // 95% of requests < 500ms
http_req_failed: ['rate<0.01'], // less than 1% errors
},
};
export default function () {
const user = users[__VU % users.length];
// Login + get token
const loginRes = http.post('https://api.example.com/v1/auth/login', JSON.stringify({
email: user.email,
password: user.password,
}), {
headers: { 'Content-Type': 'application/json' },
});
check(loginRes, {
'login 200': (r) => r.status === 200,
'has token': (r) => r.json('data.access_token') !== undefined,
});
const token = loginRes.json('data.access_token');
sleep(1); // simulate user behavior
// Load feed
const feedRes = http.get('https://api.example.com/v1/feed?page=1&limit=20', {
headers: { Authorization: `Bearer ${token}` },
});
check(feedRes, {
'feed 200': (r) => r.status === 200,
'feed has items': (r) => r.json('data.items').length > 0,
});
sleep(2);
}
Official k6 documentation recommends using SharedArray to distribute test data among virtual users.
SharedArray for users is critical. If all virtual users share one account, the backend might cache the session, skewing results.
What Load Profiles Are Needed?
Mobile traffic is uneven. We define four typical profiles:
Details on load profiles
| Profile | Goal | Duration | Success Criteria |
|---|---|---|---|
| Baseline | Stable 24/7 operation | 1–2 hours | p95 < 300 ms, error rate < 0.1% |
| Peak | Morning/evening spike | 30 minutes | p95 < 500 ms, error rate < 1% |
| Stress | Find breaking point | 10–20 minutes | error rate < 5% |
| Soak | Detect leaks | 4–8 hours | latency doesn't grow |
Baseline—steady load 24/7. Checks that at average traffic p95 < 300 ms.
Peak—morning and evening spikes. Gradual ramp from 10% to 300% of average over 5 minutes.
Stress—intentionally exceed estimated maximum to find the breaking point. Continue until error rate exceeds 5% or latency increases tenfold.
Soak—70% of peak for 4–8 hours. Catches memory leaks, database connection pool exhaustion, log rotation issues.
Analyzing Results: What to Look For in Metrics
k6 sends metrics to Grafana via InfluxDB or built-in Prometheus remote write:
k6 run --out influxdb=http://localhost:8086/k6 scenario.js
After the run, inspect:
-
http_req_durationpercentiles (p50, p90, p95, p99) -
http_req_blocked—queue time (high value = connection pool exhausted) -
http_req_connecting—TCP connection time (high = no keep-alive) -
data_received—data volume (unexpectedly large = no gzip or extra fields in response)
Typical bottlenecks in mobile API:
- N+1 queries to database when loading feed with nested objects
- Missing index on
user_id+created_atin posts table - Synchronous push notification sending inside request instead of background queue
Running in CI
- name: Run k6 load test
uses: grafana/[email protected]
with:
filename: tests/load/api_test.js
flags: --duration 5m --vus 100
env:
K6_CLOUD_TOKEN: ${{ secrets.K6_CLOUD_TOKEN }}
In CI we run a lightweight profile (100 VUs, 5 minutes) for basic performance regression. Full stress tests are scheduled or triggered before releases.
What's Included in Our Work
We provide a complete package:
- Turnkey load test scripts (k6/JMeter/Gatling)
- Report with metrics and graphs (Grafana dashboard)
- Bottleneck optimization recommendations
- Integration into your CI/CD (GitHub Actions, GitLab CI, Jenkins)
- Consultation with your backend team on results
- Script correctness guarantee: free rework if the backend changes
How to Write a k6 Script: Step-by-Step Guide
- Prepare test data. Generate a CSV file with user accounts (email, password)—at least 100 entries.
- Create script. Import k6 modules, define options (stages, thresholds), and the main function with authorization and typical requests.
- Set up environment. Install k6 locally or in Docker, prepare InfluxDB/Grafana for metrics collection.
- Run test. Execute
k6 run script.jswith desired parameters. - Analyze results. Review dashboards, identify bottlenecks.
Company Experience
We have over 5 years in load testing and have completed more than 50 projects for fintech, e-commerce, and social media apps. Certified k6 and JMeter specialists ensure objective results.
Timelines and Cost
Estimated timelines: 3–7 days for script development, execution, and reporting. Infrastructure savings after our optimization can reach 40%. Cost is determined after reviewing your API documentation.
Contact us for a consultation—we'll assess your project free of charge. Order load testing to avoid downtime and user loss.







