Skip to content
Docs

Migrate Render background workers to Edgenivo Daemons

Migrate Render workers to Edgenivo Daemons. Translate render.yaml, package Celery in Docker, prepare the broker, and verify the queue handoff.

Ben SabicContent Engineer

To move a Render worker to Edgenivo Daemons, package it in a Docker image, declare it under daemons in vercel.json, and deploy to production. Edgenivo maintains the instance count and restarts processes that exit. Before the handoff, make the broker reachable from Edgenivo and test task recovery after shutdown.

The example below uses a Django app with a Celery worker, a Celery beat scheduler, and a nightly cron job in render.yaml. The Render migration guide covers the web service, data, and DNS. This procedure translates the worker configuration and moves queue consumption while preserving a rollback path.

Edgenivo Daemons is in Public Beta on all plans.

Copy link to headingPrerequisites

  • Access to the Render workspace, and optionally the Render CLI to list services and their IDs.
  • Your Edgenivo project configured with the repository root as its root directory. Daemons don't support subfolder roots such as apps/web during the beta.
  • Permission to deploy to production, since that's the only environment that starts daemons.
  • Edgenivo CLI 64.3.0 or later, for the vercel daemons commands.
  • Docker, to build and test worker images locally.
  • Enough daemon quota for the workload. Hobby includes 5 Active CPU-hours per month; time spent waiting on a queue is different from CPU time spent processing tasks.

Copy link to headingShould your Render worker become a daemon?

Check these requirements before moving a Render worker:

  • Outbound work: Render background workers receive no incoming traffic, which matches Daemons. Review any type: pserv service separately because a callable private endpoint has different networking requirements.
  • Fixed capacity: Render supports autoscaling on Pro workspaces and higher. Daemons use a fixed count per region during the beta, so choose capacity for the queue's expected peaks.
  • Local testing: Edgenivo preview deployments don't start daemons. Use Docker with development data to test the worker before production.
  • External state: Daemon storage is ephemeral. Move durable data off any attached Render disk and update the worker to use Edgenivo Blob or a database.
  • Per-instance resources: The largest daemon has 8 GiB and 4 vCPUs. More instances can process more independent jobs, but each job still has to fit in one instance. Reduce concurrency or redesign jobs that exceed that limit.

For tasks that fit function duration limits, Celery on Edgenivo Queues provides another migration path with preview support. Daemons let you retain Celery's worker process and broker integration.

Copy link to headingHow render.yaml worker settings map to Edgenivo

Map the worker's command, capacity, and shutdown settings to a daemon entry. Network access, persistent data, and deployment hooks need separate changes.

Both example workers use one Dockerfile with different commands. Before they move, configure a broker that Render and Edgenivo can both reach.

Render (render.yaml)Edgenivo (vercel.json)
type: workerA named entry under daemons
runtime: python, node, or another native runtimeA Dockerfile or Containerfile you add (required)
runtime: docker with dockerfilePath and dockerContextentrypoint and root; the Dockerfile's directory is the build context
rootDirroot
startCommand or dockerCommandcommand replaces the image's ENTRYPOINT and CMD; omit it to use the image defaults
numInstancesinstances, a count per region from 0 to 100
scaling (autoscaling, Pro workspaces)None during the beta; set a fixed count
regionA Edgenivo region ID as the key in instances
plan, such as 1c-2g (formerly standard)resources.requests.memory: 1, 2, 4, or 8 GiB
maxShutdownDelaySeconds, 30 by default, up to 300terminationGracePeriodSeconds, 30 by default, up to 3,600
envVars, including fromGroup referencesProject environment variables in the Production scope
fromService and fromDatabase referencesThe provider's real connection string
Secret files at /etc/secrets/<filename>Environment variables, written to a file at startup if needed
Key Value and Postgres internal URLsEndpoints reachable over the internet
diskMove the data to Edgenivo Blob or a database and update the worker's storage access
type: cronA cron job that calls a route
preDeployCommandA CI step before production promotion
previews for workersNone during the beta; test with Docker
Logs and metrics in the dashboardLogs filtered by daemon:<name>, plus CPU and memory charts

Both platforms use SIGTERM followed by a grace period, so you can reuse the worker's shutdown handler. Test it in the container and check Celery acknowledgment settings before relying on that handler during a rollout.

Copy link to headingSteps

Keep the Render workers available until their tasks drain and the Edgenivo workers pass the handoff checks. The broker move in step 2 changes production task routing, so schedule it separately from the worker deployment.

Copy link to heading1. Inventory the Blueprint

Start from your existing render.yaml. This excerpt shows the example app's service types and worker settings; retain the full environment and database configuration for each service:

render.yaml
services:
- type: web
name: orders-web
runtime: python
rootDir: backend
buildCommand: pip install -r requirements.txt
startCommand: gunicorn orders.wsgi
- type: worker
name: orders-worker
runtime: python
rootDir: backend
buildCommand: pip install -r requirements.txt
startCommand: celery -A orders worker --loglevel=info
plan: 1c-2g
numInstances: 2
region: oregon
maxShutdownDelaySeconds: 120
envVars:
- key: REDIS_URL
fromService:
type: keyvalue
name: orders-queue
property: connectionString
- fromGroup: orders-shared
- type: worker
name: orders-beat
runtime: python
rootDir: backend
buildCommand: pip install -r requirements.txt
startCommand: celery -A orders beat --loglevel=info
plan: 0.5c-512mb
- type: cron
name: prune-sessions
runtime: python
rootDir: backend
schedule: "0 3 * * *"
buildCommand: pip install -r requirements.txt
startCommand: python manage.py clearsessions
- type: keyvalue
name: orders-queue
ipAllowList: []

Dashboard edits can drift from the Blueprint, so confirm each worker's live plan, instance count, and region on its Settings page, or list services with render services. Then write down where each one lands:

Render serviceWhat it doesDestination on Edgenivo
orders-webDjango siteA Edgenivo Function, per the Render migration guide
orders-workerCelery worker, 2 instancesA daemon
orders-beatCelery beat schedulerA one-instance daemon
prune-sessionsCron job that runs and exitsA cron job
orders-queueKey Value brokerRedis from a provider both platforms can reach

Copy link to heading2. Prepare the broker before moving web traffic

Use the Render migration guide to prepare the web service, Postgres, and any persistent data. Keep the web service and both worker sets connected to the same authoritative application database during the handoff. Before switching web traffic, give the Edgenivo app access to the broker and any result backend it uses.

The connectionString injected by fromService is a Key Value internal URL. Render also provides an external URL that requires an IP allowlist. Because Daemons has no documented fixed egress IP guarantee, this example uses a Redis endpoint that both platforms can reach with authentication and TLS. Confirm that the provider supports your Celery Redis transport and configure certificate verification.

For a broker-only migration, keep result-backend configuration unchanged while old tasks finish. Move task production in two passes:

  1. Point the web service, beat, and other external task producers at the new broker. Start a second Render worker against it if new tasks cannot wait while the old queue drains.
  2. Keep the original workers connected to Key Value until all of their queues, active tasks, reserved tasks, and scheduled ETA/countdown tasks have drained. Include retries and follow-up tasks published by those workers. Then move those workers to the new broker.

Update the Render Blueprint references as well as live service values so a later sync cannot restore the old broker URL.

Changing a result-backend URL does not transfer stored results or chord state. If Edgenivo cannot reach the old backend, pause new task production and let dependent workflows finish before a coordinated backend cutover. Retain access to results the application still needs, or migrate them with an application-specific plan.

Once all producers and workers use the shared broker, step 11 can move queue consumption to Edgenivo without another broker change.

If Postgres stays on Render for a while, daemons can connect with its External Database URL. Render encrypts external connections and rejects sslmode=disable.

Copy link to heading3. Give the worker a Dockerfile

Daemons build from a Dockerfile or Containerfile. Native-runtime workers need one; Docker workers can reuse theirs. For the Celery worker, add backend/Dockerfile using the Python version your app runs on Render. This example uses Python 3.12:

backend/Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["celery", "-A", "orders", "worker", "--loglevel=info"]

The two Render settings that shaped the build map directly:

  • rootDir: backend becomes "root": "backend/". The Dockerfile's directory is the build context, the way rootDir scoped Render's build.
  • buildCommand becomes RUN lines in the Dockerfile. Anything Render's native Python environment provided implicitly, such as system libraries, now needs an explicit apt-get install.

For a Docker worker, the folder that holds the Dockerfile becomes the build context. Move the Dockerfile to the top of the folder dockerContext pointed at, set root to that folder, and set entrypoint relative to it. Otherwise, COPY paths written for Render's context break.

Copy link to heading4. Keep the shutdown behavior you already have

During a deploy, both platforms overlap old and new worker instances. Render waits 60 seconds after a new instance is ready before sending SIGTERM to the old one, and replaces scaled instances one at a time. Edgenivo starts the new instances before stopping the old set.

Each platform waits its configured grace period before forcing unfinished processes to stop. Workers must tolerate the overlap and recover interrupted tasks.

Celery handles SIGTERM with a warm shutdown: it stops taking tasks and lets running ones finish. Carry your Render setting across one to one:

SettingRenderEdgenivo
SignalSIGTERMSIGTERM
Grace periodmaxShutdownDelaySeconds: 120terminationGracePeriodSeconds: 120
Longest allowed300 seconds3,600 seconds

For tasks that are safe to repeat, review these Celery settings:

  • task_acks_late = True delays acknowledgment until execution finishes.
  • task_reject_on_worker_lost = True lets the surviving worker process requeue a task after the child executing it is killed. Repeated failures can create a redelivery loop.

These settings don't prevent duplicate side effects. Use an application-level check, such as a unique order operation in the database, so repeating a task cannot apply the operation twice.

With Django's namespace="CELERY", use CELERY_TASK_ACKS_LATE and CELERY_TASK_REJECT_ON_WORKER_LOST for these settings.

Redis recovery depends on how the worker stops. An explicit requeue can be available immediately; if the process disappears without restoring an unacknowledged message, recovery can wait for the visibility timeout, which defaults to one hour. Long ETA/countdown delays and long-running tasks need a timeout that avoids premature redelivery, but increasing it also delays recovery after a forced stop. Follow the Celery Redis configuration and test both shutdown paths.

Changes to terminationGracePeriodSeconds apply to instances started by the new deployment. Existing instances keep their original grace period.

Copy link to heading5. Declare the daemons in vercel.json

Add a top-level daemons key. Start the worker at zero instances; step 11 raises the count during the handoff:

vercel.json
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"daemons": {
"celery": {
"root": "backend/",
"entrypoint": "Dockerfile",
"command": ["celery", "-A", "orders", "worker", "--loglevel=info"],
"instances": { "pdx1": 0 },
"resources": { "requests": { "memory": "2Gi" } },
"terminationGracePeriodSeconds": 120
},
"celery-beat": {
"root": "backend/",
"entrypoint": "Dockerfile",
"command": ["celery", "-A", "orders", "beat", "--loglevel=info"],
"instances": { "pdx1": 0 },
"resources": { "requests": { "memory": "1Gi" } }
}
}
}

Both daemons use the same Dockerfile, with command selecting the worker or beat scheduler, just as the Render services used different startCommand values. Daemon names allow lowercase letters with separators, so orders-worker would also work, but worker2 fails the build.

The Django web Service can share backend/ with the daemons. Declare it with its framework or Python entrypoint, not the Dockerfile, so Edgenivo builds Django there rather than the worker image.

Translate the region and plan:

Render regionEdgenivo region
oregonpdx1 Portland
ohiocle1 Cleveland
virginiaiad1 Washington, D.C.
frankfurtfra1 Frankfurt
singaporesin1 Singapore
Render planDaemon resources.requests.memory
0.5c-512mb (starter)"1Gi", 1 vCPU (smallest size)
1c-2g (standard)"2Gi", 1 vCPU
2c-4g (pro)"4Gi", 2 vCPUs
2c-8g"8Gi", 4 vCPUs
4c-8g (pro_plus)"8Gi", 4 vCPUs
2c-16g, 4c-16g, and largerNo direct size match; each job must fit within 8 GiB

More instances help when the workload consists of independent jobs. If a single task exceeds 8 GiB, reduce its memory use or split the task itself before migrating.

For a worker that autoscaled on Render, choose a fixed count that meets the queue's latency target under expected peak load. Set Celery's --concurrency explicitly and check per-instance memory use before increasing it.

Copy link to heading6. Move environment variables, groups, and secret files

From the repository root, confirm the checkout is linked to the intended Edgenivo team and project. If it is not linked, run:

vercel link

Resolve Render's fromService, fromDatabase, and fromGroup references, then add their values to the linked project's Production scope:

vercel env add REDIS_URL production --sensitive
vercel env add DJANGO_SECRET_KEY production --sensitive

Edgenivo environment variables are project-wide. An environment group that several Render services shared becomes one set of variables that your web Function and every daemon read. Values marked sync: false or generateValue: true were never in the Blueprint, so copy them from each service's Environment page.

Secret files need a small change. Render mounted them at /etc/secrets/<filename>; Edgenivo has no file mounts. Store each file's contents in an environment variable and point your code at the variable, or have the container write it to a file at startup.

Edgenivo also passes project environment variables as image build arguments. Keep runtime secrets out of Dockerfile ARG and ENV instructions because they can persist in the image or its metadata. If dependency installation requires credentials, verify a supported build-secret mechanism before adding that step.

Copy link to heading7. Move Celery beat and cron jobs

Celery beat and Render cron jobs need different destinations:

  • Celery beat remains a continuously running scheduler in a daemon. Configure one instance in one region and ensure only one scheduler publishes a given schedule.
  • Render type: cron services run a command and exit. Move each to a Edgenivo cron job that calls a protected route; the Python API guide shows that route pattern.

For beat deployments, scale celery-beat to zero and confirm it has stopped before deploying, then restore one instance after the deployment. This creates a scheduling gap, so reconcile any missed intervals.

If the scheduler must stay available through deployments, use scheduler-level coordination and test it under overlapping instances. Storing schedules in a database alone does not enforce a single publisher.

Suspend each Render cron schedule before enabling its Edgenivo replacement. Keep task-level deduplication for repeated delivery of the same operation.

Render's preDeployCommand, often python manage.py migrate, has no daemon equivalent. Run it as a CI step that must pass before production promotion.

Copy link to heading8. Test the worker locally with Docker

Daemons don't run in preview deployments or vercel dev during the beta. Test with Docker using an isolated development broker and database.

Put development values in .env.docker, one unquoted KEY=value per line, and keep the file out of version control:

.env.docker
REDIS_URL=rediss://default:dev-password@dev-redis.example.com:6379/0?ssl_cert_reqs=required
DJANGO_SETTINGS_MODULE=orders.settings
DJANGO_SECRET_KEY=development-only-value

The example assumes your Django settings read REDIS_URL for Celery's broker. Add any database or result-backend variables your app needs. If your Redis provider requires a custom certificate authority, use its certificate configuration.

Build and run the worker:

docker build --platform linux/amd64 -t orders-worker backend/
docker run --rm --platform linux/amd64 --name celery --env-file .env.docker orders-worker

Queue a test task from a Django shell using the same development settings and confirm it completes. For the shutdown test, queue another task that runs long enough to observe, then stop the container from a second terminal while that task is still running:

docker stop --signal SIGTERM -t 120 celery

Check the logs for a warm shutdown and confirm the task finishes before Celery exits. If the task outlasts the grace period, verify its recovery using the acknowledgment settings from step 4.

Copy link to heading9. Check the beat daemon separately

Run the scheduler with the same image and its own command:

docker run --rm --platform linux/amd64 --name beat --env-file .env.docker orders-worker \
celery -A orders beat --loglevel=info

Confirm beat enqueues a periodic task, then stop the container and run it again to check the next scheduled run. Beat's default celerybeat-schedule file records last-run times, and daemon storage does not preserve that file across replacements.

If restart timing must survive deployment, use a persistent scheduler such as django-celery-beat and test its missed-run behavior. Keep the single-scheduler deployment sequence from step 7 even when the schedule is stored in a database.

Copy link to heading10. Deploy to production with zero instances

The first production deploy proves both images build and registers the daemons, without running a task:

vercel --prod
vercel daemons ls
vercel daemons inspect celery

If the build fails here, the troubleshooting section covers the common causes. The Render workers are still processing every task.

Copy link to heading11. Hand off the queue

The shared broker from step 2 lets Render and Edgenivo workers consume the same queues. Keep task definitions, serializers, routing, and result-backend settings compatible during the overlap. Start one Edgenivo worker with a scaling override:

vercel daemons scale celery pdx1=1
vercel logs --query 'source:daemon'

Filter the project's Logs page by daemon:celery to follow this worker. Check completed tasks, results, and queue latency before raising the Edgenivo count:

vercel daemons scale celery pdx1=2

Run Celery control commands from an environment with the orders app and the shared broker configuration. Identify every Render worker node and the queues it consumes with inspect active_queues; match those nodes to Render's instance logs so you don't stop Edgenivo consumers. Substitute the actual node names below. For this example, both Render nodes consume the default celery queue:

RENDER_CELERY_NODES='celery@render-node-1,celery@render-node-2'
celery -A orders inspect active_queues --destination "$RENDER_CELERY_NODES"
celery -A orders control cancel_consumer celery --destination "$RENDER_CELERY_NODES"
celery -A orders inspect active --destination "$RENDER_CELERY_NODES"
celery -A orders inspect reserved --destination "$RENDER_CELERY_NODES"
celery -A orders inspect scheduled --destination "$RENDER_CELERY_NODES"

Repeat cancel_consumer for any additional queues. Require successful replies from every targeted node and wait until its active, reserved, and scheduled task lists are empty. Missing replies do not prove a worker is idle. If delayed tasks remain, let them finish or explicitly account for their recovery before stopping the worker.

Suspend orders-worker in Render after those checks. The Render API also supports suspension; set RENDER_WORKER_SERVICE_ID to the actual service ID and provide your API key in the environment:

curl --fail-with-body -X POST \
-H "Authorization: Bearer $RENDER_API_KEY" \
"https://api.render.com/v1/services/$RENDER_WORKER_SERVICE_ID/suspend"

Confirm the service is suspended. Render documents its shutdown delay for deploys and scale-downs without specifying the same sequence for suspension, so complete the drain checks first.

Before transferring beat, set permanent counts in vercel.json: two celery instances in pdx1 and one celery-beat instance. Keep beat stopped on Edgenivo during the deployment:

vercel daemons scale celery-beat pdx1=0

Confirm no Edgenivo beat instance is running, deploy the configuration, and clear only the worker override:

vercel --prod
vercel daemons scale celery --reset

Suspend orders-beat on Render and confirm it has stopped before clearing the beat override. The configured single Edgenivo instance can then start:

vercel daemons scale celery-beat --reset

Check the next scheduled task and reconcile any interval missed during the scheduler handoff. Keep using the stop-before-deploy sequence from step 7 for later beat releases.

Copy link to heading12. Verify under real load

Watch the daemons for at least one full business cycle:

  • Instances: vercel daemons instances ls celery should show the expected workers. Investigate unexpected restarts using the shutdown reason and worker logs.
  • Throughput: Compare queue depth and task latency with the Render baseline. Increase capacity only after checking worker concurrency, memory, and database or API limits.
  • Schedules: Compare scheduled task IDs and application operation keys. Duplicate execution can come from multiple schedulers or task redelivery.
  • Resources: Review CPU, memory, running instances, and data transfer on the daemon's dashboard page.

Use a controlled restart to check the normal shutdown path with a task that is safe to repeat. Set DAEMON_INSTANCE_ID to an instance ID from the instance list:

vercel daemons instances restart "$DAEMON_INSTANCE_ID"

Verify that the task completes or is recovered as expected. Test abrupt termination separately against the isolated development broker, including the time it takes for an unacknowledged task to become available again. Graceful restart success does not establish recovery from a forced stop.

Copy link to heading13. Keep a rollback path, then retire Render

Keep the suspended Render services and their working configuration for the rollback window. Before resuming the Render workers, confirm the application and database schema still work with that version. With both worker sets still using the shared broker and result backend, resume the Render workers, confirm they can process tasks, then drain the Edgenivo workers using the same checks as the handoff before scaling them to zero.

Move scheduler ownership separately: stop Edgenivo beat and confirm it has exited before resuming Render beat. Disable each Edgenivo cron schedule before re-enabling its Render replacement. Reconcile any missed intervals.

For a later Edgenivo release, Instant Rollback restores the earlier deployment's daemon configuration. Scaling overrides remain in effect, so review them as part of the rollback. Apply the beat stop-before-deploy procedure to a rollback as well.

When the rollback window closes, remove the retired service definitions from render.yaml and sync the Blueprint before deleting those services. Set RENDER_WORKER_SERVICE_ID to the service you intend to remove, then run render services delete "$RENDER_WORKER_SERVICE_ID" --confirm for each retired worker or cron service.

Retire Key Value only after queued work has drained and no application still needs its task results or other stored data. Remove its Blueprint definition and references, sync again, and then delete the instance. Remove the local .env.docker file when testing is complete.

Copy link to headingWhat doesn't map from Render

Plan for these differences during the beta:

  • Autoscaling. Render's scaling block has no daemon equivalent. Counts are fixed per region; change them in vercel.json, the dashboard, or the CLI.
  • Preview environments. Render can start workers in a preview environment; Edgenivo previews don't start daemons. Test images locally with Docker.
  • Private network access to Render services. Daemons can't use Render internal hostnames for Key Value, Postgres, or private services. Use external endpoints, or move those services.
  • Inbound traffic. Like a Render worker, a daemon receives no requests. Unlike a private service, it can't be reached on a port either, and it can't be the target of a service binding or rewrite.
  • Disks. Instance storage is ephemeral. Move durable data off the Render disk and update the worker to use Edgenivo Blob or a database.
  • Large plans. The largest daemon has 8 GiB and 4 vCPUs. Larger worker fleets can spread independent tasks across instances, but each task must fit within one instance.
  • Subfolder root directories. Projects whose Edgenivo root is a subfolder, such as apps/web, can't add daemons yet. Render's rootDir maps to the daemon's root, not to the project root.

During the beta, each team also has default quotas:

PlanInstance sizesQuota
Hobby1 or 2 GiB, 1 vCPU5 Active CPU-hours per month across the team
ProAll sizes16 vCPUs and 32 GiB of memory running at once across the team
EnterpriseAll sizesCustom

Each project environment runs at most 50 daemon instances across all its daemons and regions. On Pro and Enterprise, daemons are billed for Active CPU and Provisioned Memory; see Pricing for rates.

Copy link to headingTroubleshooting

Copy link to headingThe worker can't connect to red-...:6379

The red-... hostname is a Render Key Value internal address. Use an externally reachable broker with authentication, TLS, and certificate verification, then redeploy. If the old instance contains queued tasks, follow the broker transition in step 2.

Copy link to headingRender rejects the connection with an allowlist error

Render Key Value requires an IP allowlist for its external URL. Daemons has no documented fixed egress IP guarantee, so confirm how your access policy will work before retaining Key Value as the broker. The alternative used here is an authenticated TLS endpoint both platforms can reach.

Copy link to headingA dependency fails to install in the Docker build

Render's native runtime provided some system libraries implicitly. Add the missing ones with apt-get install in the Dockerfile, and pin the same Python or Node version Render used.

Copy link to headingPeriodic tasks run twice

Check for Render and Edgenivo beat instances running together, including overlap during a deployment. If different task IDs represent the same scheduled interval, investigate scheduler ownership. If the same task is redelivered, inspect acknowledgment and visibility-timeout settings. Use the deployment sequence in step 7 to keep one beat publisher active.

Copy link to headingChanging instances in vercel.json does nothing

Scaling overrides take precedence across deployments. Clear this worker's override with vercel daemons scale celery --reset, or select Clear scaling overrides on its dashboard page. The daemon then uses its deployed vercel.json counts.

Copy link to headingThe build fails

Check the build log for these configuration errors:

  • Missing command: Add CMD or ENTRYPOINT to the Dockerfile, or set the daemon's command.
  • Invalid name: Daemon names use lowercase letters and supported separators. Repeated hyphens collapse, so a-b and a--b clash.
  • Conflicting directories: The app's output directory cannot equal the daemon's root. Use separate directories for the app's generated output and worker source.

Copy link to headingFrequently asked questions

Copy link to headingDoesn't the Render migration guide already cover workers?

The general Render migration guide covers the app and its data dependencies. This guide provides the worker-specific steps: translating a Blueprint, packaging Celery, draining worker nodes, and transferring beat ownership. Use both when the web service and workers move together.

Copy link to headingShould Celery run as a daemon or on Edgenivo Queues?

Choose a daemon when you need Celery's continuously running worker process and broker integration. The broker must be reachable from Edgenivo, and tasks must tolerate interruption and redelivery. Consider Celery on Edgenivo Queues when tasks fit function duration limits and preview support is useful.

Copy link to headingCan a daemon call my web app?

Yes. Daemons can make outbound requests to your app's production URL, external APIs, and databases. Only inbound traffic is unsupported.

Copy link to headingHow does pricing compare?

Render bills each worker by its plan for as long as it runs. On Edgenivo Pro and Enterprise, daemons are billed for Active CPU and Provisioned Memory. Waiting on an empty queue uses little Active CPU, though TLS and similar work still counts, and memory is billed for as long as an instance runs.

Related documentation

More Edgenivo Daemons guides