Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed to publish your Function. Got error: Error: Script startup exceeded CPU time limit. #54

Closed
shiyuhang0 opened this issue Jan 13, 2023 · 36 comments · Fixed by #191
Closed
Assignees
Labels
blocked by external This can't be currently solved because of external factors (Vercel/Next, Pages, etc...) in progress This issue is currently being worked on and show be solved soon.

Comments

@shiyuhang0
Copy link

shiyuhang0 commented Jan 13, 2023

I am using nextjs and prisma data proxy to connect to a database.
Then I deploy to cloudflare pages but failed with Script startup exceeded CPU time limit.

I don't know if it is the problem of my project or the work_js generated by next-on-pages.

image

@mihazs
Copy link

mihazs commented Jan 18, 2023

I'm having the same issue right now, i'm not able to update my application because of that.

In my case, the _worker.js file inside .vercel/output/static folder, has 7.2MB, which is very huge for a worker script.

According with : https://developers.cloudflare.com/workers/platform/limits/#worker-startup-time

Script size can impact startup because there’s more code to parse and evaluate.

In my tests, the _worker.js file easily increases a lot the size in every new build with new features, so the script startup will exceed CPU time limit all the time.

For me, this is a deal breaker. I came to the conclusion that cloudflare pages and next.js only works for tiny projects at this moment. Right now, I'm working to get my project out of the cloudflare and considering Vercel, netlify or open-next for deploy to AWS.

If you want a fast solution, probably cloudflare wouldn't fit :/

@saaymeen
Copy link

Sharing this experience with a very small project, 5 pages, not many additional dependencies and 2 pages using little data from getServerSideProps.

@xMuratY
Copy link

xMuratY commented Feb 15, 2023

I just created a layout component (just some html no server side things) and then created dummy pages with the calling layout. After duplicating the pages this problem appeared. Can publish with removing some of the dummies.

//edit: build log

2023-02-15T02:30:20.873828Z ▲ info - Generating static pages (0/2)
2023-02-15T02:30:20.87394Z ▲
2023-02-15T02:30:20.974761Z ▲ info - Generating static pages (2/2)
2023-02-15T02:30:20.975103Z ▲
2023-02-15T02:30:20.99126Z ▲ info - Finalizing page optimization...
2023-02-15T02:30:20.991593Z ▲
2023-02-15T02:30:20.996341Z ▲
2023-02-15T02:30:20.996627Z ▲
2023-02-15T02:30:21.038888Z ▲ Route (pages) Size First Load JS
2023-02-15T02:30:21.0394Z ▲ ┌ ℇ / 425 B 73.8 kB
2023-02-15T02:30:21.039665Z ▲ ├ /_app 0 B 73.4 kB
2023-02-15T02:30:21.039867Z ▲ ├ ○ /404 181 B 73.6 kB
2023-02-15T02:30:21.040038Z ▲ ├ ℇ /api/auth 0 B 73.4 kB
2023-02-15T02:30:21.040171Z ▲ ├ ℇ /auth/signin 3.18 kB 78.6 kB
2023-02-15T02:30:21.040298Z ▲ ├ ℇ /auth/signup 3.22 kB 78.7 kB
2023-02-15T02:30:21.040421Z ▲ ├ ℇ /dashboard 1.87 kB 90.2 kB
2023-02-15T02:30:21.040575Z ▲ ├ ℇ /dashboard/management 1.89 kB 90.2 kB
2023-02-15T02:30:21.040695Z ▲ ├ ℇ /dashboard/management/keys 1.89 kB 90.2 kB
2023-02-15T02:30:21.040805Z ▲ ├ ℇ /dashboard/management/updates 1.89 kB 90.2 kB
2023-02-15T02:30:21.040914Z ▲ ├ ℇ /dashboard/management/users 1.89 kB 90.2 kB
2023-02-15T02:30:21.041031Z ▲ ├ ℇ /dashboard/order 1.87 kB 90.2 kB
2023-02-15T02:30:21.041154Z ▲ └ ℇ /dashboard/recent 1.87 kB 90.2 kB
2023-02-15T02:30:21.041271Z ▲ + First Load JS shared by all 76.9 kB
2023-02-15T02:30:21.041384Z ▲ ├ chunks/framework-2c79e2a64abdb08b.js 45.2 kB
2023-02-15T02:30:21.041504Z ▲ ├ chunks/main-809835cec98db2ac.js 26.9 kB
2023-02-15T02:30:21.041613Z ▲ ├ chunks/pages/_app-891652dd44e1e4e1.js 296 B
2023-02-15T02:30:21.041719Z ▲ ├ chunks/webpack-0b5d8249fb15f5f3.js 939 B
2023-02-15T02:30:21.042024Z ▲ └ css/837114518d7a7749.css 3.55 kB
2023-02-15T02:30:21.042201Z ▲
2023-02-15T02:30:21.042468Z ▲ ƒ Middleware 48.4 kB
2023-02-15T02:30:21.042619Z ▲
2023-02-15T02:30:21.042734Z ▲
2023-02-15T02:30:21.042856Z ▲ ℇ (Streaming) server-side renders with streaming (uses React 18 SSR streaming or Server Components)
2023-02-15T02:30:21.042964Z ▲ ○ (Static) automatically rendered as static HTML (uses no initial props)
2023-02-15T02:30:21.043081Z ▲
2023-02-15T02:30:21.043193Z ▲
2023-02-15T02:30:21.985327Z ▲ Collected static files (public/, static/, .next/static): 19.694ms
2023-02-15T02:30:21.985934Z ▲
2023-02-15T02:30:22.352255Z ▲ Using TypeScript 4.9.5 (local user-provided)
2023-02-15T02:30:22.352633Z ▲
2023-02-15T02:30:25.316304Z ▲ Build Completed in .vercel/output [31s]

@GregBrimble
Copy link
Member

This Worker startup time limit is unfortunately unrelated to this project, and is just a fundamental limit of the Workers platform: https://developers.cloudflare.com/workers/platform/limits/#worker-startup-time

If you can, try to move any work you do into request handlers rather than having it in global scope, as this moves the work from startup time to request time which may help here.

@GregBrimble GregBrimble closed this as not planned Won't fix, can't repro, duplicate, stale Mar 1, 2023
@Rigo-m
Copy link

Rigo-m commented Mar 24, 2023

Why isn't the CPU limit following the bundled/unbounded rules?
I.e.: I tried changing to unbounded mode (30s startup time limit vs 50ms CPU Time Limit), but I got the same error after 2 seconds.

@nitaking
Copy link

@GregBrimble

If you can, try to move any work you do into request handlers rather than having it in global scope, as this moves the work from startup time to request time which may help here.

Can you give us a specific example?

I understand why this is closed, but it has become an immediate problem faced by sites using cloudflare pages and Nextjs and is an issue that should be addressed quickly to resolve.

Cloudflare team should provide some kind of concrete solution.

@dario-piotrowicz
Copy link
Member

@nitaking Yeah this is a real issue and something that I believe very often developers can't do much about (especially if they include third party code which can do things at startup anyways).

We've actually already got a solution for this and we should release it soon, but before we can do that some changes need to be made in wrangler and I believe Greg is looking into that.

The solution will be next-on-pages splitting the code appropriately and lazy loading route code so that it is run only when needed resulting in a much lighter startup processing, so from a developer point of view you will hopefully only have to upgrade the next-on-pages package and things should just work 🙂👍

@dario-piotrowicz dario-piotrowicz self-assigned this Apr 13, 2023
@aufalmarom
Copy link

got the same issue please help us guys, i was deployed next js project at cloudflare pages
image

@ynishimura
Copy link

I am experiencing the same problem. Is there a workaround?

@Rigo-m
Copy link

Rigo-m commented Apr 17, 2023

We've actually already got a solution for this and we should release it soon, but before we can do that some changes need to be made in wrangler and I believe Greg is looking into that.

Since this problem is present in other metaframeworks as well (e.g.: nuxt3 with nitro), would you mind sharing your findings so that it's possible to pass on these improvements in these other metaframeworks as well?

@uglyrobot
Copy link

Blocked me from using Pages today as well. Off to Vercel...

@dario-piotrowicz
Copy link
Member

Since this problem is present in other metaframeworks as well (e.g.: nuxt3 with nitro), would you mind sharing your findings so that it's possible to pass on these improvements in these other metaframeworks as well?

@Rigo-m thanks a lot for the interest! 😃 and sorry for the late reply 😓 anyways I'll share the strategy in details when we add it to the project

We're also planning to contact and try to work with metaframework authors to help in this, although we've seen that many metaframeworks will need to change how they bundle the _worker before they can apply such type of strategy (it also depends on how the metaframework itself works and how it splits its code).

Anyways the strategy is simple, basically wrangler is introducing the ability to use dynamic imports, once we have those, instead of bundling everything together (which causes extra code to unnecessarily run) we add dynamic imports so that the code is evaluated and run only when actually used.

In next-on-pages basically the idea is to have a basic worker which simply acts at the next server/router (with just the basic logic, so it's going to be much faster), then when it needs to use a route, only at that point it dynamically imports that route's code.

Example

So for example let's say your app has routeA, routeB and apiRouteX and say routeA uses libA, routeB uses libB and apiRouteX uses libX all of which do some setup work

now we kind of take all of that js code and bundle it together, so all the setup work for libA, libB and libX is always run for every request

with dynamic imports, if you'll request routeB the worker won't load the libA and libX code at all, just the libB one with its setup work, so overall every request should be much faster (making it more difficult to hit the startup CPU time limit)

I hope the above helps, as I said I'll probably make this much more clear and provide a more detailed description of this when we actually add it to the project 🙂 (which should hopefully be pretty soon)

@Rigo-m
Copy link

Rigo-m commented Apr 19, 2023

This is extremely encouraging. And extremely is an undestatement.
We want to ditch netlify for cloudflare pages but the thing that at some point the app breaks for being too large has been a huge no-no for now, because it's too scary. Knowing that this issue is being tackled is a thing of pure joy. Paging @danielroe on this, hoping that Nitro will be ready for this change

Eagerly waiting to hear when this is finished, thanks a lot for your time!

@danielroe
Copy link

@Rigo-m Thanks for the ping. We are in contact now 😊

@lourou
Copy link

lourou commented Apr 24, 2023

I got the same error. I only have one basic hello world /api function in a nextjs@13 project, that then fails to build on Cloudflare pages:

▲  warn  - You are using `experimental.runtime` which was removed. Check https://nextjs.org/docs/api-routes/edge-api-routes on how to use edge runtime.
▲  info  - Compiled successfully
[...]
⚡️ Completed `npx vercel build`.
⚡️ Generated '.vercel/output/static/_worker.js'.
Finished
Found _worker.js in output directory. Uploading.
✨ Compiled Worker successfully
Found _routes.json in output directory. Uploading.
Validating asset output directory
Deploying your site to Cloudflare's global network...
Parsed 1 valid header rule.
Uploading... (59/59)
✨ Success! Uploaded 2 files (57 already uploaded) (0.98 sec)
✨ Upload complete!
Success: Assets published!
Error: Failed to publish your Function. Got error: Error: Script startup exceeded CPU time limit.

@olajiredominic
Copy link

Similar experience
10:58:34.092 | ⚡️ Completed npx vercel build. 10:58:37.268 | ⚡️ Generated '.vercel/output/static/_worker.js'. 10:58:37.345 | Finished 10:58:37.345 | Found _worker.js in output directory. Uploading. 10:58:38.453 | ✨ Compiled Worker successfully 10:58:38.530 | Found _routes.json in output directory. Uploading. 10:58:38.592 | Validating asset output directory 10:58:39.512 | Deploying your site to Cloudflare's global network... 10:58:42.159 | Parsed 1 valid header rule. 10:58:43.359 | Uploading... (84/86) 10:58:43.972 | Uploading... (85/86) 10:58:44.032 | Uploading... (86/86) 10:58:44.032 | ✨ Success! Uploaded 2 files (84 already uploaded) (1.20 sec) 10:58:44.032 |   10:58:44.314 | ✨ Upload complete! 10:58:46.532 | Success: Assets published! 10:58:48.503 | Error: Failed to publish your Function. Got error: Error: Script startup exceeded CPU time limit.

@bruce-shi
Copy link

#191
cloudflare/workers-sdk#2966

Since above two PR are still pending to merge, If you are in a hurry you can setup a GitHub action to manually deploy to CloudFlare pages.

This is an example of Github Workflow file.

on: [push]
jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      deployments: write
    name: Deploy to Cloudflare Pages
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 16
          cache: 'yarn'
          cache-dependency-path: yarn.lock
      # Run your project's build step
      - name: Build
        run: yarn install && npx https://prerelease-registry.devprod.cloudflare.dev/next-on-pages/runs/4786008794/npm-package-next-on-pages-191
      - name: Publish
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          PROJECT_NAME: ${{ secrets.PROJECT_NAME }}
        run: npx https://prerelease-registry.devprod.cloudflare.dev/workers-sdk/prs/2966/npm-package-wrangler-2966 pages publish .vercel/output/static --project-name=$PROJECT_NAME --branch=$GITHUB_REF_NAME

The trick here is to use the preview version of wrangler and next-on-pages from the following PR.
#191
cloudflare/workers-sdk#2966

Follow this guide to set up your account id and api token:
https://developers.cloudflare.com/pages/how-to/use-direct-upload-with-continuous-integration/

@dario-piotrowicz
Copy link
Member

Awesome, thanks for the temporary fix suggestion @bruce-shi 😄

(Anyways hopefully the two PRs will get merged soon 🤞)

@dario-piotrowicz dario-piotrowicz added blocked by external This can't be currently solved because of external factors (Vercel/Next, Pages, etc...) in progress This issue is currently being worked on and show be solved soon. labels May 5, 2023
@dario-piotrowicz
Copy link
Member

Just merged the PR 🙂

@shiyuhang0, @mihazs, @saaymeen, @aufalmarom, @ynishimura, @uglyrobot, @lourou and @olajiredominic (and whoever I might have missed 😅) If you want please try out your apps with the latest beta release: https://www.npmjs.com/package/@cloudflare/next-on-pages/v/0.0.0-b33639f and let me how it goes, hopefully you should not hit the startup time limit anymore 🙂

@zizifn
Copy link

zizifn commented May 9, 2023

Just merged the PR 🙂
@shiyuhang0, @mihazs, @saaymeen, @aufalmarom, @ynishimura, @uglyrobot, @lourou and @olajiredominic (and whoever I might have missed 😅) If you want please try out your apps with the latest beta release: https://www.npmjs.com/package/@cloudflare/next-on-pages/v/0.0.0-b33639f and let me how it goes, hopefully you should not hit the startup time limit anymore 🙂

after upgraded 0.0.0-b33639f with "wrangler": "^2.20.0", local wrangler pages dev .vercel/output/static has the below error. CF pages can deploy in prod but will have 404 for the index page.

[mf:err] Unhandled Promise Rejection: Error: Dynamic require of "node:buffer" is not supported
at __require (/tmp/tmp-6146-Jpj72xMGvB5Y/v286aujddf.js:6:9)

And wrangler pages deployment tail will have below error.

No deployment specified. Using latest deployment for production environment.

✘ [ERROR] A request to the Cloudflare API (/accounts/f7d1b2da33b7651c618148d0e05d024d/pages/projects/mytrash/deployments/d95b84d1-01d5-415f-8137-081f1dcd88c1/tails) failed.

  workers.api.error.script_not_found [code: 8000068]

  If you think this is a bug, please open an issue at:
  https://github.com/cloudflare/workers-sdk/issues/new/choose

BTW, version 0.10.1 working fine.

@zizifn
Copy link

zizifn commented May 9, 2023

Just merged the PR 🙂
@shiyuhang0, @mihazs, @saaymeen, @aufalmarom, @ynishimura, @uglyrobot, @lourou and @olajiredominic (and whoever I might have missed 😅) If you want please try out your apps with the latest beta release: https://www.npmjs.com/package/@cloudflare/next-on-pages/v/0.0.0-b33639f and let me how it goes, hopefully you should not hit the startup time limit anymore 🙂

after upgraded 0.0.0-b33639f with "wrangler": "^2.20.0", local wrangler pages dev .vercel/output/static has the below error. CF pages can deploy in prod but will have 404 for the index page.

[mf:err] Unhandled Promise Rejection: Error: Dynamic require of "node:buffer" is not supported at __require (/tmp/tmp-6146-Jpj72xMGvB5Y/v286aujddf.js:6:9)

And wrangler pages deployment tail will have below error.

No deployment specified. Using latest deployment for production environment.

✘ [ERROR] A request to the Cloudflare API (/accounts/f7d1b2da33b7651c618148d0e05d024d/pages/projects/mytrash/deployments/d95b84d1-01d5-415f-8137-081f1dcd88c1/tails) failed.

  workers.api.error.script_not_found [code: 8000068]

  If you think this is a bug, please open an issue at:
  https://github.com/cloudflare/workers-sdk/issues/new/choose

BTW, version 0.10.1 working fine.

same error with version 0.0.0-3e2dad8...

@dario-piotrowicz
Copy link
Member

@zizifn yeah sorry, that's totally my bad, my change kind of broke this code:

// Chunks can contain `require("node:buffer")`, this is not allowed and breaks at runtime
// the following fixes this by updating the require to a standard esm import from node:buffer
const nodeBufferPlugin: Plugin = {
name: 'node:buffer',
setup(build) {
build.onResolve({ filter: /^node:buffer$/ }, ({ kind, path }) => {
// this plugin converts `require("node:buffer")` calls, those are the only ones that
// need updating (esm imports to "node:buffer" are totally valid), so here we tag with the
// node-buffer namespace only imports that are require calls
return kind === 'require-call'
? {
path,
namespace: 'node-buffer',
}
: undefined;
});
// we convert the imports we tagged with the node-buffer namespace so that instead of `require("node:buffer")`
// they import from `export * from 'node:buffer;'`
build.onLoad({ filter: /.*/, namespace: 'node-buffer' }, () => ({
contents: `export * from 'node:buffer'`,
loader: 'js',
}));
},
};

(because now there is a bunch of code from Vercel that we don't process 😓)

so sorry for the inconvenience, I'm on it 🙇

@dario-piotrowicz
Copy link
Member

@zizifn should be all good now hopefully (sorry it took me a while I had to also deal with a runtime bug which I wasn't aware of 😓), please try again with the latest beta 🙂 🙏 (https://www.npmjs.com/package/@cloudflare/next-on-pages/v/0.0.0-4740c02)

@zizifn
Copy link

zizifn commented May 10, 2023

@zizifn should be all good now hopefully (sorry it took me a while I had to also deal with a runtime bug which I wasn't aware of 😓), please try again with the latest beta 🙂 🙏 (https://www.npmjs.com/package/@cloudflare/next-on-pages/v/0.0.0-4740c02)

Different error now, and I have --compatibility-flag=nodejs_compat when running..
image

@zizifn
Copy link

zizifn commented May 11, 2023

@zizifn should be all good now hopefully (sorry it took me a while I had to also deal with a runtime bug which I wasn't aware of 😓), please try again with the latest beta 🙂 🙏 (https://www.npmjs.com/package/@cloudflare/next-on-pages/v/0.0.0-4740c02)

Different error now, and I have --compatibility-flag=nodejs_compat when running.. image

@dario-piotrowicz is there something I'm doing wrong or you can reproduce this new error in your side?

@dario-piotrowicz
Copy link
Member

dario-piotrowicz commented May 11, 2023

@zizifn I'm so sorry I extensively looked into this and forgot to reply to you 😓

No, you're not doing things wrong, we've found out that there's actually currently a runtime bug which sort of causes the AsyncLocalStorage store not to be passed correctly 😓

A colleague of mine has implemented a fix for it: cloudflare/workerd#634 but I am not sure when that will be available in the runtime (maybe this or next week)

I kind of fixed this in my PR with a try-catch hack: https://github.com/cloudflare/next-on-pages/pull/232/files#r1190419297
which basically just prevents the app from breaking but if the ASL store is not present there isn't much more I can do about it 😓

It is not 100% not good, but as you can see from the apps I mentioned in the PR's description is sort of holding up decently (and anyways it'll be fixed as soon as the runtime's ready)


So you can use my pre-release to build and deploy your application and hopefully now it should work nicely

Unfortunately if you try to you won't be able to run the app locally because of a bug in wrangler pages dev we're also looking into it and will hopefully get fixed very soon (cloudflare/workers-sdk#3175) 😓


PS: I'm so sorry for the inconvenience, one thing after another kept popping up here 😓 (but after I extensively tested my PR's apps I am confident that it's all almost sorted out 🙇)
(we've also been talking about adding proper e2es to the project but haven't been able to for external reasons, I do really much hope we'll add some very soon so that moving forward things should never break this badly 😓)

@lsgrep
Copy link

lsgrep commented May 26, 2023

Hi, still having this issue. Is there any workaround for this?

@dario-piotrowicz
Copy link
Member

@lsgrep could you check if you are using the latest version of next-on-pages?

is it possible that your index page is doing some (costly?) setup work? could you reduce that?

in any case could you share your app so that we could have a look more in detail?

@Ehesp
Copy link

Ehesp commented May 26, 2023

Chiming in here - I'm using Remix rather than Next but have the same problems.

is it possible that your index page is doing some (costly?) setup work? could you reduce that?

This is no doubt the issue, but when applications grow complex it's incredibly hard to pinpoint where that costly setup is coming from. It's only reproducible when pushing to Cloudflare, so the iteration cycle is slow and there seems to be no way to profile the generated script :(

@lopugit
Copy link

lopugit commented Jun 8, 2023

Having the same issue with a Remix + Hydrogen app, bundle size is 2.5MB

@Ehesp
Copy link

Ehesp commented Jun 8, 2023

According to this blog post - the startup time is increasing to 400ms from 200ms:

In the age of AI, WASM, and powerful full-stack applications, we’ve noticed that developers are hitting our current resource limits with increased frequency. We want to be a place where these applications thrive and developers are empowered to build bigger and more sophisticated applications. Therefore, within the next week we’ll be increasing application size limits (JavaScript/WASM bundle size) to 10MB (after gzip) and startup latency limit (script compile time) is being increased from 200ms to 400ms.

Not sure if that's live or not now.

@BadMachine
Copy link

Having the same issue with a Remix + Hydrogen app, bundle size is 2.5MB

+1.

@justinhenricks
Copy link

Having the same issue with a Remix + Hydrogen app, bundle size is 2.5MB

me too - anyone know how to fix this?

@vladinator1000
Copy link

vladinator1000 commented May 21, 2024

My bundle is 550kb and it still fails. Checked with https://github.com/btd/rollup-plugin-visualizer

Error: Failed to publish your Function. Got error: Error: Script startup exceeded CPU time limit.

I'm using Remix to server-render my app. It would be really useful to have some more information / tooling to see why that happens. Also it would be nice if the error states the absolute CPU time limit.

@hawkcookie
Copy link

hawkcookie commented May 23, 2024

My bundle is 550kb and it still fails. Checked with https://github.com/btd/rollup-plugin-visualizer

Error: Failed to publish your Function. Got error: Error: Script startup exceeded CPU time limit.

I'm using Remix to server-render my app. It would be really useful to have some more information / tooling to see why that happens. Also it would be nice if the error states the absolute CPU time limit.

I have the same error. Does anyone have a solution?

@vladinator1000
Copy link

vladinator1000 commented May 25, 2024

@hawkcookie look at getLoadContext and entry.server.tsx, check what modules you are importing at the top and refactor potentially heavy imports to dynamic imports. Avoid running computations outside function calls.

let { someFunction } = await import('./someModule')

I'm using Remix, but if y'all are using another framework, the same principle could help you, just the entrypoints will be different.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked by external This can't be currently solved because of external factors (Vercel/Next, Pages, etc...) in progress This issue is currently being worked on and show be solved soon.
Projects
None yet
Development

Successfully merging a pull request may close this issue.