or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdload-balancing.mdperformance-monitoring.mdpool-management.mdtask-cancellation.mdtask-queues.mdtransferable-objects.md

performance-monitoring.mddocs/

0

# Performance Monitoring

1

2

Built-in performance metrics collection with detailed histogram statistics for runtime and wait times, including percentile calculations.

3

4

## Capabilities

5

6

### PiscinaHistogram Interface

7

8

Main interface for accessing performance metrics from the pool.

9

10

```typescript { .api }

11

/**

12

* Main histogram interface providing runtime and wait time statistics

13

*/

14

interface PiscinaHistogram {

15

/** Runtime statistics for task execution */

16

readonly runTime: PiscinaHistogramSummary;

17

18

/** Wait time statistics for task queuing */

19

readonly waitTime: PiscinaHistogramSummary;

20

21

/**

22

* Reset runtime histogram data

23

*/

24

resetRunTime(): void;

25

26

/**

27

* Reset wait time histogram data

28

*/

29

resetWaitTime(): void;

30

}

31

```

32

33

### PiscinaHistogramSummary Interface

34

35

Detailed statistical summary with percentile calculations.

36

37

```typescript { .api }

38

/**

39

* Comprehensive statistical summary of timing data

40

* All values are in milliseconds

41

*/

42

interface PiscinaHistogramSummary {

43

/** Average/mean execution time in milliseconds */

44

readonly average: number;

45

46

/** Mean execution time in milliseconds (same as average) */

47

readonly mean: number;

48

49

/** Standard deviation of execution times */

50

readonly stddev: number;

51

52

/** Minimum recorded execution time */

53

readonly min: number;

54

55

/** Maximum recorded execution time */

56

readonly max: number;

57

58

// Percentile values (all in milliseconds)

59

/** 0.1st percentile (1 in 1000 tasks faster) */

60

readonly p0_001: number;

61

62

/** 1st percentile (1 in 100 tasks faster) */

63

readonly p0_01: number;

64

65

/** 10th percentile (1 in 10 tasks faster) */

66

readonly p0_1: number;

67

68

/** 1st percentile */

69

readonly p1: number;

70

71

/** 2.5th percentile */

72

readonly p2_5: number;

73

74

/** 10th percentile */

75

readonly p10: number;

76

77

/** 25th percentile (first quartile) */

78

readonly p25: number;

79

80

/** 50th percentile (median) */

81

readonly p50: number;

82

83

/** 75th percentile (third quartile) */

84

readonly p75: number;

85

86

/** 90th percentile */

87

readonly p90: number;

88

89

/** 97.5th percentile */

90

readonly p97_5: number;

91

92

/** 99th percentile */

93

readonly p99: number;

94

95

/** 99.9th percentile */

96

readonly p99_9: number;

97

98

/** 99.99th percentile */

99

readonly p99_99: number;

100

101

/** 99.999th percentile */

102

readonly p99_999: number;

103

}

104

```

105

106

### Pool-Level Metrics

107

108

Access performance metrics through the main pool instance.

109

110

```typescript { .api }

111

class Piscina {

112

/** Performance histogram (when recordTiming is enabled) */

113

readonly histogram: PiscinaHistogram;

114

115

/** Pool utilization as percentage (0-1) */

116

readonly utilization: number;

117

118

/** Pool runtime duration in milliseconds */

119

readonly duration: number;

120

121

/** Total number of completed tasks */

122

readonly completed: number;

123

}

124

```

125

126

**Usage Examples:**

127

128

```typescript

129

import Piscina from "piscina";

130

131

// Create pool with timing enabled (default)

132

const pool = new Piscina({

133

filename: "worker.js",

134

recordTiming: true, // Default: true

135

workerHistogram: true // Enable per-worker histograms

136

});

137

138

// Run some tasks

139

await Promise.all([

140

pool.run({ task: "fast" }),

141

pool.run({ task: "medium" }),

142

pool.run({ task: "slow" })

143

]);

144

145

// Access performance metrics

146

const stats = pool.histogram;

147

148

console.log('Runtime Statistics:');

149

console.log(`Average: ${stats.runTime.average.toFixed(2)}ms`);

150

console.log(`Median (p50): ${stats.runTime.p50.toFixed(2)}ms`);

151

console.log(`97.5th percentile: ${stats.runTime.p97_5.toFixed(2)}ms`);

152

console.log(`99th percentile: ${stats.runTime.p99.toFixed(2)}ms`);

153

console.log(`Min: ${stats.runTime.min.toFixed(2)}ms`);

154

console.log(`Max: ${stats.runTime.max.toFixed(2)}ms`);

155

156

console.log('\nWait Time Statistics:');

157

console.log(`Average wait: ${stats.waitTime.average.toFixed(2)}ms`);

158

console.log(`Median wait: ${stats.waitTime.p50.toFixed(2)}ms`);

159

console.log(`99th percentile wait: ${stats.waitTime.p99.toFixed(2)}ms`);

160

161

console.log('\nPool Statistics:');

162

console.log(`Utilization: ${(pool.utilization * 100).toFixed(2)}%`);

163

console.log(`Completed tasks: ${pool.completed}`);

164

console.log(`Running for: ${pool.duration.toFixed(2)}ms`);

165

```

166

167

### Worker-Level Metrics

168

169

Individual worker performance tracking when `workerHistogram` is enabled.

170

171

```typescript { .api }

172

interface PiscinaWorker {

173

/** Worker-specific histogram (when workerHistogram is enabled) */

174

readonly histogram: PiscinaHistogramSummary | null;

175

}

176

```

177

178

**Usage Examples:**

179

180

```typescript

181

import Piscina from "piscina";

182

183

const pool = new Piscina({

184

filename: "worker.js",

185

workerHistogram: true, // Enable per-worker tracking

186

maxThreads: 4

187

});

188

189

// Run tasks and monitor per-worker performance

190

await Promise.all(

191

Array.from({ length: 100 }, (_, i) => pool.run({ taskId: i }))

192

);

193

194

// Monitor individual worker performance

195

pool.threads.forEach((thread, index) => {

196

const workerStats = thread.histogram;

197

if (workerStats) {

198

console.log(`\nWorker ${index} Performance:`);

199

console.log(`Average runtime: ${workerStats.average.toFixed(2)}ms`);

200

console.log(`Median runtime: ${workerStats.p50.toFixed(2)}ms`);

201

console.log(`97.5th percentile: ${workerStats.p97_5.toFixed(2)}ms`);

202

}

203

});

204

```

205

206

### Performance Monitoring Patterns

207

208

#### Real-time Monitoring

209

210

```typescript

211

import Piscina from "piscina";

212

213

const pool = new Piscina({

214

filename: "worker.js",

215

recordTiming: true,

216

workerHistogram: true

217

});

218

219

// Real-time performance dashboard

220

function displayPerformanceMetrics() {

221

const stats = pool.histogram;

222

223

console.clear();

224

console.log('=== Piscina Performance Dashboard ===\n');

225

226

// Pool overview

227

console.log(`Pool Utilization: ${(pool.utilization * 100).toFixed(1)}%`);

228

console.log(`Active Threads: ${pool.threads.length}`);

229

console.log(`Queue Size: ${pool.queueSize}`);

230

console.log(`Completed Tasks: ${pool.completed}`);

231

console.log(`Pool Runtime: ${(pool.duration / 1000).toFixed(1)}s\n`);

232

233

// Runtime statistics

234

console.log('Runtime Statistics:');

235

console.log(` Mean: ${stats.runTime.mean.toFixed(2)}ms`);

236

console.log(` Median: ${stats.runTime.p50.toFixed(2)}ms`);

237

console.log(` P97.5: ${stats.runTime.p97_5.toFixed(2)}ms`);

238

console.log(` P99: ${stats.runTime.p99.toFixed(2)}ms\n`);

239

240

// Wait time statistics

241

console.log('Wait Time Statistics:');

242

console.log(` Mean: ${stats.waitTime.mean.toFixed(2)}ms`);

243

console.log(` Median: ${stats.waitTime.p50.toFixed(2)}ms`);

244

console.log(` P97.5: ${stats.waitTime.p97_5.toFixed(2)}ms`);

245

console.log(` P99: ${stats.waitTime.p99.toFixed(2)}ms\n`);

246

247

// Worker breakdown

248

console.log('Worker Performance:');

249

pool.threads.forEach((thread, index) => {

250

const usage = thread.currentUsage;

251

const hist = thread.histogram;

252

const avgTime = hist ? hist.average.toFixed(1) : 'N/A';

253

console.log(` Worker ${index}: ${usage} tasks, ${avgTime}ms avg`);

254

});

255

}

256

257

// Update dashboard every 2 seconds

258

const dashboardInterval = setInterval(displayPerformanceMetrics, 2000);

259

260

// Stop monitoring

261

setTimeout(() => {

262

clearInterval(dashboardInterval);

263

pool.close();

264

}, 60000);

265

```

266

267

#### Performance Alerting

268

269

```typescript

270

import Piscina from "piscina";

271

272

const pool = new Piscina({

273

filename: "worker.js",

274

recordTiming: true

275

});

276

277

// Performance thresholds

278

const THRESHOLDS = {

279

avgRuntimeMs: 1000, // Alert if average > 1s

280

p99RuntimeMs: 5000, // Alert if P99 > 5s

281

avgWaitTimeMs: 100, // Alert if wait > 100ms

282

utilizationPercent: 90 // Alert if utilization > 90%

283

};

284

285

function checkPerformanceAlerts() {

286

const stats = pool.histogram;

287

const utilization = pool.utilization * 100;

288

289

// Runtime alerts

290

if (stats.runTime.average > THRESHOLDS.avgRuntimeMs) {

291

console.warn(`⚠️ High average runtime: ${stats.runTime.average.toFixed(2)}ms`);

292

}

293

294

if (stats.runTime.p99 > THRESHOLDS.p99RuntimeMs) {

295

console.warn(`⚠️ High P99 runtime: ${stats.runTime.p99.toFixed(2)}ms`);

296

}

297

298

// Wait time alerts

299

if (stats.waitTime.average > THRESHOLDS.avgWaitTimeMs) {

300

console.warn(`⚠️ High average wait time: ${stats.waitTime.average.toFixed(2)}ms`);

301

}

302

303

// Utilization alerts

304

if (utilization > THRESHOLDS.utilizationPercent) {

305

console.warn(`⚠️ High utilization: ${utilization.toFixed(1)}%`);

306

}

307

308

// Queue backup alert

309

if (pool.queueSize > 10) {

310

console.warn(`⚠️ Queue backup: ${pool.queueSize} tasks waiting`);

311

}

312

}

313

314

// Check for alerts every 10 seconds

315

const alertInterval = setInterval(checkPerformanceAlerts, 10000);

316

```

317

318

#### Performance Logging

319

320

```typescript

321

import Piscina from "piscina";

322

import { writeFileSync, appendFileSync } from "fs";

323

324

const pool = new Piscina({

325

filename: "worker.js",

326

recordTiming: true,

327

workerHistogram: true

328

});

329

330

// Log performance metrics to file

331

function logPerformanceMetrics() {

332

const timestamp = new Date().toISOString();

333

const stats = pool.histogram;

334

335

const logEntry = {

336

timestamp,

337

utilization: pool.utilization,

338

completed: pool.completed,

339

queueSize: pool.queueSize,

340

activeThreads: pool.threads.length,

341

runtime: {

342

mean: stats.runTime.mean,

343

median: stats.runTime.p50,

344

p97_5: stats.runTime.p97_5,

345

p99: stats.runTime.p99

346

},

347

waitTime: {

348

mean: stats.waitTime.mean,

349

median: stats.waitTime.p50,

350

p97_5: stats.waitTime.p97_5,

351

p99: stats.waitTime.p99

352

}

353

};

354

355

appendFileSync('piscina-performance.log', JSON.stringify(logEntry) + '\n');

356

}

357

358

// Log metrics every minute

359

const logInterval = setInterval(logPerformanceMetrics, 60000);

360

361

// Reset metrics periodically to avoid memory growth

362

setInterval(() => {

363

console.log('Resetting performance metrics...');

364

pool.histogram.resetRunTime();

365

pool.histogram.resetWaitTime();

366

}, 3600000); // Reset every hour

367

```

368

369

### Histogram Reset Operations

370

371

Reset performance data for fresh measurements.

372

373

```typescript { .api }

374

interface PiscinaHistogram {

375

/**

376

* Reset all runtime measurement data

377

* Useful for periodic cleanup or benchmarking specific periods

378

*/

379

resetRunTime(): void;

380

381

/**

382

* Reset all wait time measurement data

383

* Useful for periodic cleanup or benchmarking specific periods

384

*/

385

resetWaitTime(): void;

386

}

387

```

388

389

**Usage Examples:**

390

391

```typescript

392

const pool = new Piscina({ filename: "worker.js" });

393

394

// Run baseline measurements

395

await runBaselineTasks();

396

397

// Reset for clean benchmark

398

pool.histogram.resetRunTime();

399

pool.histogram.resetWaitTime();

400

401

// Run benchmark

402

await runBenchmarkTasks();

403

404

// Get clean benchmark results

405

const benchmarkStats = pool.histogram;

406

console.log(`Benchmark average: ${benchmarkStats.runTime.average}ms`);

407

```

408

409

### Configuration Options

410

411

Control performance monitoring behavior through pool options.

412

413

```typescript { .api }

414

interface Options {

415

/** Enable/disable timing collection (default: true) */

416

recordTiming?: boolean;

417

418

/** Enable per-worker histograms (default: false) */

419

workerHistogram?: boolean;

420

}

421

```

422

423

**Usage Examples:**

424

425

```typescript

426

// Disable performance monitoring for maximum performance

427

const highPerformancePool = new Piscina({

428

filename: "worker.js",

429

recordTiming: false, // Disable metrics collection

430

workerHistogram: false

431

});

432

433

// Full monitoring for development/debugging

434

const debugPool = new Piscina({

435

filename: "worker.js",

436

recordTiming: true,

437

workerHistogram: true

438

});

439

440

// Production monitoring (pool-level only)

441

const productionPool = new Piscina({

442

filename: "worker.js",

443

recordTiming: true,

444

workerHistogram: false // Reduce overhead

445

});

446

```