Functions with config.background: true run with the 60s synchronous timeout when deployed via netlify deploy
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 1.9k
- Forks
- 474
- Avg merge
- 23h 30m
- Merged PRs (30d)
- 53
Description
Describe the bug
A v2 function that declares background mode in-source with export const config = { background: true } and is deployed with netlify deploy --no-build ends up half-applied:
- The Netlify API reports the function with
invoke_mode: "background". - Callers get the documented instant
202 Accepted. - But execution is killed at exactly the 60-second synchronous limit (
Duration: 60000 msin function logs, the function body never completes), and AWS Lambda async-retries the killed invocation twice, so the body also runs 3 times.
An identical function using the legacy -background filename suffix gets the real 15-minute background budget and completes normally, on the same site, same deploy, same command.
Reproduced identically on netlify-cli 26.1.0 (first version whose bundler supports config.background, zip-it-and-ship-it 14.6.0) and 26.2.0 (latest). Runtime nodejs20.x, us-east-2, paid team plan (background functions enabled, proven by the suffixed control running >90s on the same site).
Observed (both probes are identical 90s sleepers that log START/END, fired at the same moment):
[probe-bg-config] 02:46:52.727Z INFO Duration: 60000 ms Memory Usage: 113 MB
[probe-bg-config] 02:46:52.743Z INFO PROBE probe-bg-config START 2026-07-23T02:46:52.743Z
[probe-bg-suffix-background] 02:46:52.815Z INFO Duration: 90335 ms Memory Usage: 104 MB
[probe-bg-suffix-background] 02:46:52.822Z INFO PROBE probe-bg-suffix-background START 2026-07-23T02:46:52.822Z
[probe-bg-suffix-background] 02:48:22.822Z INFO PROBE probe-bg-suffix-background END 2026-07-23T02:48:22.822Z
probe-bg-config (config only): killed at 60s, END never logs, 2 async retries follow. probe-bg-suffix-background (suffix): END at exactly START+90s. Same result on both CLI versions.
Expected: per the Background functions docs and the configuration defaults table, config.background: true should grant the 15-minute background execution limit. A function the API itself reports as invoke_mode: background and that 202-acks callers should not run under the 60s synchronous limit. The two declaration mechanisms should not diverge.
This is nasty in production: every observable signal (dashboard, API, 202s) says "background", so nothing errors at the caller. The function is silently killed mid-work and silently re-run twice, applying partial effects up to 3 times for non-idempotent work.
Possibly related internals: config.background only entered the in-source-config schema in zisi 14.6.0 (CLI 26.1.0); older CLIs silently strip it. netlify.toml [functions.<name>] background = true is dropped by normalizeFunctionsConfig at every version, so the toml route is no workaround. We've also observed in-source path routes being bundled and uploaded but 404ing on --no-build deploys (they only take effect via the build-pipeline manifest). It looks like CLI deploys upload enough for registration/routing (invocationMode) but timeout provisioning never switches to the background budget.
Workaround: the -background filename suffix (directory + entry file) behaves correctly at every CLI version.
Steps to reproduce
-
Create a project with two identical dependency-free v2 functions that sleep 90s:
functions/probe-bg-config/probe-bg-config.ts:export const config = { background: true }; export default async () => { console.log(`PROBE probe-bg-config START ${new Date().toISOString()}`); await new Promise((resolve) => setTimeout(resolve, 90_000)); console.log(`PROBE probe-bg-config END ${new Date().toISOString()}`); return new Response('ok', { status: 200 }); };functions/probe-bg-suffix-background/probe-bg-suffix-background.ts: identical body (suffix variant also keeps the config export). -
Deploy without the build pipeline:
npx -y netlify-cli@26.2.0 deploy --no-build --site <site> --dir public --functions functions --alias probe -
Confirm both functions registered as background:
curl -s -H "Authorization: Bearer $NETLIFY_AUTH_TOKEN" \ "https://api.netlify.com/api/v1/sites/$SITE_ID/functions" # both report "im": "background" -
Invoke each once — both return 202 in ~0.2s:
curl -X POST "https://probe--<site>.netlify.app/.netlify/functions/probe-bg-config" curl -X POST "https://probe--<site>.netlify.app/.netlify/functions/probe-bg-suffix-background" -
Wait ~2.5 minutes, then read the logs:
npx -y netlify-cli@26.2.0 logs --source functions \ --url https://probe--<site>.netlify.app --since 30m -
See that
probe-bg-configshowsDuration: 60000 mswith no END line (plus 2 unrequested retry STARTs), whileprobe-bg-suffix-backgroundlogs END at START+90s. -
Optional: redeploy with
netlify-cli@26.1.0and repeat — identical results.
Configuration
[build]
command = "pnpm --filter @hopdrive/svc-s3... build"
publish = "public"
[functions]
directory = "functions"
[dev]
autoLaunch = false
(No [functions.<name>] blocks, no redirects. The deploy is --no-build, so the build section is inert.)
Environment
- netlify-cli: 26.1.0 and 26.2.0 (both reproduce)
- Node.js: 20.x locally and on the GitHub-hosted runner; functions runtime nodejs20.x
- OS: macOS 14 and ubuntu-latest (GitHub Actions) — same behavior
- Deploy:
netlify deploy --no-build --site <site> --dir public --functions functions --alias <alias>
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the --no-build deployment path and normalizeFunctionsConfig, comparing in-source config.background handling with the -background filename suffix and the timeout provisioning path. Reproduce with the two 90-second functions from the issue and verify that the config form receives the 15-minute background limit, completes once, and does not retry after 60 seconds.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- backend, cli, cloud
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100