ہماری Performance & Scalability سیریز کا حصہ
مکمل گائیڈ پڑھیںلوڈ ٹیسٹنگ کے بغیر مصنوعات کی ترسیل ایک جوا ہے۔ آپ کو اپنے بریکنگ پوائنٹ کا علم نہیں ہوتا جب تک کہ صارفین اسے آپ کے لیے تلاش نہ کریں — عام طور پر پروڈکٹ لانچ، وائرل لمحے، یا سیلز میں اضافے کے دوران۔ k6 ایک جدید لوڈ ٹیسٹنگ ٹول ہے جو آپ کو JavaScript میں ٹیسٹ لکھنے، انہیں CI سے چلانے اور صارفین سے پہلے اپنی کارکردگی کی حد دریافت کرنے دیتا ہے۔ یہ ڈویلپر کے لیے دوستانہ، وسائل کے لحاظ سے موثر ہے (k6 goroutines کا استعمال کرتا ہے، نہ کہ تھریڈز)، اور ریئل ٹائم میٹرکس کے لیے Grafana اور Prometheus کے ساتھ صاف طور پر ضم ہوتا ہے۔
یہ گائیڈ پہلی اسکرپٹ سے پیچیدہ ملٹی سیناریو لوڈ ٹیسٹ، کسٹم میٹرکس، تھریشولڈز، CI انضمام، اور Node.js/NestJS APIs کے لیے پروڈکشن کے لیے محفوظ ٹیسٹنگ پیٹرن کے ذریعے k6 کا احاطہ کرتی ہے۔
اہم ٹیک ویز
- k6 اسکرپٹ جاوا اسکرپٹ ہیں لیکن گو رن ٹائم میں چلتی ہیں — کوئی Node.js APIs نہیں (کوئی
require، کوئیfs، کوئیsetTimeout)- ورچوئل یوزرز (VUs) ہم وقت ساز استعمال کنندہ ہیں۔ تکرار انفرادی اسکرپٹ پر عملدرآمد ہیں۔
- دوڑنے سے پہلے ہمیشہ حد مقرر کریں - ناکام ہونے والی حدیں ٹیسٹ کو روکتی ہیں اور CI میں ناکام ہوجاتی ہیں
- حقیقی ٹریفک پیٹرن کو ماڈل کرنے کے لیے منظرنامے (مستقل-vus، ramping-vus، constant-arrival-rate) کا استعمال کریں
- آپریشن کے ساتھ ہم آہنگی کیے بغیر کبھی بھی ٹیسٹ پروڈکشن لوڈ نہ کریں - اسٹیجنگ یا پروڈکشن کلون کے خلاف ٹیسٹ
http_req_durationمیٹرک آپ کا بنیادی SLA میٹرک ہے — p95 اور p99 اوسط سے زیادہ اہمیت رکھتے ہیں- اپنے k6 رنرز کو ریٹ محدود کریں — لوڈ ٹیسٹ ٹریفک سے آپ کی شرح کی حد کا بجٹ ختم نہیں ہونا چاہیے۔
- جغرافیائی علاقوں میں تقسیم شدہ لوڈ ٹیسٹنگ کے لیے k6 Cloud یا Grafana k6 استعمال کریں
انسٹالیشن اور پہلا اسکرپٹ
# macOS
brew install k6
# Ubuntu/Debian
sudo gpg -k && sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update && sudo apt-get install k6
# Windows (via Chocolatey)
choco install k6
آپ کی پہلی k6 اسکرپٹ:
// k6/homepage-load.js
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate } from 'k6/metrics';
// Custom metric: error rate
const errorRate = new Rate('error_rate');
export const options = {
// Ramp up to 50 VUs over 1 minute, hold 2 minutes, ramp down
stages: [
{ duration: '1m', target: 50 },
{ duration: '2m', target: 50 },
{ duration: '1m', target: 0 },
],
thresholds: {
http_req_duration: ['p(95)<500', 'p(99)<1000'], // 95th pct < 500ms
http_req_failed: ['rate<0.01'], // Less than 1% errors
error_rate: ['rate<0.01'],
},
};
const BASE_URL = __ENV.BASE_URL || 'http://localhost:3000';
export default function () {
const res = http.get(`${BASE_URL}/`);
const ok = check(res, {
'status is 200': (r) => r.status === 200,
'response time < 500ms': (r) => r.timings.duration < 500,
'body contains ECOSIRE': (r) => r.body.includes('ECOSIRE'),
});
errorRate.add(!ok);
sleep(1); // 1 second think time between iterations
}
اسے چلائیں:
k6 run k6/homepage-load.js
k6 run --env BASE_URL=https://staging.ecosire.com k6/homepage-load.js
k6 run --vus 100 --duration 30s k6/homepage-load.js # Quick smoke test
توثیق کے ساتھ API لوڈ ٹیسٹ
// k6/api-load.js
import http from 'k6/http';
import { check, group, sleep } from 'k6';
import { Counter, Trend } from 'k6/metrics';
const apiCalls = new Counter('api_calls');
const authDuration = new Trend('auth_duration');
export const options = {
scenarios: {
// Constant arrival rate: 100 requests/second regardless of VU count
constant_load: {
executor: 'constant-arrival-rate',
rate: 100,
timeUnit: '1s',
duration: '3m',
preAllocatedVUs: 50,
maxVUs: 200,
},
},
thresholds: {
http_req_duration: ['p(95)<300', 'p(99)<500'],
'http_req_duration{type:api}': ['p(95)<200'],
http_req_failed: ['rate<0.005'], // 0.5% error budget
},
};
const BASE_URL = __ENV.BASE_URL || 'http://localhost:3001';
// setup() runs once before VUs start
export function setup() {
// Authenticate and return tokens for VUs to use
const loginRes = http.post(`${BASE_URL}/auth/login`, JSON.stringify({
email: __ENV.TEST_EMAIL,
password: __ENV.TEST_PASSWORD,
}), {
headers: { 'Content-Type': 'application/json' },
});
check(loginRes, { 'login successful': (r) => r.status === 200 });
const { accessToken } = loginRes.json();
return { accessToken };
}
export default function (data) {
const { accessToken } = data;
const headers = {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
};
group('Contacts API', () => {
// List contacts
const listRes = http.get(`${BASE_URL}/contacts?page=1&limit=20`, {
headers,
tags: { type: 'api', endpoint: 'contacts-list' },
});
check(listRes, {
'list contacts: 200': (r) => r.status === 200,
'list contacts: has items': (r) => r.json('data') !== null,
});
apiCalls.add(1);
sleep(0.5);
// Create a contact
const createRes = http.post(`${BASE_URL}/contacts`, JSON.stringify({
name: `Load Test User ${Date.now()}`,
email: `load-test-${Date.now()}@example.com`,
}), {
headers,
tags: { type: 'api', endpoint: 'contacts-create' },
});
check(createRes, {
'create contact: 201': (r) => r.status === 201,
});
apiCalls.add(1);
});
sleep(1);
}
// teardown() runs once after all VUs finish
export function teardown(data) {
// Clean up test data if needed
console.log(`Test complete. Data: ${JSON.stringify(data)}`);
}
ریمپنگ VU منظرنامے۔
متعدد مراحل اور منظرناموں کے ساتھ حقیقی ٹریفک کے نمونوں کو ماڈل کریں:
// k6/stress-test.js
export const options = {
scenarios: {
// Scenario 1: Normal traffic baseline
normal_traffic: {
executor: 'ramping-vus',
startVUs: 0,
stages: [
{ duration: '2m', target: 20 },
{ duration: '5m', target: 20 },
],
gracefulRampDown: '30s',
},
// Scenario 2: Sudden spike (marketing campaign goes live)
traffic_spike: {
executor: 'ramping-vus',
startVUs: 0,
startTime: '7m', // Starts after baseline is stable
stages: [
{ duration: '30s', target: 200 }, // Rapid spike
{ duration: '2m', target: 200 }, // Hold spike
{ duration: '30s', target: 20 }, // Fall back
],
},
// Scenario 3: Soak test for memory leaks
soak_test: {
executor: 'constant-vus',
vus: 10,
duration: '30m', // Run for 30 minutes
startTime: '10m',
},
},
thresholds: {
'http_req_duration{scenario:normal_traffic}': ['p(95)<300'],
'http_req_duration{scenario:traffic_spike}': ['p(95)<800'],
http_req_failed: ['rate<0.02'],
},
};
بلاگ/سائٹ میپ کرال ٹیسٹ
// k6/sitemap-crawl.js
import http from 'k6/http';
import { check, sleep } from 'k6';
import { SharedArray } from 'k6/data';
// Load URLs from sitemap (pre-fetched and saved as JSON)
const urls = new SharedArray('sitemap urls', function () {
// In real usage, fetch sitemap XML and parse URLs beforehand
// SharedArray is loaded once and shared across all VUs (memory efficient)
return JSON.parse(open('./sitemap-urls.json'));
});
export const options = {
vus: 20,
duration: '5m',
thresholds: {
http_req_duration: ['p(95)<2000'], // Public pages can be slower
http_req_failed: ['rate<0.01'],
},
};
export default function () {
// Each VU picks a random URL from the sitemap
const url = urls[Math.floor(Math.random() * urls.length)];
const res = http.get(url, {
headers: {
// Identify as load tester in logs
'User-Agent': 'k6-load-tester/1.0',
},
timeout: '10s',
});
check(res, {
'status is 200': (r) => r.status === 200,
'no error page': (r) => !r.body.includes('Error'),
'has canonical tag': (r) => r.body.includes('rel="canonical"'),
'response time < 2000ms': (r) => r.timings.duration < 2000,
});
sleep(Math.random() * 2 + 1); // Random 1-3 second think time
}
حسب ضرورت میٹرکس اور حد
// k6/checkout-load.js
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Counter, Rate, Trend, Gauge } from 'k6/metrics';
// Custom metrics for business-specific tracking
const checkoutSuccesses = new Counter('checkout_successes');
const checkoutFailures = new Counter('checkout_failures');
const checkoutDuration = new Trend('checkout_duration');
const activeCheckouts = new Gauge('active_checkouts');
export const options = {
stages: [
{ duration: '1m', target: 10 },
{ duration: '3m', target: 30 },
{ duration: '1m', target: 0 },
],
thresholds: {
checkout_duration: ['p(95)<3000'], // Checkout < 3s at p95
checkout_failures: ['count<10'], // Max 10 absolute failures
http_req_duration: ['p(99)<2000'],
},
};
export default function (data) {
activeCheckouts.add(1);
const start = Date.now();
// Step 1: Add to cart
const cartRes = http.post('/api/cart/add', JSON.stringify({
productId: 'prod_odoo_customization',
quantity: 1,
}), { headers: { 'Content-Type': 'application/json' } });
if (!check(cartRes, { 'add to cart: 200': (r) => r.status === 200 })) {
checkoutFailures.add(1);
activeCheckouts.add(-1);
return;
}
sleep(2);
// Step 2: Create checkout session
const checkoutRes = http.post('/api/billing/checkout', JSON.stringify({
cartId: cartRes.json('cartId'),
}), { headers: { 'Content-Type': 'application/json' } });
const success = check(checkoutRes, {
'checkout session created': (r) => r.status === 200,
'has session URL': (r) => r.json('url') !== null,
});
if (success) {
checkoutSuccesses.add(1);
checkoutDuration.add(Date.now() - start);
} else {
checkoutFailures.add(1);
}
activeCheckouts.add(-1);
sleep(1);
}
گرافانا آؤٹ پٹ انٹیگریشن
K6 میٹرکس کو InfluxDB پر سٹریم کریں اور ٹیسٹ کے دوران گرافانا میں تصور کریں:
# Run with InfluxDB output
k6 run --out influxdb=http://localhost:8086/k6 k6/api-load.js
# Or use the k6 Grafana integration (k6 v0.45+)
k6 run --out experimental-prometheus-rw k6/api-load.js
# docker-compose.monitoring.yml
services:
influxdb:
image: influxdb:2.7
ports: ["8086:8086"]
environment:
INFLUXDB_DB: k6
INFLUXDB_ADMIN_USER: admin
INFLUXDB_ADMIN_PASSWORD: password
grafana:
image: grafana/grafana:latest
ports: ["3030:3000"]
environment:
GF_AUTH_ANONYMOUS_ENABLED: "true"
volumes:
- ./grafana/dashboards:/etc/grafana/provisioning/dashboards
- ./grafana/datasources:/etc/grafana/provisioning/datasources
CI انٹیگریشن
# .github/workflows/ci.yml (load test section)
load-tests:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' # Only on main branch
needs: [deploy-staging]
steps:
- uses: actions/checkout@v4
- name: Install k6
run: |
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg \
--keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" \
| sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update && sudo apt-get install k6
- name: Run smoke test (30 VUs, 60s)
run: |
k6 run --vus 30 --duration 60s \
--env BASE_URL=${{ secrets.STAGING_URL }} \
--env TEST_EMAIL=${{ secrets.TEST_EMAIL }} \
--env TEST_PASSWORD=${{ secrets.TEST_PASSWORD }} \
apps/api/k6/api-load.js
- name: Upload k6 results
uses: actions/upload-artifact@v4
if: always()
with:
name: k6-results
path: k6-results/
کارکردگی کی بنیادیں۔
رجعت پر بنیادی خطوط اور الرٹ قائم کریں:
| اختتامی نقطہ | p50 | p95 | p99 | خرابی بجٹ |
|---|---|---|---|---|
GET / (ہوم پیج) | 120ms | 400ms | 800ms | 0.1% |
GET /api/contacts | 50ms | 150ms | 300ms | 0.5% |
POST /api/contacts | 80ms | 200ms | 400ms | 0.5% |
POST /auth/login | 200ms | 500ms | 1000ms | 1% |
POST /billing/checkout | 500ms | 1500ms | 3000ms | 1% |
GET /blog/[slug] | 100ms | 300ms | 600ms | 0.1% |
اکثر پوچھے گئے سوالات
VUs اور درخواستوں فی سیکنڈ میں کیا فرق ہے؟
VUs (ورچوئل یوزرز) ہم وقت سازی والے صارف ہیں۔ ہر VU آپ کا ڈیفالٹ فنکشن ایک لوپ میں چلاتا ہے۔ فی سیکنڈ کی درخواستوں کا انحصار اس بات پر ہے کہ ہر تکرار کتنی تیزی سے چلتی ہے۔ اگر ہر VU تکرار میں 2 سیکنڈ لگتے ہیں (بشمول نیند کا وقت) اور آپ کے پاس 100 VUs ہیں، تو آپ کو تقریباً 50 RPS ملتے ہیں۔ constant-arrival-rate executor کا استعمال کریں جب آپ کو کسی مخصوص RPS کو ٹارگٹ کرنے کی ضرورت ہو قطع نظر اس کے کہ تکرار کی مدت ہو۔
کیا مجھے پروڈکشن یا سٹیجنگ کے خلاف ٹیسٹ لوڈ کرنا چاہیے؟
ہمیشہ اسٹیجنگ کو ترجیح دیں۔ پروڈکشن لوڈ ٹیسٹ سے حقیقی صارفین پر اثر انداز ہونے، شرح کی حد کو ختم کرنے، ٹیسٹ ڈیٹا سے حقیقی آرڈرز بنانے اور حقیقی ویب ہک ایونٹس کو متحرک کرنے کا خطرہ ہوتا ہے۔ اگر آپ کو پروڈکشن کی جانچ کرنی ہے، تو اسے کم ٹریفک والی ونڈوز کے دوران کریں، ٹیسٹ پیمنٹ ٹوکن استعمال کریں، اور رول بیک پلان رکھیں۔ k6 کلاؤڈ جیو ڈسٹری بیوٹڈ لوڈ جنریشن کو سپورٹ کرتا ہے تاکہ آپ اصلیت کو چھوئے بغیر اپنے CDN ایج کی کارکردگی کو جانچ سکیں۔
میں طویل ٹیسٹوں کے دوران auth token کی میعاد ختم ہونے کو کیسے ہینڈل کروں؟
مختصر ٹیسٹوں کے لیے (15 منٹ سے کم)، setup() میں ایک ٹوکن حاصل کریں اور اسے data کے ذریعے تمام VUs کو منتقل کریں۔ لمبے ٹیسٹوں کے لیے (15 منٹ سے زیادہ)، ٹیسٹ اسکرپٹ میں ٹوکن ریفریش کو لاگو کریں: ڈیفالٹ فنکشن میں ٹوکن کی عمر کو چیک کریں اور جب اس کی میعاد ختم ہو جائے تو ریفریش کریں۔ ٹوکن کو JavaScript متغیر میں ہر VU کے لیے مقامی طور پر اسٹور کریں۔
stages اور scenarios میں کیا فرق ہے؟
stages ایک واحد ramping-vus منظر نامے کے لیے ایک شارٹ ہینڈ ہے — سادہ ریمپ اپ/ہولڈ/ریمپ-ڈاؤن پیٹرن کے لیے اچھا ہے۔ scenarios آپ کو مکمل کنٹرول فراہم کرتا ہے: متعدد بیک وقت ٹریفک کے پیٹرن، مختلف ایگزیکیوٹرز فی منظر، فی منظر کی حد، اور میٹرکس میں منظر نامے کی ٹیگنگ۔ حقیقت پسندانہ ملٹی پیٹرن ٹیسٹنگ کے لیے scenarios استعمال کریں (بیس لائن + اسپائک + سوک بیک وقت)۔
ایک واحد k6 پراسیس کتنے VUs کو سنبھال سکتا ہے؟
جدید ہارڈ ویئر پر ایک واحد k6 عمل 5,000-10,000 VUs کو برقرار رکھ سکتا ہے اور اسکرپٹ کی پیچیدگی اور رسپانس سائز کے لحاظ سے 50,000-100,000 RPS پیدا کر سکتا ہے۔ زیادہ بوجھ کے لیے، k6 cloud استعمال کریں یا لوڈ ڈسٹری بیوٹر کے پیچھے متعدد k6 مثالیں چلائیں۔ ہر VU انتہائی ہلکا ہوتا ہے (ایک گوروٹین) — k6 مساوی VU شمار کے لیے JMeter یا Gatling کے مقابلے میں بہت کم وسائل استعمال کرتا ہے۔
اگلے اقدامات
لوڈ ٹیسٹنگ آپ کی ایپلیکیشن کی حقیقی کارکردگی کے پروفائل کو ظاہر کرتی ہے اس سے پہلے کہ صارفین اسے دباؤ میں دریافت کریں۔ اس گائیڈ کے پیٹرن — ریمپنگ منظرنامے، حسب ضرورت حد، CI انضمام، اور گرافانا ڈیش بورڈز — آپ کو کارکردگی کی رکاوٹوں کو تلاش کرنے اور ان کو مستقل طور پر دور کرنے کے لیے بنیادی ڈھانچہ فراہم کرتے ہیں۔
ECOSIRE ہوم پیج، API اینڈ پوائنٹس، چیک آؤٹ فلو، اور مکمل سائٹ میپ کرالز کو کور کرنے والے k6 لوڈ ٹیسٹ کے ساتھ کارکردگی کی توثیق شدہ NestJS APIs بناتا ہے۔ ہماری بیک اینڈ انجینئرنگ سروسز کو دریافت کریں یہ جاننے کے لیے کہ ہم پہلے دن سے کارکردگی کے لیے کیسے تعمیر کرتے ہیں۔
تحریر
ECOSIRE TeamTechnical Writing
The ECOSIRE technical writing team covers Odoo ERP, Shopify eCommerce, AI agents, Power BI analytics, GoHighLevel automation, and enterprise software best practices. Our guides help businesses make informed technology decisions.
ECOSIRE
ECOSIRE کے ساتھ اپنا کاروبار بڑھائیں
ERP، ای کامرس، AI، تجزیات، اور آٹومیشن میں انٹرپرائز حل۔
متعلقہ مضامین
Shopify Speed Optimization: A Technical Checklist That Actually Moves Core Web Vitals (2026)
A field-tested Shopify speed checklist for 2026 — what actually improves LCP, INP, and CLS on real stores, what wastes time, and how to audit apps and themes.
Odoo 19 HR: Skills Matrix, Career Plans, Performance Cycles
Odoo 19 HR upgrade: native skills matrix, career path planning, performance review cycles, 9-box grid, succession planning, HRIS integration.
Odoo 19 Performance Benchmarks: PostgreSQL 17 Tuning Numbers
Real-world Odoo 19 performance benchmarks: web client speed, ORM throughput, PG17 tuning settings, connection pooling, worker counts, scaling thresholds.
Performance & Scalability سے مزید
Shopify Speed Optimization: A Technical Checklist That Actually Moves Core Web Vitals (2026)
A field-tested Shopify speed checklist for 2026 — what actually improves LCP, INP, and CLS on real stores, what wastes time, and how to audit apps and themes.
Technical SEO Audit Checklist 2026: 47 Checks We Run on Every Client Site
The 47-point technical SEO audit checklist we run on every client site in 2026 — crawlability, indexation, canonicals, hreflang, Core Web Vitals, and logs.
Odoo 19 HR: Skills Matrix, Career Plans, Performance Cycles
Odoo 19 HR upgrade: native skills matrix, career path planning, performance review cycles, 9-box grid, succession planning, HRIS integration.
Odoo 19 Performance Benchmarks: PostgreSQL 17 Tuning Numbers
Real-world Odoo 19 performance benchmarks: web client speed, ORM throughput, PG17 tuning settings, connection pooling, worker counts, scaling thresholds.
OpenClaw Cost Optimization and Token Efficiency at Scale
OpenClaw token cost optimization: prompt caching, model routing, response caching, batch APIs, and per-tenant cost guardrails for production agents.
Power BI Incremental Refresh for Tables Over 10 Million Rows
Power BI Incremental Refresh playbook for 10M+ row tables: partition design, RangeStart/RangeEnd, refresh policies, query folding, and DirectQuery hybrids.