Edge Functions

Troubleshooting Common Issues

How to solve common problems and issues related to Edge Functions.


When developing Edge Functions, you can run into various issues during development, deployment, and at runtime. Most problems fall under these categories:

This guide will cover most of the common issues.


Deployment issues

Unable to deploy Edge Function

  1. Check function syntax: Run deno check on your function files locally
  2. Review dependencies: Verify all imports are accessible and compatible with Deno
  3. Examine bundle size: Large functions may fail to deploy
1
2
3
4
5
# Check for syntax errorsdeno check ./supabase/functions/your-function/index.ts# Deploy with verbose outputsupabase functions deploy your-function --debug

Bundle size issues

Functions have a 10MB source code limit. Check your bundle size:

1
deno info /path/to/function/index.ts

Look for the "size" field in the output. If your bundle is too large:

  • Remove unused dependencies
  • Use selective imports: import { specific } from 'npm:package/specific'
  • Consider splitting large functions into smaller ones

Runtime issues

Edge Function takes too long to respond

Functions have a 60-second execution limit.

  1. Check function logs: Navigate to Functions > [Your Function] > Logs in the dashboard
  2. Examine boot times: Look for booted events and check for consistent boot times
  3. Identify bottlenecks: Review your code for slow operations
    • If the boot times are similar, it’s likely an issue with your function’s code, such as a large dependency, a slow API call, or a complex computation. You can try to optimize your code, reduce the size of your dependencies, or use caching techniques to improve the performance of your function.
    • If only some of the booted events are slow, find the affected region in the metadata and submit a support request via the "Help" button at the top.
1
2
3
4
5
6
7
8
// ✅ Optimize database queriesconst { data } = await supabase .from('users') .select('id, name') // Only select needed columns .limit(10)// ❌ Avoid fetching large datasetsconst { data } = await supabase.from('users').select('*') // Fetches all columns

546 Error Response

The 546 error typically indicates resource exhaustion or code issues:

  • Memory or CPU Limits: Your function may have exceeded available resources. Check the resource usage metrics in your dashboard.

  • Event Loop Completion: If logs show "Event loop completed," your function has implementation issues. You should check your function code for any syntax errors, infinite loops, or unresolved promises that might cause this error.

    You can also try running the function locally (using Supabase CLI functions serve) to see if you can debug the error. The local console should give a full stack trace on the error with line numbers of the source code. You can also refer to Edge Functions examples for guidance.

Run the function locally with supabase functions serve to get detailed stack traces.

Unable to call Edge Function

For invocation or CORS issues:

  1. Review CORS configuration: Check out the CORS guide, and ensure you've properly configured CORS headers
  2. Check function logs: Look for errors in the Functions > Logs section
  3. Verify authentication: Confirm JWT tokens and permissions are correct
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// ✅ Proper CORS handlingDeno.serve(async (req) => { if (req.method === 'OPTIONS') { return new Response(null, { status: 200, headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', }, }) } // Your function logic here return new Response('Success', { headers: { 'Access-Control-Allow-Origin': '*' }, })})

There are two debugging tools available: Invocations and Logs. Invocations shows the Request and Response for each execution, while Logs shows any platform events, including deployments and errors.


Local development issues

Issues serving functions locally

When supabase functions serve fails:

  1. Use debug mode: Run with the --debug flag for detailed output
  2. Check port availability: Ensure ports 54321 and 8081 are available
1
2
3
4
5
# Serve with debug outputsupabase functions serve your-function --debug# Check specific port usagelsof -i :54321

If the problem persists, search the Edge Runtime and CLI repositories for similar error messages.

Performance optimization

Monitoring resource usage

Track your function's performance through the dashboard:

  1. Navigate to Edge Functions > [Your Function] > Metrics
  2. Review CPU, memory, and execution time charts
  3. Identify potential problems in resource consumption

Understanding CPU limits

An isolate is like a worker that can handle multiple requests for a function. It works until a time limit of 400 seconds is reached. Edge Functions use isolates with soft and hard CPU limits:

  1. Soft Limit: When the isolate hits the soft limit, it retires. This means it won't take on any new requests, but it will finish processing the ones it's already working on. It keeps going until it either hits the hard limit for CPU time or reaches the 400-second time limit, whichever comes first.
  2. Hard Limit: If there are new requests after the soft limit is reached, a new isolate is created to handle them. The original isolate continues until it hits the hard limit or the time limit. This ensures that existing requests are completed, and new ones will be managed by a newly created isolate.

Dependency Analysis

It’s important to optimize your dependencies for better performance. Large or unnecessary dependencies can significantly impact bundle size, boot time, and memory usage.

Deno Dependencies

Start by analyzing your dependency tree to understand what's being imported:

1
2
3
4
5
# Basic dependency analysisdeno info /path/to/function/index.ts# With import map (if using one)deno info --import-map=/path/to/import_map.json /path/to/function/index.ts

Review the output for:

  • Large dependencies: Look for packages that contribute significantly to bundle size
  • Redundant imports: Multiple packages providing similar functionality
  • Outdated versions: Dependencies that can be updated to more efficient versions
  • Unused imports: Dependencies imported but not actually used in your code

NPM Dependencies

When using NPM modules, keep their impact on bundle size in mind. Many NPM packages are designed for Node.js and may include unnecessary polyfills or large dependency trees.

Use selective imports to minimize overhead:

1
2
3
4
5
6
7
// ✅ Import specific submodulesimport { Sheets } from 'npm:@googleapis/sheets'import { JWT } from 'npm:google-auth-library/build/src/auth/jwtclient'// ❌ Import entire packageimport * as googleapis from 'npm:googleapis'import * as googleAuth from 'npm:google-auth-library'
  • Tree-shake aggressively: Only import what you actually use
  • Choose lightweight alternatives: Research smaller packages that provide the same functionality
  • Bundle analysis: Use deno info before and after changes to measure impact
  • Version pinning: Lock dependency versions to avoid unexpected size increases