Performance Test ที่ดี เริ่มจากวางแผน
ไม่ใช่แค่กดรัน Script
ทีมส่วนใหญ่เริ่ม Performance Test ด้วยการเปิด JMeter แล้วกด Start ทันที ผลที่ได้คือตัวเลขที่ไม่มี Baseline เปรียบเทียบ ไม่มี Acceptance Criteria และ Report ที่ Dev Team ไม่รู้จะทำอะไรต่อ บทความนี้ครอบคลุม 7 ขั้นตอน ตั้งแต่กำหนด Objective ไปจนถึงการเขียน Report ที่ Stakeholder อ่านแล้วตัดสินใจได้ทันที
7 ขั้นตอนการทำ Performance Testing
| API Type | p95 | p99 | Error Rate |
|---|---|---|---|
| Read (GET) | < 500ms | < 1s | < 0.1% |
| Write (POST/PUT) | < 1s | < 2s | < 0.5% |
| Search / Query | < 2s | < 3s | < 1% |
| Payment / Critical | < 3s | < 5s | < 0.1% |
| Report / Bulk Export | < 10s | < 30s | < 1% |
| Ratio (Test : Prod) | ตัวอย่าง Test Env | วิธีแปลผล | เหมาะกับ |
|---|---|---|---|
| 1:1 | Spec เท่ากันทุกอย่าง | ผลตรงตาม Production ได้เลย | Critical System, ก่อน Go-live |
| 1:2 | CPU/RAM ครึ่งนึง | Throughput จริงประมาณ 2× ที่วัดได้ | ทั่วไป, งบปานกลาง |
| 1:4 | 1 node แทน 4 nodes | Throughput จริงประมาณ 4× ที่วัดได้ | Early-stage, Regression Test |
| 1:8 | Dev machine / Sandbox | ใช้ดู Trend เท่านั้น ตัวเลขไม่ตรง | Smoke Test, Script Validation |
Workload Modeling — Transaction Mix ตัวอย่าง
| User Journey | % ของ Traffic | Think Time | หมายเหตุ |
|---|---|---|---|
| Browse Products | 40% | 2–4s | READ-heavy, cache ได้ |
| Search | 25% | 3–5s | DB-intensive |
| Login / Auth | 15% | 1–2s | Session management critical |
| Add to Cart | 12% | 1–3s | WRITE operation |
| Checkout | 8% | 5–10s | Critical Path — ต้องผ่าน SLA เสมอ |
Business Volume → Load Calculation
ก่อนกำหนดจำนวน VU หรือ TPS ควรรู้ก่อนว่า Business ทำธุรกรรมกี่รายการต่อวัน (TPD) หรือต่อชั่วโมง (TPH) และ Peak Hour อยู่ช่วงไหน
Peak TPS = Average TPS × Peak Factor (2–5×)
Design Target = Peak TPS × Safety Buffer (1.2–1.5×)
| Business Volume | Working Hours | Average TPS | Peak Factor | Peak TPS |
|---|---|---|---|---|
| 100,000 orders/day | 8 ชม. (28,800s) | 3.5 TPS | 3× | ~10 TPS |
| 1,000,000 pageviews/day | 16 ชม. (57,600s) | 17.4 RPS | 4× | ~70 RPS |
| 50,000 API calls/day | 24 ชม. (86,400s) | 0.6 TPS | 5× | ~3 TPS |
Peak Factor อ้างอิงจาก Access Log จริง — ถ้าไม่มีข้อมูลให้ใช้ 3× เป็น Default สำหรับ Web Application ทั่วไป
เมื่อรู้ Ratio ของ Environment แล้ว ต้องลด Target Load ให้สอดคล้องกับ Resource ที่มี ไม่ใช่รัน Full Production Load บน Environment ที่เล็กกว่า เพราะจะ Saturate ตั้งแต่ต้น ทำให้ผลที่ได้ไม่มีความหมาย
ตัวอย่าง: Production Target = 200 TPS, Ratio = 1:4
→ Test Target = 200 ÷ 4 = 50 TPS
| Production Target | Environment Ratio | Test Target TPS | ถ้า Test ผ่าน หมายความว่า |
|---|---|---|---|
| 200 TPS | 1:1 | 200 TPS | Production รองรับได้ 200 TPS จริง |
| 200 TPS | 1:2 | 100 TPS | Production รองรับได้ประมาณ 200 TPS |
| 200 TPS | 1:4 | 50 TPS | Production รองรับได้ประมาณ 200 TPS |
| 200 TPS | 1:8 | 25 TPS | ใช้ดู Trend / Bottleneck เท่านั้น |
รัน 200 TPS บน 1:4 Environment → ระบบ Saturate ทันที → Response Time พุ่ง → สรุปผิดว่าระบบรองรับได้แค่ 200 TPS แต่จริงๆ คือ Environment เล็กเกินไปสำหรับ Load นั้น
Environment Ratio & Setup Checklist
Ratio คืออัตราส่วน Resource ระหว่าง Test Environment กับ Production ต้องครอบคลุมทุก Layer ให้สม่ำเสมอ มิฉะนั้นผลจะ skewed
| Layer | Production | Test Env (1:4) | หมายเหตุ |
|---|---|---|---|
| App Server | 4 nodes × 8C/16GB | 1 node × 8C/16GB | ลด node ลง 4 เท่า |
| Database | Primary + 2 Replica | Primary + 1 Replica | ควรรักษา Replica ไว้ |
| Cache (Redis) | 3-node Cluster 32GB | 1-node 8GB | ลด Memory ให้ได้สัดส่วน |
| Network | 10 Gbps | 2.5 Gbps | Bandwidth ต้องลดตามสัดส่วน |
ถ้า App Server เป็น 1:4 แต่ DB เป็น 1:1 (เต็ม Production) — DB จะไม่ใช่ Bottleneck ใน Test แต่อาจเป็นปัญหาจริงใน Production
- ☑ Grafana + Prometheus หรือ DataDog
- ☑ CPU, Memory, Network, Disk Metrics
- ☑ DB Slow Query Log เปิดอยู่
- ☑ APM Tool (New Relic, Dynatrace)
- ☑ บันทึก Environment Ratio ไว้ใน Test Plan
- ☑ Test Client อยู่ใกล้ Server (Low Latency)
- ☑ Network Bandwidth เพียงพอ
- ☑ ปิด Background Process ที่ไม่จำเป็น
- ☑ Test Data พร้อมและถูกต้อง
- ☑ Script Validation ผ่านแล้ว (1 User)
Connection Pool — ตั้งค่าก่อนรัน Test
Connection Pool ที่ตั้งค่าผิดคือ Root Cause อันดับต้นๆ ของ Error Rate พุ่งและ Response Time สูงตอน Peak Load ตรวจและปรับค่าเหล่านี้ก่อนรัน Test ทุกครั้ง
| Setting | ค่าที่แนะนำ | ผลถ้าตั้งผิด |
|---|---|---|
| Max Pool Size | 20–100 (ขึ้นกับ DB) | น้อยเกิน → Queue + Timeout |
| Min Pool Size | 5–10 | น้อยเกิน → Lag ตอน Cold Start |
| Connection Timeout | 3–10 วินาที | น้อยเกิน → Error Rate สูง |
| Idle Timeout | 30–60 วินาที | สั้นเกิน → Reconnect บ่อย |
| Max Overflow | 10–20 | เผื่อ Burst Traffic ชั่วคราว |
ตัวอย่าง: 50 TPS × 0.05s avg query ÷ 2 instances = 1.25 → ตั้ง min 10, max 30
Pre-test Checklist
ผ่าน Checklist นี้ก่อนทุก Test Run เพื่อหลีกเลี่ยง False Result
- ☐ ไม่มี Scheduled Job รันในช่วง Test
- ☐ DB ไม่มี Maintenance Task
- ☐ ไม่มี Deploy ใหม่ในช่วง Test
- ☐ Cache Clear แล้ว (ถ้าต้องการ Cold Start)
- ☐ Connection Pool Settings ถูกต้อง
- ☐ Test Script ผ่าน Dry Run (1 User) แล้ว
- ☐ Assertions ครบทุก Endpoint
- ☐ Test Data พอสำหรับ Virtual Users ทั้งหมด
- ☐ Think Time ตั้งค่าสมจริง
- ☐ Ramp-up Period กำหนดแล้ว
Best Practices
Anti-patterns — สิ่งที่ควรหลีกเลี่ยง
Performance Testing ก่อน Go-live 1 วันสายเกินไปแล้ว หากพบ Bottleneck ใหญ่ จะไม่มีเวลาแก้ไข ควรเริ่มตั้งแต่ Sprint แรก
ห้ามใช้ข้อมูลจริงของ User (PII) ใน Performance Test ทั้ง PDPA และ Security Risk สูงมาก ให้ใช้ Synthetic Data แทน
Script ที่ไม่มี Think Time จะสร้าง Load เกินจริงมาก User จริงไม่ได้ส่ง Request ไปเรื่อยๆ โดยไม่หยุด ใส่ Think Time 1–5 วินาทีให้ใกล้เคียงพฤติกรรมจริง
Average ซ่อน Outlier ที่น่ากังวลมาก ต้องดู p95 และ p99 เสมอ เพื่อให้รู้ว่า User ในกลุ่มสุดท้ายประสบการณ์เป็นอย่างไร
Test Plan Document — โครงสร้างที่ควรมี
ก่อนเริ่ม Test ควรมีเอกสารที่ Dev, QA, DevOps และ Stakeholder เห็นด้วยกัน — ลดการ Re-test และข้อถกเถียงตอนสรุปผล
- Scope — ระบบอะไร, API ไหน, User Journey ที่ Test
- Objectives — ทำไมต้อง Test ตอนนี้
- Test Types — Load / Stress / Spike / Soak
- Out of Scope — สิ่งที่ไม่ Test และเหตุผล
- Business Volume — TPH, Working Hours, Peak Factor
- Workload Model — Transaction Mix, Think Time
- API SLA — p95/p99 Target, Error Rate Threshold
- Acceptance Criteria — Pass/Fail Definition ที่ชัดเจน
- Environment Spec — Server, DB, Network Config
- Connection Settings — Pool Size, Timeout
- Monitoring Setup — Tool, Dashboard, Alert Threshold
- Test Data — ปริมาณ, วิธีสร้าง, Data Masking
- Test Schedule — วันที่, Timeline, ลำดับ Test
- Entry Criteria — เงื่อนไขก่อนเริ่ม Test
- Exit Criteria — เงื่อนไขหยุด/ผ่าน Test
- Roles & Responsibilities — ใครทำอะไร
- Risks & Assumptions — สิ่งที่อาจทำให้ผลคลาดเคลื่อน
JMeter Test Report ระดับ Enterprise — โครงสร้าง Excel
Enterprise Test Report ใน Excel แบ่งเป็น 8 Sheets แต่ละ Sheet ตอบคำถามคนละกลุ่ม — Management เปิด Sheet 1, Dev เปิด Sheet 3, DevOps เปิด Sheet 4
| Sheet | ชื่อ | สำหรับใคร | สิ่งสำคัญ |
|---|---|---|---|
| 1 | Executive Summary | Management | Overall PASS/FAIL, Key Findings, Go / No-Go |
| 2 | SLA Compliance | Stakeholders + QA | p95/p99 vs Target ทุก API |
| 3 | Summary Results | Dev Team | Avg / p90 / p95 / p99 / Error% / TPS ทุก Endpoint |
| 4 | Resource Utilization | DevOps + DBA | CPU / Memory / DB Connections Timeline |
| 5 | Error Analysis | Dev + QA | Error Type, Count, Root Cause |
| 6 | Timeline & Graphs | ทุกคน | TPS vs Response Time vs Error Rate Chart |
| 7 | Baseline Comparison | Dev + QA | Delta เทียบกับ Test Run ครั้งก่อน |
| 8 | Test Configuration | ทุกคน | Environment Spec, JMeter Settings, Test Parameters |
หน้าแรกที่ Management เปิดดู ต้องเห็น Overall Result ทันทีโดยไม่ต้องอ่านทั้งหมด
- 🔴/🟢 Overall Result — PASS / FAIL (ตัวใหญ่ มองเห็นชัด)
- 📅 Project, Environment, Test Date, Tester Name
- 📊 Key Metrics: Total Requests, Error Rate, p95 RT, Peak TPS
- ✅ Acceptance Criteria vs Actual — ตาราง Pass/Fail ต่อ KPI
- ⚠️ Top Issues Found (3–5 รายการ) พร้อม Priority
- 💡 Recommendation — Go Live / Hold / Re-test
ตาราง PASS/FAIL ต่อ API — ใช้ Conditional Formatting สีแดง/เขียวอัตโนมัติ
| API / Transaction | p95 SLA | p95 Actual | p99 SLA | p99 Actual | Error% | Status |
|---|---|---|---|---|---|---|
| GET /products | 500ms | 320ms | 1s | 680ms | 0.0% | PASS |
| POST /checkout | 3s | 2.1s | 5s | 4.8s | 0.3% | PASS |
| GET /search | 2s | 3.4s | 3s | 5.2s | 1.2% | FAIL |
Export จาก JMeter Aggregate Report — เพิ่มคอลัมน์ Status และ SLA Target เพื่อให้อ่านง่ายขึ้น
| Label | Samples | Avg | p90 | p95 | p99 | Min | Max | Error% | TPS | Status |
|---|---|---|---|---|---|---|---|---|---|---|
| TOTAL | 45,230 | 342ms | 780ms | 1.2s | 2.8s | 12ms | 12.4s | 0.4% | 42.3 | — |
| Login | 6,800 | 215ms | 480ms | 620ms | 1.1s | 18ms | 3.2s | 0.1% | 6.3 | ✅ PASS |
| Browse Products | 18,100 | 298ms | 520ms | 680ms | 1.4s | 12ms | 4.1s | 0.0% | 16.8 | ✅ PASS |
| Search | 11,300 | 1,810ms | 3,100ms | 3,400ms | 5,200ms | 340ms | 12.4s | 1.2% | 10.5 | ❌ FAIL |
| Checkout | 3,630 | 1,920ms | 2,800ms | 3,100ms | 4,600ms | 210ms | 8.2s | 0.3% | 3.4 | ✅ PASS |
Timeline ของ Server Resources — ดูว่า Bottleneck เกิดจาก CPU / Memory / DB Connections
| Time | App CPU% | App Mem | DB CPU% | DB Conn | Net MB/s |
|---|---|---|---|---|---|
| 10:00 | 35% | 2.1 GB | 22% | 18/100 | 12 |
| 10:10 | 68% | 2.4 GB | 45% | 52/100 | 28 |
| 10:20 | 91% | 2.9 GB | 82% | 98/100 | 41 |
| 10:30 | 74% | 2.7 GB | 61% | 74/100 | 33 |
สีแดง = เกิน Threshold (CPU >80%, DB Conn >90%)
อย่า Report แค่ Error Rate % — ต้องระบุ Root Cause ให้ Dev แก้ได้ทันที
| Error Type | Code | Count | % | Root Cause |
|---|---|---|---|---|
| Connection Timeout | 503 | 312 | 0.69% | DB Pool หมด (98/100 conn) |
| Slow Response > SLA | 200 | 228 | 0.50% | Missing Index — table products |
| Auth Failed | 401 | 5 | 0.01% | Test Data ซ้ำ / Token หมดอายุ |
เปรียบเทียบกับ Test Run ครั้งก่อน — จับ Regression ก่อน Release
| Metric | Baseline | This Run | Delta | Trend |
|---|---|---|---|---|
| p95 Response Time | 1.1s | 1.2s | +9% | ⬆ ช้าลง |
| Peak TPS | 38.5 | 42.3 | +10% | ⬆ ดีขึ้น |
| Error Rate | 0.2% | 0.4% | +0.2% | ⬆ แย่ลง |
| Peak CPU | 78% | 91% | +13% | ⬆ แย่ลง |
- Tool: Apache JMeter 5.6.2
- Test Types: Load Test + Stress Test
- Load Profile: Ramp 0→500 VU ใน 10 นาที, Hold 30 นาที
- Target TPS: 50 TPS (จาก 180,000 TPH Business Volume)
- Environment: Staging — 2 App Nodes (8C/16GB), PostgreSQL 16
- Monitoring: Grafana + Prometheus + DB Slow Query Log
- Test Data: 10,000 synthetic users, 50,000 products