Reference

Production rollout

Production capture works, but it's the riskiest mode: real users, real data, real devices. Go through this list before the first store build that records.

  1. Use the right project

    The API URL and ingest key are compiled into every build. Use your production project's ingest key in store builds (ask your BugCapsule team for a separate project if QA and production should stay apart). Never put the bcs_ secret key in an app.

  2. Test the kill switch before you need it

    bugcapsule capture --on       # kill switch ON = capture disabled
    bugcapsule capture            # show config
    bugcapsule capture --off      # resume

    BugCapsule refuses uploads at once. Devices see it at their next settings refresh: after the refresh interval (default 5 min), when the app returns to the foreground, or before an upload with a stale config. They stop recording, drop the buffer, delete queued and saved captures, and keep the switch across launches even offline. An upload already on the wire finishes. Re-enabling applies from the next launch.

  3. Understand capture settings

    Fetched after startup, refreshed every few minutes and on resume, and cached per API URL and ingest key (a staging project's settings never apply to production). With no cached settings, debug/QA builds record and production builds sample at the app's cap, but nothing is uploaded until the settings are fetched. Cached settings older than 7 days also stop uploads.

  4. Set sampling

    A production session records with probability min(productionSampleRate, project sample rate), decided at launch. The app's cap (default 0.1) is the ceiling; the project setting can only lower it. Lowering mid-session keeps a recording session with probability new/old. Start low: bugcapsule capture --sample-rate 0.01.

  5. Review redaction on real flows

    Run a real login and payment flow in a QA build, then read the capsule end to end (bugcapsule inspect <id> --json). Add redactKeys, redactPatterns, hooks, exclude rules and sanitizeLocation. See Privacy & redaction.

  6. Decide on bodies

    Turn off captureNetworkBodies (locally or remotely) for anything you can't send. Capsules become partial. Capture never buffers whole bodies: a bounded prefix (256 KiB, binary 64 KiB) while the app gets the stream unchanged.

  7. Check storage allowlists

    Especially Flutter's BugCapsuleSharedPreferences(), which captures every key unless you pass allowPrefixes.

  8. Know the device footprint

    At most 20 saved captures and an outbox of 10 capsules / 10 MiB / 7 days, oldest evicted first; failed uploads back off from 30 s to 1 h. Disk-full and corrupt files drop the capsule, never the app.

  9. Rely on isolation, but verify it

    If storage, an integration or anything in setup fails, the app starts without capture; SDK errors never reach the app's handlers. Test with a read-only or full disk on a QA device.

  10. Measure performance

    Cold start, frame times and memory on a low-end Android device, with and without the SDK. On Flutter, pointer and HTTP capture and redaction run on the UI isolate; encoding runs in a background isolate. The Flutter repo's docs/release-and-device-test-plan.md has the overhead budget.

  11. Confirm release builds can't replay

    Flutter release ignores replay requests; Android needs the androidTest runner and a debuggable build; iOS needs DEBUG; web needs allowReplay: true, which must be false in production builds.

  12. Plan key rotation

    Rotation revokes the old key immediately with no overlap. A rotated ingest key stops every shipped build from uploading until a build with the new key ships. Rotate the secret key freely; rotate the ingest key only when you must.

  13. Agree on data handling

    Retention, share-link policy and how deletion requests are handled. Read what's collected and where it goes with whoever owns privacy in your company, and contact your BugCapsule team for anything that needs changing.

Platform-specific notes

PlatformWatch out for
FlutterOverlay hidden in production by default (showOverlay). BLoC state data in events is off in production unless recordStateData: true.
AndroidEmpty consumer R8 rules and an untested minified build: verify a minified QA build first. Declare INTERNET. No cleartext outside local hosts.
iOSDeclare required-reason APIs (UserDefaults, file timestamps, system uptime) in your privacy manifest. Uploads happen only in the foreground.
WebSet mode explicitly; get your production origin allowed by your BugCapsule team; a rejected ingest key deletes the local queue.