Can you deliver 1000+ events/sec? Optimize: batch database inserts, run multiple workers, profile bottlenecks, and load test. By the end, you'll have a high-throughput system with measured performance.
← Back to Module 06 overviewk6 or Locust: measure throughput, p50, p95, p99./docs/perf.Update src/routes/events.ts:
// Instead of one-by-one inserts:
const batchDeliveries = webhooksResult.rows.map(webhook => {
const deliveryId = crypto.randomUUID();
return [deliveryId, webhook.id, eventRow.id, 'pending'];
});
// Batch insert
if (batchDeliveries.length > 0) {
const values = batchDeliveries.map((_, i) =>
`($${i*4+1}, $${i*4+2}, $${i*4+3}, $${i*4+4})`
).join(',');
const flatValues = batchDeliveries.flat();
await pool.query(
`INSERT INTO deliveries (id, webhook_id, event_id, status) VALUES ${values}`,
flatValues
);
}
// Batch enqueue jobs
const jobs = webhooksResult.rows.map(webhook => ({
delivery_id: generateId(),
webhook_id: webhook.id,
event_id: eventRow.id,
webhook_url: webhook.url,
webhook_secret: webhook.secret,
payload: payload,
attempt: 0
}));
await deliveryQueue.addBulk(jobs.map(job => ({ data: job })));
Create src/workers.ts to manage multiple workers:
import './worker/deliveryWorker';
const NUM_WORKERS = parseInt(process.env.NUM_WORKERS || '1');
console.log(`Starting ${NUM_WORKERS} delivery workers...`);
for (let i = 0; i < NUM_WORKERS; i++) {
console.log(`Worker ${i+1} started`);
}
Or use a process manager like concurrently:
npm install --save-dev concurrently
"scripts": {
"worker:multi": "concurrently 'npm run worker' 'npm run worker' 'npm run worker'"
}
npm run worker:multi and see 3 workers start.npm install --save-dev k6
Create load-test.js:
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '10s', target: 100 }, // Ramp to 100 concurrent requests
{ duration: '30s', target: 100 }, // Stay at 100
{ duration: '10s', target: 0 }, // Ramp down
],
thresholds: {
http_req_duration: ['p(95)<500'], // 95th percentile under 500ms
},
};
// Create 100 webhooks first
const webhooks = [];
for (let i = 0; i < 100; i++) {
const res = http.post('http://localhost:3000/webhooks', JSON.stringify({
url: `https://webhook${i}.example.com/hook`,
secret: 'secret',
event_types: ['order.created']
}), { headers: { 'Content-Type': 'application/json' } });
webhooks.push(JSON.parse(res.body));
}
export default function () {
const payload = JSON.stringify({
type: 'order.created',
payload: { order_id: Math.random() * 100000 }
});
const res = http.post('http://localhost:3000/events', payload, {
headers: { 'Content-Type': 'application/json' },
});
check(res, {
'status is 201': (r) => r.status === 201,
'response time < 500ms': (r) => r.timings.duration < 500,
});
sleep(0.1);
}
k6 run load-test.js completes with results.Add timing logs to src/routes/events.ts:
const t1 = Date.now();
// Webhook lookup
const webhooksResult = await pool.query(...);
const t2 = Date.now();
// Batch insert deliveries
await pool.query(...);
const t3 = Date.now();
// Enqueue jobs
await deliveryQueue.addBulk(...);
const t4 = Date.now();
console.log(`[PERF] webhook_lookup=${t2-t1}ms, batch_insert=${t3-t2}ms, enqueue=${t4-t3}ms`);
Run load test and check logs to identify slowest operation.
Run load test with 1, 2, 3 workers:
NUM_WORKERS=1 npm run dev & npm run worker # Wait for load test to complete # Record results NUM_WORKERS=2 npm run dev & npm run worker:multi # Run same load test # Record results and compare
Create docs/perf/load-test-report.md:
# Load Test Report ## Test Setup - Webhooks: 100 - Events: 5000 total (100 VUs × 50 requests each) - Duration: 50 seconds - Workers: 1, 2, 3 ## Results | Workers | Throughput (req/s) | p50 (ms) | p95 (ms) | p99 (ms) | |---------|-------------------|----------|----------|----------| | 1 | 98 req/s | 450 | 850 | 1200 | | 2 | 195 req/s | 430 | 780 | 1050 | | 3 | 287 req/s | 410 | 720 | 950 | ## Conclusion Throughput scales near-linearly with worker count. Each worker handles ~100 req/s on this hardware.
git add -A git commit -m "perf: optimize delivery throughput with batching and workers - Batch enqueue delivery jobs (not one-by-one) - Support multiple worker processes - k6 load test: 1000+ events/sec with 100 webhooks - Performance report with scaling metrics - 2-3 workers scale throughput near-linearly" git push origin main
git log --oneline shows your commit.You now have a fast, scalable system. Next, you'll instrument it: logs, metrics, traces, and dashboards. Head to Module 07.