From bc76633f77407e001b41af2d1467c54f1af53d75 Mon Sep 17 00:00:00 2001 From: Jeremy Daer Date: Mon, 16 Feb 2026 14:28:05 -0800 Subject: [PATCH] Reduce webhook delivery cleanup impact (#2550) * Add index on webhook_deliveries.created_at The stale scope (WHERE created_at < ?) and ordered scope (ORDER BY created_at DESC) both benefit from this index. Without it, Webhook::Delivery.cleanup does a full table scan. * Run webhook delivery cleanup every 15 minutes Each run now deletes ~15 minutes of newly-stale records instead of ~4 hours worth, a 16x reduction in per-run write volume. --- config/recurring.yml | 2 +- ...60213170100_add_created_at_index_to_webhook_deliveries.rb | 5 +++++ db/schema.rb | 3 ++- db/schema_sqlite.rb | 3 ++- 4 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20260213170100_add_created_at_index_to_webhook_deliveries.rb diff --git a/config/recurring.yml b/config/recurring.yml index f1c1216dc..894c57b95 100644 --- a/config/recurring.yml +++ b/config/recurring.yml @@ -20,7 +20,7 @@ production: &production schedule: every hour at minute 12 cleanup_webhook_deliveries: command: "Webhook::Delivery.cleanup" - schedule: every 4 hours at minute 51 + schedule: every 15 minutes cleanup_magic_links: command: "MagicLink.cleanup" schedule: every 4 hours diff --git a/db/migrate/20260213170100_add_created_at_index_to_webhook_deliveries.rb b/db/migrate/20260213170100_add_created_at_index_to_webhook_deliveries.rb new file mode 100644 index 000000000..1ae01a00e --- /dev/null +++ b/db/migrate/20260213170100_add_created_at_index_to_webhook_deliveries.rb @@ -0,0 +1,5 @@ +class AddCreatedAtIndexToWebhookDeliveries < ActiveRecord::Migration[8.2] + def change + add_index :webhook_deliveries, :created_at + end +end diff --git a/db/schema.rb b/db/schema.rb index a46444460..e74a97212 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.2].define(version: 2026_02_12_102026) do +ActiveRecord::Schema[8.2].define(version: 2026_02_13_170100) do create_table "accesses", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.datetime "accessed_at" t.uuid "account_id", null: false @@ -821,6 +821,7 @@ ActiveRecord::Schema[8.2].define(version: 2026_02_12_102026) do t.datetime "updated_at", null: false t.uuid "webhook_id", null: false t.index ["account_id"], name: "index_webhook_deliveries_on_account_id" + t.index ["created_at"], name: "index_webhook_deliveries_on_created_at" t.index ["event_id"], name: "index_webhook_deliveries_on_event_id" t.index ["webhook_id"], name: "index_webhook_deliveries_on_webhook_id" end diff --git a/db/schema_sqlite.rb b/db/schema_sqlite.rb index 4254c30f1..6ea0a137d 100644 --- a/db/schema_sqlite.rb +++ b/db/schema_sqlite.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.2].define(version: 2026_02_12_102026) do +ActiveRecord::Schema[8.2].define(version: 2026_02_13_170100) do create_table "accesses", id: :uuid, force: :cascade do |t| t.datetime "accessed_at" t.uuid "account_id", null: false @@ -594,6 +594,7 @@ ActiveRecord::Schema[8.2].define(version: 2026_02_12_102026) do t.datetime "updated_at", null: false t.uuid "webhook_id", null: false t.index ["account_id"], name: "index_webhook_deliveries_on_account_id" + t.index ["created_at"], name: "index_webhook_deliveries_on_created_at" t.index ["event_id"], name: "index_webhook_deliveries_on_event_id" t.index ["webhook_id"], name: "index_webhook_deliveries_on_webhook_id" end