Skip to main content
fal captures your app’s stdout and stderr, including print() statements, Python logging output, and error tracebacks. Runner logs cover a runner’s lifetime. Request logs cover a single request. For deployed apps, both are restricted to the app owner. Non-owner callers do not receive them. The app owner is the personal or team account that owns the deployment.

Runner Logs

Runner logs capture the full output of a runner process from the moment it starts until it shuts down. This includes output from setup() (model loading, initialization), every request the runner handles, and any background output between requests. Runner logs are visible only to the app owner through the dashboard and CLI. Use runner logs for internal diagnostics: model loading times, memory usage, cache behavior, and anything that spans the runner’s lifetime rather than a single request.
You can view runner logs in the CLI with fal runners logs <runner-id>, or in the dashboard filtered by runner ID.

Request Logs

Request logs contain runner output emitted while a request is processing. Only the authenticated app owner can retrieve them through queue status or the Playground. Use with_logs=True in Python or logs: true in JavaScript to request them. Non-owner callers receive empty log arrays. Sharing a request link does not grant log access. Apps with max_multiplexing > 1 return no request logs, even to the owner. Concurrent requests share a runner’s output. Use runner logs to debug these apps.
Owner-only access does not prevent log storage. Do not log secrets or customer data that must not be retained.

Log Privacy Settings

Request logs are owner-only regardless of the Log Privacy setting. Setting private_logs=True excludes app output from request-log responses, even for the owner. Logs are still captured. The owner can read them through the dashboard’s runner logs and fal runners logs. The Log Privacy setting supplies the default for apps deployed without an explicit private_logs value. An explicit True or False overrides that default. Changing the account default does not change existing deployments. Redeploy an app to pick up the new default.

Playground Logs

The Playground follows the same request-log rules as the queue API. Non-owner callers receive no request logs. As the app owner, use runner logs if request logs are unavailable. During development with fal run, logs also stream directly to your terminal, giving you immediate feedback without needing the dashboard.

Writing Logs

For quick debugging, print() is the simplest approach. Both stdout and stderr are captured.
For production apps, use Python’s standard logging module to control log levels and message format. A good pattern is to route INFO and WARNING to stdout and ERROR and above to stderr, so you can filter by severity when reviewing logs.
Include the request ID in your log output for easier debugging. You can access it via self.current_request.request_id in your endpoint handler. See Request Headers for all available per-request context including caller identity and custom headers.
Avoid logging secrets, API keys, or large raw payloads. Log IDs, sizes, and high-level status instead.

Log Sources

When filtering logs in the dashboard or CLI, the source field tells you where the logs came from:
  • run - logs from runners created by fal run during development
  • gateway - logs from runners serving deployed apps in production
  • deploy - logs emitted by the deployment process itself when using fal deploy

Where to View Logs