Destroying Actors
Permanently destroy Rivet Actors and their stored state, use lifecycle cleanup hooks, and choose safe deletion patterns.
- User account deletion
- Ending a user session
- Closing a room or game
- Cleaning up temporary resources
- GDPR/compliance data removal
Actors sleep when idle, so destruction is only needed to permanently remove data; not to save compute.
Destroying An Actor
Destroy via Action
To destroy an actor, use c.destroy() like this:
import { actor } from "rivetkit";
import { db } from "rivetkit/db";
interface UserInput {
email: string;
name: string;
}
const userActor = actor({
db: db({
onMigrate: async (db) => {
await db.execute(`
CREATE TABLE IF NOT EXISTS profile (
id INTEGER PRIMARY KEY CHECK (id = 1),
email TEXT NOT NULL,
name TEXT NOT NULL
);
`);
},
}),
onCreate: async (c, input: UserInput) => {
await c.db.execute(
"INSERT INTO profile (id, email, name) VALUES (1, ?, ?)",
input.email,
input.name,
);
},
actions: {
deleteAccount: (c) => {
c.destroy();
},
},
});
Destroy via HTTP
Send a DELETE request to your control plane to destroy an actor. Authenticate with your Rivet token.
const actorId = "your-actor-id";
const namespace = "default";
const token = "your-token";
await fetch(`https://rivet.example.com/actors/${actorId}?namespace=${namespace}`, {
method: "DELETE",
headers: {
Authorization: `Bearer ${token}`,
},
});
curl -X DELETE "https://rivet.example.com/actors/{actorId}?namespace={namespace}" \
-H "Authorization: Bearer {token}"
To find the actor ID, list the actors with that name first:
curl "https://rivet.example.com/actors?namespace={namespace}&name={actor-name}" \
-H "Authorization: Bearer {token}"
Lifecycle Hook
Once destroyed, the onDestroy hook will be called. This can be used to clean up resources related to the actor. For example:
import { actor } from "rivetkit";
import { db } from "rivetkit/db";
interface UserInput {
email: string;
name: string;
}
// Example email service interface
const emailService = {
send: async (options: { from: string; to: string; subject: string; text: string }) => {},
};
const userActor = actor({
db: db({
onMigrate: async (db) => {
await db.execute(`
CREATE TABLE IF NOT EXISTS profile (
id INTEGER PRIMARY KEY CHECK (id = 1),
email TEXT NOT NULL,
name TEXT NOT NULL
);
`);
},
}),
onCreate: async (c, input: UserInput) => {
await c.db.execute(
"INSERT INTO profile (id, email, name) VALUES (1, ?, ?)",
input.email,
input.name,
);
},
onDestroy: async (c) => {
const rows = (await c.db.execute(
"SELECT email, name FROM profile WHERE id = 1",
)) as { email: string; name: string }[];
const user = rows[0];
await emailService.send({
from: "noreply@example.com",
to: user.email,
subject: "Account Deleted",
text: `Goodbye ${user.name}, your account has been deleted.`,
});
},
actions: {
deleteAccount: (c) => {
c.destroy();
},
},
});
Accessing Actor After Destroy
Once an actor is destroyed, any subsequent requests to it will fail with an actor.not_found error ({ group: "actor", code: "not_found" }). The actor’s data, including its SQLite database, is permanently deleted.