{
    "componentChunkName": "component---src-components-blog-post-jsx",
    "path": "/blog/how-to-check-bundled-netlify-function-size-locally/",
    "result": {"data":{"site":{"siteMetadata":{"author":"Monica Powell","siteUrl":"https://www.aboutmonica.com"}},"mdx":{"id":"86116a72-c67a-5654-9218-8f76e57c0da4","timeToRead":4,"body":"var _excluded = [\"components\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"How to Check Bundled Netlify Function Size Locally\",\n  \"date\": \"2022-01-02T19:05:25.851Z\",\n  \"template\": \"post\",\n  \"draft\": true,\n  \"slug\": \"how-to-check-bundled-netlify-function-size-locally\",\n  \"category\": [\"tutorial\"],\n  \"tags\": [\"netlify\"],\n  \"description\": \"Is everything working locally but you're having trouble deploying a Netlify function due to it being greater than 50 MB? This article walks through how to use the Netlify CLI to determine the size of the bundled Netlify function locally.\"\n};\n\nvar makeShortcode = function makeShortcode(name) {\n  return function MDXDefaultShortcode(props) {\n    console.warn(\"Component \" + name + \" was not imported, exported, or provided by MDXProvider as global scope\");\n    return mdx(\"div\", props);\n  };\n};\n\nvar Callout = makeShortcode(\"Callout\");\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, _excluded);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"Does your Netlify function appear to be working locally but you're having trouble successfully deploying the function due to it being greater than 50 MB? This article walks through how to use the Netlify CLI to determine the size of the bundled Netlify function locally in order to more quickly optimize the size.\"), mdx(\"h2\", {\n    \"id\": \"relationship-between-aws-lambda-50-mb-and-netlify-functions\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#relationship-between-aws-lambda-50-mb-and-netlify-functions\",\n    \"aria-label\": \"relationship between aws lambda 50 mb and netlify functions permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Relationship between AWS Lambda 50 MB and Netlify Functions\"), mdx(\"p\", null, \" Under the hood Netlify functions are an abstraction build on top of AWS Lambda functions. Therefore, Netlify functions are subject to the same limits as AWS Lambda functions and currently \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html\"\n  }, \"AWS restricts zipped Lambda files to 50 MB\"), \". During the build process Netlify bundles any Netlify functions, by default with the zip-it-and-ship it bundler and attempts to upload the zipped version. If a Netlify function is greater than 50 MB after the bundling process then during the build process when uploading the zipped function you will receive an error similar to the below: \"), mdx(Callout, {\n    variant: \"danger\",\n    mdxType: \"Callout\"\n  }, \"Request must be smaller than 69905067 bytes for the CreateFunction operation\"), mdx(\"h2\", {\n    \"id\": \"how-to-determine-size-of-zipped-netlify-function-locally\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#how-to-determine-size-of-zipped-netlify-function-locally\",\n    \"aria-label\": \"how to determine size of zipped netlify function locally permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"How to Determine Size of Zipped Netlify Function Locally\"), mdx(\"p\", null, \"You can often get feedback more quickly on the size of your Lambda functions by testing locally whether or not the zipped artifacts for your Netlify functions are less than 50MB without having to do a full remote build. \"), mdx(\"p\", null, \"I was recently working on a Netlify function to programmatically generate meta images and required the following dependencies dotenv, node-fetch, chrome-aws-lambda and puppeteer. It was working as expected locally and remotely but once I added an additional dependency of Cloudinary I began to encounter issues with the function size being too large and needed to experiment with potential optimizations like, will using puppeteer directly from chrome-aws-lambda meaningfully reduce the overall size of the function? Or, will switching the bundler reduce the size of the function below 50MB? The ability to test the impact of my changes of the overall bundle size locally without having to commit them and wait for remote CI/CD was helpful for reducing the amount of time it took to get feedback on my changes and allowed me to land on a working solution more quickly.\"), mdx(\"p\", null, \"1) In order to most effectively work with Netlify functions in a development environment you should use the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://docs.netlify.com/cli/get-started/\"\n  }, \"Netlify CLI\"), \" as it allows you to run a local development server and interact with Netlify in a similar context to your hosted build configuration. The Netlify CLI can be installed globally with:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"npm install -g netlify-cli\\n\")), mdx(\"p\", null, \"In order to interact with your hosted Netlify site you will need to authenticate by logging into Netlify and link the local project to a site hosted in your Netlify account:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"# Login to Netlify \\nnetlify login\\n\\n# Link current directory to a remote Netlify site\\nnetlify link\\n\")), mdx(\"p\", null, \"Once everything is configured for the Netlify CLI you should be able to run a build locally that mirrors what happens when Netlify generates a deploy preview remotely which is a similar context to where the error related to file function size occurs.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"netlify build --context deploy-preview \\n\")), mdx(\"p\", null, \"This will run a full build of your site and show in the logs each build step as it occurs and whether or not there are any errors. If everything succeeded then you should be able to view the functions generated by the build in a hidden \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".netlify\"), \" directory within your site which contains your functions folder and both the zipped and unzipped versions of the functions. Since we're concerned about the size of the generated zipped version of the function that is the file that we need to examine closer.\"), mdx(\"p\", null, \"We can quickly inspect the file path of the zipped function that was generated during the build with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"du\"), \" which is a unix command to get information on disk usage and use the -h flag to render the output in a \\\"human-readable\\\" format. Note since this format is human-readable it's an approximation of the actual number.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"# du -h .netlify/functions/getMetaImg.zip\\ndu -h path/to/your/generated/netlify/function.zip\\n                                   \\n\")), mdx(\"p\", null, \"For the above \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"du\"), \" command the example output for a 50MB file would be: \"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"# 50M   .netlify/functions/getMetaImg.zip\\n50m path/to/your/generated/netlify/function.zip\\n\")), mdx(\"p\", null, \"You can also navigate to the file via your computer's GUI file navigator such as MacOS's Finder or Windows' File Explorer and view more information for the file to view the file size. I found that looking at the file in the MacOS Finder and then right-clicking \\\"more info\\\" provided me with more significant digits for the same file than the number returned by \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"du\"), \". File Explorer can also be configured to display file sizes.\"), mdx(\"h2\", {\n    \"id\": \"reducing-size-of-netlify-functions\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#reducing-size-of-netlify-functions\",\n    \"aria-label\": \"reducing size of netlify functions permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Reducing Size of Netlify functions\"), mdx(\"p\", null, \" In order to be able to successfully upload and deploy your function you will need to figure out a way to reduce the size to be no greater than 50 MB by removing unused dependencies, swapping out\\ndependencies with lighter-weight alternatives or updating how your functions are being bundled for production. One of the fastest ways to reduce the overall size of Netlify functions is by using the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://esbuild.github.io/\"\n  }, \"esbuild\"), \" bundler instead of the currently default for Netlify functions \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/netlify/zip-it-and-ship-it\"\n  }, \"zip it and ship it (a.k.a zisi)\"), \". In April 2021, \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://www.netlify.com/blog/2021/04/02/modern-faster-netlify-functions/\"\n  }, \"Netlify announced beta support for esbuild\"), \" as a more modern and faster, alternative to zisi.\\nYou can enable esbuild for your Netlify functions by updating the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"netlify.toml\"), \" in the root of your project to include the following:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"[functions]\\n  node_bundler = \\\"esbuild\\\"\\n\")), mdx(\"p\", null, \"I updated my \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"netlify.toml\"), \" and then was able to determine that the same function bundled with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"esbuild\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"zisi\"), \" was ~2MB smaller in the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"esbuild\"), \" version by doing a local deploy-preview build of my site with the Netlify CLI and then running \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"du\"), \" to view the file size. However, if the file is still too large you will need to do a closer evaluation of the dependencies your function relies onto function to determine if there are opportunities to reduce or replace larger dependencies.\"), mdx(\"p\", null, \"Initially, I encountered  some issues using esbuild out of the box which caused a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Error: spawn ETXTBSY\"), \" error when running the deployed function as the zipped version excluded one  of my dependencies \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"chrome-aws-lambda\"), \". I was able to determine this by checking the Netlify logs which output the following tip during the Functions bundling step:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\n  4. Functions bundling                                         \\n \\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\n \\u200B\\n Packaging Functions from netlify/functions directory:\\n  - getMetaImg.js\\n - gatsby/gatsby.js\\n \\u200B\\n\\u276F The following Node.js modules use dynamic expressions to include files:\\n   - chrome-aws-lambda\\n\\n  Because files included with dynamic expressions aren't bundled with your serverless functions by default,\\n  this may result in an error when invoking a function. To resolve this error, you can mark these Node.js modules as external in the [functions] section of your `netlify.toml` configuration file:\\n\\u200B\\n   [functions]\\n      external_node_modules = [\\\"chrome-aws-lambda\\\"]\\n  \\n    Visit https://ntl.fyi/dynamic-imports for more information.\\n\")), mdx(\"p\", null, \"My issues with the deployed function were resolved after I updated my esbuild configuration to include that dynamic dependency of \\\"chrome-aws-lambda\\\" by adding the following to the netlify.toml\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"#replace functionName with the name of your function or use [functions] to apply to all of the Netlify # functions configured by that netlify.toml\\n[functions.functionName]\\n  external_node_modules = [\\\"chrome-aws-lambda\\\"]\\n\")), mdx(\"p\", null, \"If you are noticing differences in behavior between the esbuild and zisi version of your function you should double-check the logs to help determine if dynamic imports that you need were not removed during the esbuild process and if so, update the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://docs.netlify.com/configure-builds/file-based-configuration/#functions\"\n  }, \"functions configuration\"), \" as needed.\"), mdx(\"h2\", {\n    \"id\": \"conclusion\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#conclusion\",\n    \"aria-label\": \"conclusion permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Conclusion\"), mdx(\"p\", null, \"Using the Netlify CLI can be a helpful resource for developing and testing Netlify functions locally. By creating a local deploy-preview build of your site with the Netlify CLI you can gain meaningful insight into issues that arise during remote deployments and shorten the feedback loop to debug issues that do not appear during normal local development. If you're using the default, zisi, bundler for Netlify functions you may want to consider switching over to esbuild.\"));\n}\n;\nMDXContent.isMDXComponent = true;","tableOfContents":{"items":[{"url":"#relationship-between-aws-lambda-50-mb-and-netlify-functions","title":"Relationship between AWS Lambda 50 MB and Netlify Functions"},{"url":"#how-to-determine-size-of-zipped-netlify-function-locally","title":"How to Determine Size of Zipped Netlify Function Locally"},{"url":"#reducing-size-of-netlify-functions","title":"Reducing Size of Netlify functions"},{"url":"#conclusion","title":"Conclusion"}]},"frontmatter":{"title":"How to Check Bundled Netlify Function Size Locally","date":"January 02, 2022","description":"Is everything working locally but you're having trouble deploying a Netlify function due to it being greater than 50 MB? This article walks through how to use the Netlify CLI to determine the size of the bundled Netlify function locally.","tags":["netlify"]}},"allWebMentionEntry":{"edges":[]}},"pageContext":{"permalink":"https://www.aboutmonica.com/blog/how-to-check-bundled-netlify-function-size-locally/","slug":"/blog/how-to-check-bundled-netlify-function-size-locally/","prev":{"id":"ccb8bd43-0980-5093-9486-bbf760ba5ac1","frontmatter":{"title":"Your future self will thank you: Building your personal documentation","category":null,"date":"2022-01-12T13:19:10.285Z","slug":null,"tags":["ExternalLink"],"redirects":null},"fields":{"slug":"/blog/undefined/"}},"next":{"id":"1419354c-d573-5ecc-9e46-e01e550f2525","frontmatter":{"title":"How to hone your new superpower: teaching","category":null,"date":"2021-12-14T13:19:10.285Z","slug":null,"tags":["ExternalLink"],"redirects":null},"fields":{"slug":"/blog/undefined/"}}}},
    "staticQueryHashes": ["1977783444","764694655"]}