Skip to content

300 Minutes a Month: Cutting My Eleventy Netlify Build Time in Half

A sequel to my Eleventy build post: this time the bottleneck wasn't the build tool, it was the hosting bill. Notes on caching webmentions and guestbook fetches, killing a dead Discord webhook, nearly breaking my JSON feed, and a git error I still don't have an answer for.

B♾️

couple of months ago I wrote about [making my Eleventy build five times faster](https://brennan.day/i-made-my-eleventy-build-5-faster-with-five-changes/) by fixing a handful of embarrassing filters. I wrote about developer experience and the feedback loop of "I write a line" and "I see the result."

Why am I writing a sequel already? Well, the answer is money. Or more accurately, keeping things free.

I'm on [Netlify's legacy free plan](https://www.netlify.com/pricing/faq/), which gives me 300 build minutes a month. Right now, despite my previous optimizations, the build time averages around **2 minutes, 45 seconds**. If I'm committing and building the site once a day (and I usually am more often than that), then I'm getting too close to that free limit.

What can I optimize? The answers are far more Netlify-centric this time around, rather than just about 11ty.

## An Unused Webhook

Before optimizing, I looked for what I could delete outright. The fastest build minute is the one you never spend.

I had a Discord webhook integration, a shell script and a Netlify Function, that pinged a Discord channel whenever I published. Since I'm deleting my Discord and [a bunch of other social media](https://brennan.day/a-full-guide-to-properly-delete-corporate-social-media-accounts/), I no longer need the webhook. The way I wrote the script meant that at each build, it was fetching my RSS feed, sleeping 30 seconds to "allow for deployment," parsing the latest post, and POSTing to the webhook.

```bash # scripts/discord-webhook-ping.sh (deleted) sleep 30 LATEST_POST=$(curl -s "$RSS_URL" | ...) curl -X POST "$DISCORD_WEBHOOK_URL" -d "{ \"embeds\": [...] }" ```

Thirty seconds of `sleep`, plus a network round-trip, on every deploy, for a feature I'd abandoned. I deleted the script, the Netlify Function, and the `DISCORD_WEBHOOK_URL` reference from `.env.example`.

Dead code should die properly. If I ever want notifications pinging elsewhere, it's a small script to rewrite.

## Uncached Data Fetches

My `src/_data/` directory has a few files that hit external APIs on every single build:

- `statuslog.js`: pulls my [status.lol](https://brennan.omg.lol) updates - `webmentions.js`: pulls webmentions from [webmention.io](https://webmention.io) - `guestbook.js`: pulls form submissions from the Netlify API

All three use [`@11ty/eleventy-fetch`](https://www.11ty.dev/docs/plugins/fetch/) for disk caching, but the cache `duration` values were too conservative: 1 hour for statuslog and 6 hours for webmentions and guestbook. My status log updates once a day at most, and guestbook entries trickle in over weeks.

```javascript // Before: re-fetches every 6 hours, most of which are wasted const response = await EleventyFetch(url, { duration: "6h", type: "json" }); ```

Did you enjoy this article?

Recommend it — Standard Reader surfaces well-loved writing to more readers across the network.

Across the AtmosphereDiscussions