Skip to content

Persistent Storage & Scheduled Cron Jobs

MicroFly includes built-in primitives for mounting persistent disk volumes and running scheduled background cron jobs directly inside the application's isolated runtime environment.


1. Persistent Storage Volumes

Because MicroFly deploys every release into an immutable, read-only directory (mode 0550), applications that store local databases (like SQLite, DuckDB, or embedded Key-Value stores) or user file uploads must configure persistent storage mounts.

Configuring Mounts in app.toml

Add a [storage] block to your manifest:

toml
[storage]
mounts = [
  { source = "sqlite.db", target = "data/app.db" },
  { source = "user-uploads", target = "public/uploads" }
]
  • source: File or directory inside the application's persistent storage root: /var/lib/microfly/apps/<app>/shared/storage/<source>
  • target: Path relative to the application's release root directory where the storage will be bind-mounted with read-write access.

Lifecycle & Persistence Guarantees

  1. Preserved Across Releases: When a new release is deployed, existing persistent volumes are re-mounted at the target locations in the new release.
  2. Preserved Across Rollbacks: Executing microfly rollback preserves all data written to mounted storage.
  3. Strict Isolation: App A's transient systemd unit cannot access App B's persistent storage. Systemd mount namespaces ensure only explicitly mounted volumes are accessible.

Enforcing Storage Quotas

You can prevent an application from consuming excessive disk space by defining storage_limit in the [resources] block:

toml
[resources]
storage_limit = "5GB"

Prior to activating any candidate release, MicroFly measures the cumulative byte size of /var/lib/microfly/apps/<app>/shared/storage. If the usage exceeds the configured limit, the deployment fails with a clear quota error.


2. Scheduled Cron Jobs

MicroFly eliminates the need to maintain host crontabs or external schedulers. You can define scheduled tasks directly in app.toml using standard 5-field cron expressions:

toml
[[cron]]
name = "nightly-backup"
schedule = "0 2 * * *"
command = ["./bin/server", "backup", "--target", "s3"]

[[cron]]
name = "cache-cleanup"
schedule = "*/15 * * * *"
command = ["./bin/server", "cache", "prune"]

Cron Schedule Format

MicroFly uses standard 5-field cron syntax:

text
┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of the month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday)
│ │ │ │ │
* * * * *

Operational Behavior

  • UTC Timezone: All cron schedules are evaluated in Coordinated Universal Time (UTC) to avoid daylight saving discrepancies.
  • Overlap Prevention: If a scheduled task is still running when its next execution time arrives, MicroFly skips the overlapping execution.
  • No Missed-Run Storms: If the server is offline or restarting during a scheduled minute, MicroFly resumes on the next scheduled interval rather than running dozens of stale jobs simultaneously.
  • Sandbox Parity: Cron tasks run in transient systemd service units with the exact same unprivileged UID (microfly-app), capability restrictions, environment variables, and persistent storage mounts as web processes.

Released under the MIT License.