Why Expose Crashes on Large Files (and How to Fix It)

If you're using Expose to share your local site and suddenly hit this cryptic error, you're not alone:

PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 35684384 bytes)

The tunnel crashes, your demo fails, and you're left wondering what just happened.

TL;DR: Open ~/.expose/config.php and increase 'memory_limit' from '128M' to '512M' (or higher), then restart your tunnel.

When Does This Error Happen?

This error typically occurs when someone (or something) requests a large file through your Expose tunnel. Common culprits:

  • Video files (.mp4, .webm)
  • Large PDFs or downloads
  • High-resolution images
  • Any response larger than ~50-70MB

In my case, it was a 69MB background video on the homepage. The moment a browser tried to load it through the tunnel — boom, crash. This hit me right in the middle of prepping a client demo, so here's the fix I wish I'd known 20 minutes earlier.

Why Expose Runs Out of Memory

Here's what's happening under the hood:

  1. Expose proxies HTTP responses between your local server and the tunnel
  2. It effectively loads large responses into memory before forwarding them
  3. Expose ships with a default 128MB memory limit
  4. When the response size plus Expose's baseline memory usage crosses 128MB, PHP bails out with Allowed memory size exhausted

The 128MB limit isn't from your system's PHP configuration — it's set inside Expose itself via ini_set(), which overrides any CLI flags you might try.

The Fix: Increase memory_limit in config.php

Open your Expose config file:

# macOS / Linux
~/.expose/config.php

# Windows
C:\Users\<your-username>\.expose\config.php

# Or a project-specific config (overrides the global file)
.expose.php

Find the memory_limit setting and bump it up:

<?php

// ~/.expose/config.php

return [
    // Other Expose settings...

    'memory_limit' => '512M', // Increase from 128M to 512M or higher
];

If you already have a config file, just update the existing 'memory_limit' entry instead of replacing the whole file. If you don't have one yet, you can generate it by running:

expose publish

Save the file, restart your tunnel, and reload the page that previously crashed to confirm the fix.

Note: If you're using Laravel Herd, Expose is bundled in, but it still reads your ~/.expose/config.php. Project-specific .expose.php files will override the global config.

Example: Sharing a Site

# If using Laravel Herd
herd share

# Or using expose directly
expose share https://my-app.test --subdomain=demo-client

Both respect your ~/.expose/config.php settings.

How Much memory_limit Do You Need?

A rough guideline:

Largest file you're servingRecommended limit
Under 50MB128M (default)
50-100MB256M
100-200MB512M
200MB+1G or 2G

Is It Safe to Use a Very High memory_limit?

Setting memory_limit to 1G or 2G is fine on a typical dev machine with enough RAM. PHP won't pre-allocate that memory — it just caps how high it's allowed to go.

The main risk is if your machine is already low on RAM: serving multiple huge files at once could cause swapping or slowdowns. If in doubt, start with 512M or 1G and watch your memory usage the first time you test.

Why php -d memory_limit Doesn't Work

If you tried running Expose with a custom memory limit like this:

php -d memory_limit=512M ~/.expose/expose share ...

You probably noticed it still crashes at 128MB. That's one of those classic "of course there's a hidden ini_set()" moments.

Expose's AppServiceProvider does this on boot:

ini_set('memory_limit', config()->get('expose.memory_limit', '128M'));

The config file value always wins. So editing ~/.expose/config.php is the only way.

Alternative Solutions

If you routinely serve files larger than a few hundred MB through Expose, consider whether that's the right approach:

  • Host large assets on a CDN — keep only the app behind Expose
  • Compress or resize background videos — get them under 50-100MB
  • Use direct file links — share a Dropbox/S3 link instead of tunneling the file

Increasing memory_limit is the quick fix, but trimming asset size often makes everything snappier anyway.

Resources


Hope this saves someone the 20 minutes of debugging I spent on this. Happy tunneling!