tl-pg-boss について
tl-pg-boss は、Node.js アプリケーションに PostgreSQL ベースのバックグラウンドジョブキューを設定するスキルです。スケジュール、リトライ、型付きハンドラーに加え、トランザクション内でのジョブ作成や運用方法を扱います。
主な機能
- 01PostgreSQL ベースのジョブキュー
- 02Cron と遅延スケジュール
- 03リトライとジョブの有効期限
- 04バッチ処理と型付きワーカー
- 05デッドレターキューと保持設定
- 06ダッシュボードと SQL による監視
活用シーン
- 01Node.js アプリにバックグラウンド処理を追加
- 02定期タスクや遅延タスクを設定
- 03PostgreSQL で失敗ジョブを再試行
- 04保留中や失敗したジョブを監視
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ toddlevy/ tl-agent-skills --skill tl-pg-bossインストール後、Claude Code で/tl-pg-bossを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEREADME.mdreferences/advanced-patterns.mdkubernetes-deployment.mdmonitoring.mdobservability.mdschedule-management.mdsend-options.mdtesting-patterns.mdtypescript-patterns.mdwordpress-migration.md詳細
tl-pg-boss
Node.js 向けの PostgreSQL ベースのジョブキューです。厳密に一度だけの配信、cron スケジューリング、トランザクションの安全性を備えています。
使用する場合
- 「アプリにバックグラウンドジョブを追加したい」
- 「ジョブキューが必要ですが、すでに Postgres を使っています」
- 「cron ジョブ/スケジュールされたタスクを設定したい」
- 「非同期処理をリトライ付きで実行したい」
- ユーザーが次のような語句に言及した場合:ジョブキュー、バックグラウンド処理、タスクスケジューリング、ワーカー
代替手段を検討する場合
ダッシュボード UI 付きのマネージドバックグラウンドジョブには、代わりに Trigger.dev をご検討ください。pg-boss が最適なのは、次のような場合です。
- セルフホスト可能で、PostgreSQL ネイティブなジョブキューが必要
- すでに Postgres を使用しており、外部依存を避けたい
- トランザクション内でのジョブ登録が必要(データ書き込みと同じトランザクション)
- コストが重要(pg-boss は無料ですが、マネージドサービスはジョブごとに課金されます)
次のような場合は Trigger.dev が適しています。
- すぐに使える洗練されたダッシュボードが必要
- 自動スケーリング付きのマネージドインフラストラクチャを利用したい
- チームがホスト型 SaaS の利用を希望している
- ビジュアルオーケストレーションを使った複雑なワークフローが必要
成果
- パッチ:pg-boss をインストールし、型付きジョブハンドラーを設定
- 成果物:適切なキュー設定を含むジョブ定義
- 判断事項:キュー構成、ジョブのパターン、監視方法
要件
| 要件 | バージョン |
|---|---|
| Node.js | 22.12+ |
| PostgreSQL | 13+ |
| 権限 | データベースに対する CREATE |
インストール
pnpm add pg-boss
初回の start() で pgboss スキーマが自動作成されます。手動でのマイグレーションは不要です。
コアコンセプト
SKIP LOCKED
PostgreSQL の SKIP LOCKED により、分散トランザクションなしで厳密に一度だけ配信できます。
常に start() を呼び出す
重要:プロデューサーも含め、すべてのプロセスで start() を呼び出す必要があります。
const boss = new PgBoss(connectionString);
await boss.start(); // Required in EVERY process
複数のプロセスが start() を呼び出しても、監視を実行するのは 1 つだけです。
ジョブの種類ごとに 1 つのキュー
await boss.createQueue("send-email");
await boss.createQueue("process-image");
基本設定
import { PgBoss } from "pg-boss";
const boss = new PgBoss({
connectionString: process.env.DATABASE_URL,
schema: "pgboss",
});
boss.on("error", console.error);
await boss.start();
await boss.createQueue("my-queue");
ジョブのパターン
ジョブを送信する
const jobId = await boss.send("my-queue", { userId: "123" });
オプション付きで送信する
await boss.send("my-queue", payload, {
retryLimit: 3,
retryDelay: 60,
expireInMinutes: 30,
priority: 1,
});
すべてのオプション:
references/send-options.mdを参照してください。
遅延ジョブ
await boss.send("my-queue", payload, {
startAfter: new Date(Date.now() + 60000),
});
cron スケジューリング
await boss.schedule("daily-report", "0 9 * * *", { type: "daily" });
スケジュール解除(cron の削除)
await boss.unschedule("daily-report");
スケジュール管理:
references/schedule-management.mdを参照してください。
ワーカーパターン
基本的なワーカー
await boss.work("my-queue", async ([job]) => {
console.log(`Processing ${job.id}`);
// Auto-completes on return, throw to fail
});
注意:batchSize: 1 でも、コールバックには配列が渡されます。
バッチ処理
await boss.work("bulk-import", { batchSize: 10 }, async (jobs) => {
for (const job of jobs) {
await processItem(job.data);
}
});
型付きジョブ
interface EmailJob {
to: string;
subject: string;
}
await boss.send<EmailJob>("send-email", { to: "[email protected]", subject: "Hi" });
await boss.work<EmailJob>("send-email", async ([job]) => {
await sendEmail(job.data.to, job.data.subject);
});
TypeScript のパターン:
references/typescript-patterns.mdを参照してください。
キューの設定
デッドレターキュー
await boss.createQueue("my-queue", { deadLetter: "my-queue-dlq" });
await boss.createQueue("my-queue-dlq");
保持
await boss.createQueue("my-queue", { retentionMinutes: 60 * 24 });
Fastify との統合
import Fastify from "fastify";
import { PgBoss } from "pg-boss";
const fastify = Fastify();
const boss = new PgBoss(process.env.DATABASE_URL);
fastify.decorate("boss", boss);
fastify.addHook("onReady", async () => {
boss.on("error", fastify.log.error.bind(fastify.log));
await boss.start();
await boss.createQueue("my-queue");
await boss.work("my-queue", handler);
});
fastify.addHook("onClose", async () => {
await boss.stop({ graceful: true });
});
監視
ダッシュボード
pnpm add @pg-boss/dashboard
DATABASE_URL="postgres://..." npx pg-boss-dashboard
簡単な SQL
-- Pending by queue
SELECT name, COUNT(*) FROM pgboss.job WHERE state = 'created' GROUP BY name;
-- Failed jobs
SELECT * FROM pgboss.job WHERE state = 'failed' ORDER BY completedon DESC LIMIT 20;
監視の詳細:
references/monitoring.mdを参照してください。
注意が必要な点
| 注意点 | 解決策 |
|---|---|
すべての場所で start() の呼び出しが必要 | プロデューサーでも必要です |
| ワーカー内のジョブ配列 | (job) ではなく ([job]) を使用します |
| LISTEN/NOTIFY なし | ポーリングのみです。pollingIntervalSeconds を設定してください |
| スキーマに CREATE 権限が必要 | または CLI を使用します:npx pg-boss migrate --dry-run |
| 完了後は失敗にできない | work() と手動の fail() を併用しないでください |
v10 には pauseQueue() がない | unschedule() と直接 SQL を使用します |
| 再起動時にスケジュールが再登録される | 初期化時にコードが schedule() を呼び出します。スケジュール解除は一時的です |
ベストプラクティス
- ゾンビジョブを防ぐため、有効期限を設定します:
expireInMinutes: 30 - 保持ポリシーを設定して積極的にアーカイブします
- upsert を使って冪等なハンドラーを実装します
- グレースフルシャットダウン:
boss.stop({ graceful: true })
可観測性
prom-clientを使った Prometheus のゲージ/カウンターの設定と、キューの滞留や失敗率に関する Prometheus のアラートルールについては、可観測性を参照してください。
テストパターン
ジョブハンドラーの単体テスト、実際の PostgreSQL データベースを使った統合テスト、vitest での pg-boss のモックについては、テストパターンを参照してください。
Kubernetes Deployment
リソース制限、liveness probe、preStop フック、SIGTERM によるグレースフルシャットダウンのハンドラーを備えたワーカー Deployment マニフェストについては、Kubernetes Deployment を参照してください。
検証
-
boss.start()がエラーなく完了する -
boss.createQueue()が成功する -
boss.send()がジョブ ID を返す - ワーカーがジョブを処理する
- ジョブの状態が
completedに変わる
参考資料
Quilted Skills
- triggerdotdev/skills/trigger-tasks — ワークフローパターン
- omer-metin/skills-for-antigravity/pg-boss — SKIP LOCKED の原則
公式ドキュメント
- pg-boss GitHub — 公式リポジトリ
- pg-boss API Docs — API リファレンス
- pg-boss Dashboard — Web UI
PostgreSQL のリソース
- PostgreSQL SKIP LOCKED — ロックのセマンティクス
- PostgreSQL Advisory Locks — アプリケーションレベルのロック
- Connection Pooling with PgBouncer — 接続管理
代替ソリューション
- Graphile Worker — PostgreSQL キューの代替
- Trigger.dev — マネージドなバックグラウンドジョブ
- BullMQ — Redis ベースの代替
スキルの参考資料
references/send-options.md— send オプションの全一覧references/typescript-patterns.md— BaseJob、JobManagerreferences/monitoring.md— ダッシュボード+SQL クエリreferences/advanced-patterns.md— Singleton、スロットリング、pub/subreferences/schedule-management.md— Cron スケジュール、スケジュール解除、一時停止のパターンreferences/wordpress-migration.md— WP-Cron と Action Scheduler の対応付け
クレジット
| ソース | 著者 | 貢献 |
|---|---|---|
| pg-boss | Tim Gilbert (@timgit) | コアライブラリ、公式ドキュメント |
| TypeScript Deep Dive | Shayan (@ImSh4yy) | BaseJob クラス、JobManager パターン |
| pg-boss-admin-dashboard | Lyubomir Petrov (@lpetrov) | JMESPath を使った代替ダッシュボード |