Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
11d1360
on-demand backups
dwwoelfel Aug 5, 2026
323e388
add delete and cancel
dwwoelfel Aug 5, 2026
35a2789
fail earlier
dwwoelfel Aug 5, 2026
b4ae99f
missing migration
dwwoelfel Aug 5, 2026
c088dfd
don't expose raw error to client
dwwoelfel Aug 5, 2026
bd39f6b
wait for the future to unwind
dwwoelfel Aug 5, 2026
6c1e01d
fix pool size and resizing pool
dwwoelfel Aug 5, 2026
21dc77d
Merge branch 'main' of github.com:instantdb/instant into on-demand-ba…
dwwoelfel Aug 5, 2026
f6f4458
reduce stuck threshold
dwwoelfel Aug 5, 2026
8de30cb
coderabbit feedback
dwwoelfel Aug 6, 2026
c496390
much better cancellation
dwwoelfel Aug 6, 2026
3869ddd
restores from /intern
dwwoelfel Aug 6, 2026
b2e9881
cleanup, better error handling
dwwoelfel Aug 6, 2026
ee33d01
include superuser email in admin emails
dwwoelfel Aug 7, 2026
b3b17f5
add a sweeper to delete apps in smaller chunks
dwwoelfel Aug 7, 2026
b36e059
better shutdown
dwwoelfel Aug 7, 2026
ffe9635
add a test
dwwoelfel Aug 7, 2026
e1cfe27
Merge branch 'main' of github.com:instantdb/instant into custodian
dwwoelfel Aug 7, 2026
66b5f56
stop the hard-deletion sweeper
dwwoelfel Aug 7, 2026
e550ab6
guard against deleting apps/attrs that aren't marked for deletion
dwwoelfel Aug 7, 2026
e36835e
add attrs, fix a bunch of stuff in production
dwwoelfel Aug 7, 2026
9ed0a22
safer deletion of app and attrs
dwwoelfel Aug 8, 2026
f43bbbb
Merge branch 'main' of github.com:instantdb/instant into custodian
dwwoelfel Aug 10, 2026
2aab4c5
monitor inactive slots
dwwoelfel Aug 10, 2026
cacf078
fix docstring
dwwoelfel Aug 10, 2026
38ec87d
docstring
dwwoelfel Aug 10, 2026
2fc5d77
pause while failing over
dwwoelfel Aug 10, 2026
9b5cb50
fix the flaky app backups test
dwwoelfel Aug 10, 2026
3689c0c
remove unused functions
dwwoelfel Aug 10, 2026
28228c1
timeout on derefs in tests
dwwoelfel Aug 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions server/resources/migrations/124_add_custodian.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
drop table custodian;

-- Recreate the trigger that cleans up triples_size_updates on attr delete.
create or replace function clean_triples_size_updates()
returns trigger as $$
begin
delete from triples_size_updates where triples_size_updates.attr_id = old.id;
return old;
end;
$$ language plpgsql;

create trigger clean_triples_size_updates_trigger
before delete on attrs
for each row
execute function clean_triples_size_updates();
52 changes: 52 additions & 0 deletions server/resources/migrations/124_add_custodian.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
create table custodian (
id uuid primary key default gen_random_uuid(),
-- The app being deleted. Cascade so the terminal `app` delete cleans up its
-- own plan rows for free.
app_id uuid not null references apps(id) on delete cascade,
-- Set when a unit of work is scoped to a single attr (e.g. deleting one
-- attr's triples). Null means the whole app.
attr_id uuid references attrs(id) on delete cascade,
-- What this row deletes: 'triples' | 'transactions' | 'attrs' | 'attr' | 'app'
type text not null,
-- The step this one depends on: it can't run until that step is done. Forms a
-- chain, e.g. for an app: app depends on transactions depends on triples. A
-- step finishes by deleting its row; `on delete set null` then clears this
-- pointer on the dependent, so the runnable row is simply the one with
-- depends_on is null.
depends_on uuid references custodian(id) on delete set null,
-- The worker that owns this row (null when unclaimed), set on claim. Doubles
-- as an owner tag. A worker heartbeats by bumping updated_at as it works; the
-- reaper frees a row (clears worker_id) whose updated_at has gone stale.
worker_id text,
-- 'waiting' (runnable) -> 'working' (claimed by a worker) and back to 'waiting'
-- on a failed attempt; set to 'failed' once processing has errored enough times
-- (see `attempts`) so it stops being retried and can be investigated.
status text not null default 'waiting',
-- How many times processing this row has errored. We retry a few times before
-- giving up and marking it 'failed', since some failures are transient.
attempts integer not null default 0,
-- The error message from the most recent failure.
error text,
created_at timestamptz not null default now(),
updated_at timestamptz not null default now(),
-- At most one row per (app, type, attr). `nulls not distinct` so two whole-app
-- rows (attr_id is null) of the same type collide instead of duplicating.
constraint custodian_unique unique nulls not distinct (app_id, type, attr_id)
);

create index custodian_attr_id on custodian (attr_id);
create index custodian_depends_on on custodian (depends_on);

create index custodian_claimable on custodian (created_at)
where depends_on is null and worker_id is null and status = 'waiting';

create trigger update_custodian_updated_at
before update on custodian
for each row
execute function update_updated_at_column();

-- Drop the trigger that cleaned up triples_size_updates on attr delete. The
-- updater clears out the rows for us, so there's no need to delete them here.
-- When we delete an app, it causes us to delete too much.
drop trigger if exists clean_triples_size_updates_trigger on attrs;
drop function if exists clean_triples_size_updates();
9 changes: 9 additions & 0 deletions server/src/instant/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
[instant.util.posthog :as posthog]
[instant.util.tracer :as tracer]
[instant.hard-deletion-sweeper :as hard-deletion-sweeper]
[instant.custodian :as custodian]
[instant.webhook-routes :as webhook-routes]
[instant.webhook-processor :as webhook-processor]
[ring.middleware.cookies :refer [CookieDateTime]]
Expand Down Expand Up @@ -359,6 +360,12 @@
(future
(tracer/with-span! {:name "stop-join-room-logger"}
(join-room-logger/stop)))
(future
(tracer/with-span! {:name "stop-hard-deletion-sweeper"}
(hard-deletion-sweeper/stop)))
(future
(tracer/with-span! {:name "stop-custodian"}
(custodian/stop)))
Comment thread
coderabbitai[bot] marked this conversation as resolved.
(future
(when (posthog/enabled?)
(tracer/with-span! {:name "stop-posthog"}
Expand Down Expand Up @@ -478,6 +485,8 @@
(storage-sweeper/start))
(with-log-init :hard-deletion-sweeper
(hard-deletion-sweeper/start))
(with-log-init :custodian
(custodian/start))
(with-log-init :rate-limit-sweeper
(rate-limit/start))
(with-log-init :wal-log-truncator
Expand Down
Loading
Loading