build · oxidb v0.25.21 0 entries on disk
The /dev/oxide

A build log on shipping OxiDB — notes, post-mortems, and the occasional flame war about JSON parsing, pressed straight onto an embedded engine running inside this process.

posts/0019.md · 2026-04-24

OxiScript — stored procedures and a cron scheduler

hero image for: OxiScript — stored procedures and a cron scheduler
asset · bucket: blog-images · key: d14707463ee27d4a57330bda.jpg

OxiScript is a small embedded language for server-side logic. Looks like a stripped-down JavaScript with database primitives — `db.find`, `db.insert`, `db.put_object`, control flow, arithmetic, string ops. No I/O outside the engine, no allocations beyond what the script holds, no infinite loops (step counter caps execution).

**Stored procedures.** `CREATE PROCEDURE recharge_wallet (user_id, amount) AS ...`. The body is OxiScript, compiled to a tiny bytecode, persisted in `_procedures`, callable from any client (`db.run_procedure(name, args)`) or via SQL. Procedures run in-process at FFI speed — a 10-statement procedure is microseconds, not milliseconds.

**Why a custom language?** Lua would have worked. So would deno_core or boa. Both pull in ~5–10 MB of runtime infrastructure and the security model becomes 'sandbox a general-purpose language', which is hard. OxiScript is ~2K LOC and has no syscalls to sandbox — the design choice is the security boundary.

**Cron scheduler.** `CREATE SCHEDULE rotate_caches CRON '0 */6 * * *' AS rotate_caches(...)`. The scheduler runs in a background thread, reads `_schedules` at startup, wakes on each cron-tick, invokes the procedure. Misfire handling: skipped runs are not retroactively executed (we do scheduled jobs, not at-least-once delivery).

**Patterns documented.** `examples/oxiscript/` ships a few — banking ledger (atomic transfer), audit log (append-only with rule check), inventory (oversell guard), leaderboard (sorted set wrapper), rate limiter (sliding window). All copy-pasteable.